Merge remote-tracking branch 'refs/remotes/Kwoth/master'
This commit is contained in:
commit
0d224ec047
7
.gitignore
vendored
7
.gitignore
vendored
@ -10,7 +10,6 @@
|
|||||||
obj/
|
obj/
|
||||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
*.userprefs
|
*.userprefs
|
||||||
**/Bin/Debug/**
|
|
||||||
**/Bin/Release/
|
**/Bin/Release/
|
||||||
**/Bin/PRIVATE/
|
**/Bin/PRIVATE/
|
||||||
!**/Bin/Debug/opus.dll
|
!**/Bin/Debug/opus.dll
|
||||||
@ -19,9 +18,11 @@ obj/
|
|||||||
!**/Bin/Debug/Nito.AsyncEx.dll
|
!**/Bin/Debug/Nito.AsyncEx.dll
|
||||||
!**/Bin/Debug/WebSocket4Net.dll
|
!**/Bin/Debug/WebSocket4Net.dll
|
||||||
!**/Bin/Debug/sqlite3.dll
|
!**/Bin/Debug/sqlite3.dll
|
||||||
!**/Bin/Debug/data/*
|
|
||||||
!**/Bin/Debug/data/
|
|
||||||
!**/Bin/Debug/credentials_example.json
|
!**/Bin/Debug/credentials_example.json
|
||||||
|
NadekoBot/bin/debug/*.*
|
||||||
|
NadekoBot/bin/debug/data/permissions
|
||||||
|
NadekoBot/bin/debug/data/incidents
|
||||||
|
!NadekoBot/bin/Debug/data/currency_images/*
|
||||||
Tests/bin
|
Tests/bin
|
||||||
|
|
||||||
# NuGet Packages
|
# NuGet Packages
|
||||||
|
8
NadekoBot/Classes/BombermanGame.cs
Normal file
8
NadekoBot/Classes/BombermanGame.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace NadekoBot.Classes
|
||||||
|
{
|
||||||
|
class BombermanGame
|
||||||
|
{
|
||||||
|
public ulong ChannelId { get; internal set; }
|
||||||
|
public bool Ended { get; internal set; }
|
||||||
|
}
|
||||||
|
}
|
@ -1,19 +1,23 @@
|
|||||||
using System.Collections.Generic;
|
using NadekoBot.Classes._DataModels;
|
||||||
using System.Linq;
|
|
||||||
using SQLite;
|
using SQLite;
|
||||||
using NadekoBot.Classes._DataModels;
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
namespace NadekoBot.Classes {
|
namespace NadekoBot.Classes
|
||||||
internal class DbHandler {
|
{
|
||||||
|
internal class DbHandler
|
||||||
|
{
|
||||||
public static DbHandler Instance { get; } = new DbHandler();
|
public static DbHandler Instance { get; } = new DbHandler();
|
||||||
|
|
||||||
private string FilePath { get; } = "data/nadekobot.sqlite";
|
private string FilePath { get; } = "data/nadekobot.sqlite";
|
||||||
|
|
||||||
static DbHandler() { }
|
static DbHandler() { }
|
||||||
public DbHandler() {
|
public DbHandler()
|
||||||
using (var conn = new SQLiteConnection(FilePath)) {
|
{
|
||||||
|
using (var conn = new SQLiteConnection(FilePath))
|
||||||
|
{
|
||||||
conn.CreateTable<Stats>();
|
conn.CreateTable<Stats>();
|
||||||
conn.CreateTable<Command>();
|
conn.CreateTable<Command>();
|
||||||
conn.CreateTable<Announcement>();
|
conn.CreateTable<Announcement>();
|
||||||
@ -23,44 +27,83 @@ namespace NadekoBot.Classes {
|
|||||||
conn.CreateTable<CurrencyTransaction>();
|
conn.CreateTable<CurrencyTransaction>();
|
||||||
conn.CreateTable<Donator>();
|
conn.CreateTable<Donator>();
|
||||||
conn.CreateTable<PokeMoves>();
|
conn.CreateTable<PokeMoves>();
|
||||||
conn.CreateTable<userPokeTypes>();
|
conn.CreateTable<UserPokeTypes>();
|
||||||
conn.CreateTable<UserQuote>();
|
conn.CreateTable<UserQuote>();
|
||||||
|
conn.CreateTable<Reminder>();
|
||||||
conn.Execute(Queries.TransactionTriggerQuery);
|
conn.Execute(Queries.TransactionTriggerQuery);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void InsertData<T>(T o) where T : IDataModel {
|
internal T FindOne<T>(Expression<Func<T, bool>> p) where T : IDataModel, new()
|
||||||
using (var conn = new SQLiteConnection(FilePath)) {
|
{
|
||||||
|
using (var conn = new SQLiteConnection(FilePath))
|
||||||
|
{
|
||||||
|
return conn.Table<T>().Where(p).FirstOrDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void DeleteAll<T>() where T : IDataModel
|
||||||
|
{
|
||||||
|
using (var conn = new SQLiteConnection(FilePath))
|
||||||
|
{
|
||||||
|
conn.DeleteAll<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void DeleteWhere<T>(Expression<Func<T, bool>> p) where T : IDataModel, new()
|
||||||
|
{
|
||||||
|
using (var conn = new SQLiteConnection(FilePath))
|
||||||
|
{
|
||||||
|
var id = conn.Table<T>().Where(p).FirstOrDefault()?.Id;
|
||||||
|
if (id.HasValue)
|
||||||
|
conn.Delete<T>(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void InsertData<T>(T o) where T : IDataModel
|
||||||
|
{
|
||||||
|
using (var conn = new SQLiteConnection(FilePath))
|
||||||
|
{
|
||||||
conn.Insert(o, typeof(T));
|
conn.Insert(o, typeof(T));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void InsertMany<T>(T objects) where T : IEnumerable<IDataModel> {
|
internal void InsertMany<T>(T objects) where T : IEnumerable<IDataModel>
|
||||||
using (var conn = new SQLiteConnection(FilePath)) {
|
{
|
||||||
|
using (var conn = new SQLiteConnection(FilePath))
|
||||||
|
{
|
||||||
conn.InsertAll(objects);
|
conn.InsertAll(objects);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void UpdateData<T>(T o) where T : IDataModel {
|
internal void UpdateData<T>(T o) where T : IDataModel
|
||||||
using (var conn = new SQLiteConnection(FilePath)) {
|
{
|
||||||
|
using (var conn = new SQLiteConnection(FilePath))
|
||||||
|
{
|
||||||
conn.Update(o, typeof(T));
|
conn.Update(o, typeof(T));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal HashSet<T> GetAllRows<T>() where T : IDataModel, new() {
|
internal HashSet<T> GetAllRows<T>() where T : IDataModel, new()
|
||||||
using (var conn = new SQLiteConnection(FilePath)) {
|
{
|
||||||
|
using (var conn = new SQLiteConnection(FilePath))
|
||||||
|
{
|
||||||
return new HashSet<T>(conn.Table<T>());
|
return new HashSet<T>(conn.Table<T>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal CurrencyState GetStateByUserId(long id) {
|
internal CurrencyState GetStateByUserId(long id)
|
||||||
using (var conn = new SQLiteConnection(FilePath)) {
|
{
|
||||||
|
using (var conn = new SQLiteConnection(FilePath))
|
||||||
|
{
|
||||||
return conn.Table<CurrencyState>().Where(x => x.UserId == id).FirstOrDefault();
|
return conn.Table<CurrencyState>().Where(x => x.UserId == id).FirstOrDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal T Delete<T>(int id) where T : IDataModel, new() {
|
internal T Delete<T>(int id) where T : IDataModel, new()
|
||||||
using (var conn = new SQLiteConnection(FilePath)) {
|
{
|
||||||
|
using (var conn = new SQLiteConnection(FilePath))
|
||||||
|
{
|
||||||
var found = conn.Find<T>(id);
|
var found = conn.Find<T>(id);
|
||||||
if (found != null)
|
if (found != null)
|
||||||
conn.Delete<T>(found.Id);
|
conn.Delete<T>(found.Id);
|
||||||
@ -71,8 +114,10 @@ namespace NadekoBot.Classes {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates an existing object or creates a new one
|
/// Updates an existing object or creates a new one
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal void Save<T>(T o) where T : IDataModel, new() {
|
internal void Save<T>(T o) where T : IDataModel, new()
|
||||||
using (var conn = new SQLiteConnection(FilePath)) {
|
{
|
||||||
|
using (var conn = new SQLiteConnection(FilePath))
|
||||||
|
{
|
||||||
var found = conn.Find<T>(o.Id);
|
var found = conn.Find<T>(o.Id);
|
||||||
if (found == null)
|
if (found == null)
|
||||||
conn.Insert(o, typeof(T));
|
conn.Insert(o, typeof(T));
|
||||||
@ -81,8 +126,10 @@ namespace NadekoBot.Classes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal T GetRandom<T>(Expression<Func<T, bool>> p) where T : IDataModel, new() {
|
internal T GetRandom<T>(Expression<Func<T, bool>> p) where T : IDataModel, new()
|
||||||
using (var conn = new SQLiteConnection(FilePath)) {
|
{
|
||||||
|
using (var conn = new SQLiteConnection(FilePath))
|
||||||
|
{
|
||||||
var r = new Random();
|
var r = new Random();
|
||||||
return conn.Table<T>().Where(p).ToList().OrderBy(x => r.Next()).FirstOrDefault();
|
return conn.Table<T>().Where(p).ToList().OrderBy(x => r.Next()).FirstOrDefault();
|
||||||
}
|
}
|
||||||
@ -90,13 +137,14 @@ namespace NadekoBot.Classes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Queries {
|
public static class Queries
|
||||||
|
{
|
||||||
public static string TransactionTriggerQuery = @"
|
public static string TransactionTriggerQuery = @"
|
||||||
CREATE TRIGGER IF NOT EXISTS OnTransactionAdded
|
CREATE TRIGGER IF NOT EXISTS OnTransactionAdded
|
||||||
AFTER INSERT ON CurrencyTransaction
|
AFTER INSERT ON CurrencyTransaction
|
||||||
BEGIN
|
BEGIN
|
||||||
INSERT OR REPLACE INTO CurrencyState (Id, UserId, Value, DateAdded)
|
INSERT OR REPLACE INTO CurrencyState (Id, UserId, Value, DateAdded)
|
||||||
VALUES (COALESCE((SELECT Id from CurrencyState where UserId = NEW.UserId),(SELECT COALESCE(MAX(Id),0)+1 from CurrencyState)),
|
VALUES (COALESCE((SELECT Id from CurrencyState where UserId = NEW.UserId),(SELECT COALESCE(MAX(Id),0)+1 from CurrencyState)),
|
||||||
NEW.UserId,
|
NEW.UserId,
|
||||||
COALESCE((SELECT Value+New.Value FROM CurrencyState Where UserId = NEW.UserId),NEW.Value),
|
COALESCE((SELECT Value+New.Value FROM CurrencyState Where UserId = NEW.UserId),NEW.Value),
|
||||||
NEW.DateAdded);
|
NEW.DateAdded);
|
||||||
|
@ -4,7 +4,7 @@ namespace NadekoBot.Classes
|
|||||||
{
|
{
|
||||||
internal static class FlowersHandler
|
internal static class FlowersHandler
|
||||||
{
|
{
|
||||||
public static async Task AddFlowersAsync(Discord.User u, string reason, int amount)
|
public static async Task AddFlowersAsync(Discord.User u, string reason, int amount, bool silent = false)
|
||||||
{
|
{
|
||||||
if (amount <= 0)
|
if (amount <= 0)
|
||||||
return;
|
return;
|
||||||
@ -17,6 +17,10 @@ namespace NadekoBot.Classes
|
|||||||
Value = amount,
|
Value = amount,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (silent)
|
||||||
|
return;
|
||||||
|
|
||||||
var flows = "";
|
var flows = "";
|
||||||
for (var i = 0; i < amount; i++)
|
for (var i = 0; i < amount; i++)
|
||||||
{
|
{
|
||||||
@ -25,19 +29,23 @@ namespace NadekoBot.Classes
|
|||||||
await u.SendMessage("👑Congratulations!👑\nYou received: " + flows);
|
await u.SendMessage("👑Congratulations!👑\nYou received: " + flows);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task RemoveFlowersAsync(Discord.User u, string reason, int amount)
|
public static bool RemoveFlowers(Discord.User u, string reason, int amount)
|
||||||
{
|
{
|
||||||
if (amount <= 0)
|
if (amount <= 0)
|
||||||
return;
|
return false;
|
||||||
await Task.Run(() =>
|
var uid = (long)u.Id;
|
||||||
|
var state = DbHandler.Instance.FindOne<_DataModels.CurrencyState>(cs => cs.UserId == uid);
|
||||||
|
|
||||||
|
if (state.Value < amount)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DbHandler.Instance.InsertData(new _DataModels.CurrencyTransaction
|
||||||
{
|
{
|
||||||
DbHandler.Instance.InsertData(new _DataModels.CurrencyTransaction
|
Reason = reason,
|
||||||
{
|
UserId = (long)u.Id,
|
||||||
Reason = reason,
|
Value = -amount,
|
||||||
UserId = (long)u.Id,
|
|
||||||
Value = -amount,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ namespace NadekoBot.Classes.JSONModels
|
|||||||
public string Gambling { get; set; } = "$";
|
public string Gambling { get; set; } = "$";
|
||||||
public string Permissions { get; set; } = ";";
|
public string Permissions { get; set; } = ";";
|
||||||
public string Programming { get; set; } = "%";
|
public string Programming { get; set; } = "%";
|
||||||
public string Pokemon { get; set; } = "poke";
|
public string Pokemon { get; set; } = ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ConfigHandler
|
public static class ConfigHandler
|
||||||
|
@ -5,15 +5,18 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
namespace NadekoBot.Classes.Music {
|
namespace NadekoBot.Classes.Music
|
||||||
|
{
|
||||||
|
|
||||||
public enum MusicType {
|
public enum MusicType
|
||||||
|
{
|
||||||
Radio,
|
Radio,
|
||||||
Normal,
|
Normal,
|
||||||
Local
|
Local
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum StreamState {
|
public enum StreamState
|
||||||
|
{
|
||||||
Resolving,
|
Resolving,
|
||||||
Queued,
|
Queued,
|
||||||
Buffering, //not using it atm
|
Buffering, //not using it atm
|
||||||
@ -21,7 +24,8 @@ namespace NadekoBot.Classes.Music {
|
|||||||
Completed
|
Completed
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MusicPlayer {
|
public class MusicPlayer
|
||||||
|
{
|
||||||
public static int MaximumPlaylistSize => 50;
|
public static int MaximumPlaylistSize => 50;
|
||||||
|
|
||||||
private IAudioClient audioClient { get; set; }
|
private IAudioClient audioClient { get; set; }
|
||||||
@ -44,8 +48,11 @@ namespace NadekoBot.Classes.Music {
|
|||||||
public Channel PlaybackVoiceChannel { get; private set; }
|
public Channel PlaybackVoiceChannel { get; private set; }
|
||||||
|
|
||||||
private bool Destroyed { get; set; } = false;
|
private bool Destroyed { get; set; } = false;
|
||||||
|
public bool RepeatSong { get; private set; } = false;
|
||||||
|
public bool RepeatPlaylist { get; private set; } = false;
|
||||||
|
|
||||||
public MusicPlayer(Channel startingVoiceChannel, float? defaultVolume) {
|
public MusicPlayer(Channel startingVoiceChannel, float? defaultVolume)
|
||||||
|
{
|
||||||
if (startingVoiceChannel == null)
|
if (startingVoiceChannel == null)
|
||||||
throw new ArgumentNullException(nameof(startingVoiceChannel));
|
throw new ArgumentNullException(nameof(startingVoiceChannel));
|
||||||
if (startingVoiceChannel.Type != ChannelType.Voice)
|
if (startingVoiceChannel.Type != ChannelType.Voice)
|
||||||
@ -56,27 +63,42 @@ namespace NadekoBot.Classes.Music {
|
|||||||
SongCancelSource = new CancellationTokenSource();
|
SongCancelSource = new CancellationTokenSource();
|
||||||
cancelToken = SongCancelSource.Token;
|
cancelToken = SongCancelSource.Token;
|
||||||
|
|
||||||
Task.Run(async () => {
|
Task.Run(async () =>
|
||||||
while (!Destroyed) {
|
{
|
||||||
try {
|
while (!Destroyed)
|
||||||
if(audioClient?.State != ConnectionState.Connected)
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (audioClient?.State != ConnectionState.Connected)
|
||||||
audioClient = await PlaybackVoiceChannel.JoinAudio();
|
audioClient = await PlaybackVoiceChannel.JoinAudio();
|
||||||
} catch {
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
await Task.Delay(1000);
|
await Task.Delay(1000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
CurrentSong = GetNextSong();
|
CurrentSong = GetNextSong();
|
||||||
var curSong = CurrentSong;
|
var curSong = CurrentSong;
|
||||||
if (curSong != null) {
|
if (curSong != null)
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
OnStarted(this, curSong);
|
OnStarted(this, curSong);
|
||||||
await curSong.Play(audioClient, cancelToken);
|
await curSong.Play(audioClient, cancelToken);
|
||||||
} catch (OperationCanceledException) {
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
Console.WriteLine("Song canceled");
|
Console.WriteLine("Song canceled");
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
Console.WriteLine($"Exception in PlaySong: {ex}");
|
Console.WriteLine($"Exception in PlaySong: {ex}");
|
||||||
}
|
}
|
||||||
OnCompleted(this, curSong);
|
OnCompleted(this, curSong);
|
||||||
|
if (RepeatSong)
|
||||||
|
playlist.Insert(0, curSong);
|
||||||
|
else if (RepeatPlaylist)
|
||||||
|
playlist.Insert(playlist.Count, curSong);
|
||||||
SongCancelSource = new CancellationTokenSource();
|
SongCancelSource = new CancellationTokenSource();
|
||||||
cancelToken = SongCancelSource.Token;
|
cancelToken = SongCancelSource.Token;
|
||||||
}
|
}
|
||||||
@ -85,17 +107,22 @@ namespace NadekoBot.Classes.Music {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Next() {
|
public void Next()
|
||||||
lock (playlistLock) {
|
{
|
||||||
if (!SongCancelSource.IsCancellationRequested) {
|
lock (playlistLock)
|
||||||
|
{
|
||||||
|
if (!SongCancelSource.IsCancellationRequested)
|
||||||
|
{
|
||||||
Paused = false;
|
Paused = false;
|
||||||
SongCancelSource.Cancel();
|
SongCancelSource.Cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Stop() {
|
public void Stop()
|
||||||
lock (playlistLock) {
|
{
|
||||||
|
lock (playlistLock)
|
||||||
|
{
|
||||||
playlist.Clear();
|
playlist.Clear();
|
||||||
CurrentSong = null;
|
CurrentSong = null;
|
||||||
if (!SongCancelSource.IsCancellationRequested)
|
if (!SongCancelSource.IsCancellationRequested)
|
||||||
@ -105,13 +132,16 @@ namespace NadekoBot.Classes.Music {
|
|||||||
|
|
||||||
public void TogglePause() => Paused = !Paused;
|
public void TogglePause() => Paused = !Paused;
|
||||||
|
|
||||||
public void Shuffle() {
|
public void Shuffle()
|
||||||
lock (playlistLock) {
|
{
|
||||||
|
lock (playlistLock)
|
||||||
|
{
|
||||||
playlist.Shuffle();
|
playlist.Shuffle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int SetVolume(int volume) {
|
public int SetVolume(int volume)
|
||||||
|
{
|
||||||
if (volume < 0)
|
if (volume < 0)
|
||||||
volume = 0;
|
volume = 0;
|
||||||
if (volume > 150)
|
if (volume > 150)
|
||||||
@ -121,8 +151,10 @@ namespace NadekoBot.Classes.Music {
|
|||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Song GetNextSong() {
|
private Song GetNextSong()
|
||||||
lock (playlistLock) {
|
{
|
||||||
|
lock (playlistLock)
|
||||||
|
{
|
||||||
if (playlist.Count == 0)
|
if (playlist.Count == 0)
|
||||||
return null;
|
return null;
|
||||||
var toReturn = playlist[0];
|
var toReturn = playlist[0];
|
||||||
@ -131,45 +163,56 @@ namespace NadekoBot.Classes.Music {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddSong(Song s) {
|
public void AddSong(Song s)
|
||||||
|
{
|
||||||
if (s == null)
|
if (s == null)
|
||||||
throw new ArgumentNullException(nameof(s));
|
throw new ArgumentNullException(nameof(s));
|
||||||
lock (playlistLock) {
|
lock (playlistLock)
|
||||||
|
{
|
||||||
playlist.Add(s);
|
playlist.Add(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveSong(Song s) {
|
public void RemoveSong(Song s)
|
||||||
|
{
|
||||||
if (s == null)
|
if (s == null)
|
||||||
throw new ArgumentNullException(nameof(s));
|
throw new ArgumentNullException(nameof(s));
|
||||||
lock (playlistLock) {
|
lock (playlistLock)
|
||||||
|
{
|
||||||
playlist.Remove(s);
|
playlist.Remove(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveSongAt(int index) {
|
public void RemoveSongAt(int index)
|
||||||
lock (playlistLock) {
|
{
|
||||||
|
lock (playlistLock)
|
||||||
|
{
|
||||||
if (index < 0 || index >= playlist.Count)
|
if (index < 0 || index >= playlist.Count)
|
||||||
throw new ArgumentException("Invalid index");
|
throw new ArgumentException("Invalid index");
|
||||||
playlist.RemoveAt(index);
|
playlist.RemoveAt(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Task MoveToVoiceChannel(Channel voiceChannel) {
|
internal Task MoveToVoiceChannel(Channel voiceChannel)
|
||||||
|
{
|
||||||
if (audioClient?.State != ConnectionState.Connected)
|
if (audioClient?.State != ConnectionState.Connected)
|
||||||
throw new InvalidOperationException("Can't move while bot is not connected to voice channel.");
|
throw new InvalidOperationException("Can't move while bot is not connected to voice channel.");
|
||||||
PlaybackVoiceChannel = voiceChannel;
|
PlaybackVoiceChannel = voiceChannel;
|
||||||
return PlaybackVoiceChannel.JoinAudio();
|
return PlaybackVoiceChannel.JoinAudio();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ClearQueue() {
|
internal void ClearQueue()
|
||||||
lock (playlistLock) {
|
{
|
||||||
|
lock (playlistLock)
|
||||||
|
{
|
||||||
playlist.Clear();
|
playlist.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Destroy() {
|
public void Destroy()
|
||||||
lock (playlistLock) {
|
{
|
||||||
|
lock (playlistLock)
|
||||||
|
{
|
||||||
playlist.Clear();
|
playlist.Clear();
|
||||||
Destroyed = true;
|
Destroyed = true;
|
||||||
CurrentSong = null;
|
CurrentSong = null;
|
||||||
@ -178,5 +221,9 @@ namespace NadekoBot.Classes.Music {
|
|||||||
audioClient.Disconnect();
|
audioClient.Disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal bool ToggleRepeatSong() => this.RepeatSong = !this.RepeatSong;
|
||||||
|
|
||||||
|
internal bool ToggleRepeatPlaylist() => this.RepeatPlaylist = !this.RepeatPlaylist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
using Discord;
|
using Discord;
|
||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
|
using NadekoBot.Extensions;
|
||||||
|
using NadekoBot.Modules;
|
||||||
|
using NadekoBot.Modules.Administration.Commands;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NadekoBot.Extensions;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
using NadekoBot.Modules;
|
|
||||||
|
|
||||||
namespace NadekoBot {
|
namespace NadekoBot
|
||||||
public class NadekoStats {
|
{
|
||||||
|
public class NadekoStats
|
||||||
|
{
|
||||||
public static NadekoStats Instance { get; } = new NadekoStats();
|
public static NadekoStats Instance { get; } = new NadekoStats();
|
||||||
|
|
||||||
public string BotVersion => $"{Assembly.GetExecutingAssembly().GetName().Name} v{Assembly.GetExecutingAssembly().GetName().Version}";
|
public string BotVersion => $"{Assembly.GetExecutingAssembly().GetName().Name} v{Assembly.GetExecutingAssembly().GetName().Version}";
|
||||||
@ -23,11 +26,12 @@ namespace NadekoBot {
|
|||||||
public int TextChannelsCount { get; private set; } = 0;
|
public int TextChannelsCount { get; private set; } = 0;
|
||||||
public int VoiceChannelsCount { get; private set; } = 0;
|
public int VoiceChannelsCount { get; private set; } = 0;
|
||||||
|
|
||||||
private readonly Timer commandLogTimer = new Timer() {Interval = 10000};
|
private readonly Timer commandLogTimer = new Timer() { Interval = 10000 };
|
||||||
|
|
||||||
static NadekoStats() { }
|
static NadekoStats() { }
|
||||||
|
|
||||||
private NadekoStats() {
|
private NadekoStats()
|
||||||
|
{
|
||||||
var commandService = NadekoBot.Client.GetService<CommandService>();
|
var commandService = NadekoBot.Client.GetService<CommandService>();
|
||||||
|
|
||||||
statsStopwatch.Start();
|
statsStopwatch.Start();
|
||||||
@ -43,52 +47,66 @@ namespace NadekoBot {
|
|||||||
TextChannelsCount = channelsArray.Count(c => c.Type == ChannelType.Text);
|
TextChannelsCount = channelsArray.Count(c => c.Type == ChannelType.Text);
|
||||||
VoiceChannelsCount = channelsArray.Count() - TextChannelsCount;
|
VoiceChannelsCount = channelsArray.Count() - TextChannelsCount;
|
||||||
|
|
||||||
NadekoBot.Client.JoinedServer += (s, e) => {
|
NadekoBot.Client.JoinedServer += (s, e) =>
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
ServerCount++;
|
ServerCount++;
|
||||||
TextChannelsCount += e.Server.TextChannels.Count();
|
TextChannelsCount += e.Server.TextChannels.Count();
|
||||||
VoiceChannelsCount += e.Server.VoiceChannels.Count();
|
VoiceChannelsCount += e.Server.VoiceChannels.Count();
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
};
|
};
|
||||||
NadekoBot.Client.LeftServer += (s, e) => {
|
NadekoBot.Client.LeftServer += (s, e) =>
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
ServerCount--;
|
ServerCount--;
|
||||||
TextChannelsCount -= e.Server.TextChannels.Count();
|
TextChannelsCount -= e.Server.TextChannels.Count();
|
||||||
VoiceChannelsCount -= e.Server.VoiceChannels.Count();
|
VoiceChannelsCount -= e.Server.VoiceChannels.Count();
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
};
|
};
|
||||||
NadekoBot.Client.ChannelCreated += (s, e) => {
|
NadekoBot.Client.ChannelCreated += (s, e) =>
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
if (e.Channel.IsPrivate)
|
if (e.Channel.IsPrivate)
|
||||||
return;
|
return;
|
||||||
if (e.Channel.Type == ChannelType.Text)
|
if (e.Channel.Type == ChannelType.Text)
|
||||||
TextChannelsCount++;
|
TextChannelsCount++;
|
||||||
else if (e.Channel.Type == ChannelType.Voice)
|
else if (e.Channel.Type == ChannelType.Voice)
|
||||||
VoiceChannelsCount++;
|
VoiceChannelsCount++;
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
};
|
};
|
||||||
NadekoBot.Client.ChannelDestroyed += (s, e) => {
|
NadekoBot.Client.ChannelDestroyed += (s, e) =>
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
if (e.Channel.IsPrivate)
|
if (e.Channel.IsPrivate)
|
||||||
return;
|
return;
|
||||||
if (e.Channel.Type == ChannelType.Text)
|
if (e.Channel.Type == ChannelType.Text)
|
||||||
VoiceChannelsCount++;
|
VoiceChannelsCount++;
|
||||||
else if (e.Channel.Type == ChannelType.Voice)
|
else if (e.Channel.Type == ChannelType.Voice)
|
||||||
VoiceChannelsCount--;
|
VoiceChannelsCount--;
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public TimeSpan GetUptime() =>
|
public TimeSpan GetUptime() =>
|
||||||
DateTime.Now - Process.GetCurrentProcess().StartTime;
|
DateTime.Now - Process.GetCurrentProcess().StartTime;
|
||||||
|
|
||||||
public string GetUptimeString() {
|
public string GetUptimeString()
|
||||||
|
{
|
||||||
var time = (DateTime.Now - Process.GetCurrentProcess().StartTime);
|
var time = (DateTime.Now - Process.GetCurrentProcess().StartTime);
|
||||||
return time.Days + " days, " + time.Hours + " hours, and " + time.Minutes + " minutes.";
|
return time.Days + " days, " + time.Hours + " hours, and " + time.Minutes + " minutes.";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task LoadStats() =>
|
public Task LoadStats() =>
|
||||||
Task.Run(() => {
|
Task.Run(() =>
|
||||||
|
{
|
||||||
var songs = Music.MusicPlayers.Count(mp => mp.Value.CurrentSong != null);
|
var songs = Music.MusicPlayers.Count(mp => mp.Value.CurrentSong != null);
|
||||||
var sb = new System.Text.StringBuilder();
|
var sb = new System.Text.StringBuilder();
|
||||||
sb.AppendLine("`Author: Kwoth` `Library: Discord.Net`");
|
sb.AppendLine("`Author: Kwoth` `Library: Discord.Net`");
|
||||||
@ -102,7 +120,7 @@ namespace NadekoBot {
|
|||||||
sb.AppendLine($" | VoiceChannels: {VoiceChannelsCount}`");
|
sb.AppendLine($" | VoiceChannels: {VoiceChannelsCount}`");
|
||||||
sb.AppendLine($"`Commands Ran this session: {commandsRan}`");
|
sb.AppendLine($"`Commands Ran this session: {commandsRan}`");
|
||||||
sb.AppendLine($"`Message queue size: {NadekoBot.Client.MessageQueue.Count}`");
|
sb.AppendLine($"`Message queue size: {NadekoBot.Client.MessageQueue.Count}`");
|
||||||
sb.Append($"`Greeted {Commands.ServerGreetCommand.Greeted} times.`");
|
sb.Append($"`Greeted {ServerGreetCommand.Greeted} times.`");
|
||||||
sb.AppendLine($" `| Playing {songs} songs, ".SnPl(songs) +
|
sb.AppendLine($" `| Playing {songs} songs, ".SnPl(songs) +
|
||||||
$"{Music.MusicPlayers.Sum(kvp => kvp.Value.Playlist.Count)} queued.`");
|
$"{Music.MusicPlayers.Sum(kvp => kvp.Value.Playlist.Count)} queued.`");
|
||||||
sb.AppendLine($"`Heap: {Heap(false)}`");
|
sb.AppendLine($"`Heap: {Heap(false)}`");
|
||||||
@ -111,7 +129,8 @@ namespace NadekoBot {
|
|||||||
|
|
||||||
public string Heap(bool pass = true) => Math.Round((double)GC.GetTotalMemory(pass) / 1.MiB(), 2).ToString();
|
public string Heap(bool pass = true) => Math.Round((double)GC.GetTotalMemory(pass) / 1.MiB(), 2).ToString();
|
||||||
|
|
||||||
public async Task<string> GetStats() {
|
public async Task<string> GetStats()
|
||||||
|
{
|
||||||
if (statsStopwatch.Elapsed.Seconds < 4 &&
|
if (statsStopwatch.Elapsed.Seconds < 4 &&
|
||||||
!string.IsNullOrWhiteSpace(statsCache)) return statsCache;
|
!string.IsNullOrWhiteSpace(statsCache)) return statsCache;
|
||||||
await LoadStats();
|
await LoadStats();
|
||||||
@ -119,35 +138,45 @@ namespace NadekoBot {
|
|||||||
return statsCache;
|
return statsCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task StartCollecting() {
|
private async Task StartCollecting()
|
||||||
while (true) {
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
await Task.Delay(new TimeSpan(0, 30, 0));
|
await Task.Delay(new TimeSpan(0, 30, 0));
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
var onlineUsers = await Task.Run(() => NadekoBot.Client.Servers.Sum(x => x.Users.Count()));
|
var onlineUsers = await Task.Run(() => NadekoBot.Client.Servers.Sum(x => x.Users.Count()));
|
||||||
var realOnlineUsers = await Task.Run(() => NadekoBot.Client.Servers
|
var realOnlineUsers = await Task.Run(() => NadekoBot.Client.Servers
|
||||||
.Sum(x => x.Users.Count(u => u.Status == UserStatus.Online)));
|
.Sum(x => x.Users.Count(u => u.Status == UserStatus.Online)));
|
||||||
var connectedServers = NadekoBot.Client.Servers.Count();
|
var connectedServers = NadekoBot.Client.Servers.Count();
|
||||||
|
|
||||||
Classes.DbHandler.Instance.InsertData(new Classes._DataModels.Stats {
|
Classes.DbHandler.Instance.InsertData(new Classes._DataModels.Stats
|
||||||
|
{
|
||||||
OnlineUsers = onlineUsers,
|
OnlineUsers = onlineUsers,
|
||||||
RealOnlineUsers = realOnlineUsers,
|
RealOnlineUsers = realOnlineUsers,
|
||||||
Uptime = GetUptime(),
|
Uptime = GetUptime(),
|
||||||
ConnectedServers = connectedServers,
|
ConnectedServers = connectedServers,
|
||||||
DateAdded = DateTime.Now
|
DateAdded = DateTime.Now
|
||||||
});
|
});
|
||||||
} catch {
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
Console.WriteLine("DB Exception in stats collecting.");
|
Console.WriteLine("DB Exception in stats collecting.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void StatsCollector_RanCommand(object sender, CommandEventArgs e) {
|
private async void StatsCollector_RanCommand(object sender, CommandEventArgs e)
|
||||||
|
{
|
||||||
Console.WriteLine($">>Command {e.Command.Text}");
|
Console.WriteLine($">>Command {e.Command.Text}");
|
||||||
await Task.Run(() => {
|
await Task.Run(() =>
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
commandsRan++;
|
commandsRan++;
|
||||||
Classes.DbHandler.Instance.InsertData(new Classes._DataModels.Command {
|
Classes.DbHandler.Instance.InsertData(new Classes._DataModels.Command
|
||||||
|
{
|
||||||
ServerId = (long)e.Server.Id,
|
ServerId = (long)e.Server.Id,
|
||||||
ServerName = e.Server.Name,
|
ServerName = e.Server.Name,
|
||||||
ChannelId = (long)e.Channel.Id,
|
ChannelId = (long)e.Channel.Id,
|
||||||
@ -157,7 +186,9 @@ namespace NadekoBot {
|
|||||||
CommandName = e.Command.Text,
|
CommandName = e.Command.Text,
|
||||||
DateAdded = DateTime.Now
|
DateAdded = DateTime.Now
|
||||||
});
|
});
|
||||||
} catch {
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
Console.WriteLine("Error in ran command DB write.");
|
Console.WriteLine("Error in ran command DB write.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
using System;
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using NadekoBot.Classes.JSONModels;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace NadekoBot.Classes {
|
namespace NadekoBot.Classes
|
||||||
internal class SpecificConfigurations {
|
{
|
||||||
|
internal class SpecificConfigurations
|
||||||
|
{
|
||||||
public static SpecificConfigurations Default { get; } = new SpecificConfigurations();
|
public static SpecificConfigurations Default { get; } = new SpecificConfigurations();
|
||||||
public static bool Instantiated { get; private set; }
|
public static bool Instantiated { get; private set; }
|
||||||
|
|
||||||
@ -17,14 +18,19 @@ namespace NadekoBot.Classes {
|
|||||||
|
|
||||||
static SpecificConfigurations() { }
|
static SpecificConfigurations() { }
|
||||||
|
|
||||||
private SpecificConfigurations() {
|
private SpecificConfigurations()
|
||||||
|
{
|
||||||
|
|
||||||
if (File.Exists(filePath)) {
|
if (File.Exists(filePath))
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
configs = JsonConvert
|
configs = JsonConvert
|
||||||
.DeserializeObject<ConcurrentDictionary<ulong, ServerSpecificConfig>>(
|
.DeserializeObject<ConcurrentDictionary<ulong, ServerSpecificConfig>>(
|
||||||
File.ReadAllText(filePath));
|
File.ReadAllText(filePath));
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
Console.WriteLine($"Deserialization failing: {ex}");
|
Console.WriteLine($"Deserialization failing: {ex}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,14 +48,17 @@ namespace NadekoBot.Classes {
|
|||||||
|
|
||||||
private readonly object saveLock = new object();
|
private readonly object saveLock = new object();
|
||||||
|
|
||||||
public void Save() {
|
public void Save()
|
||||||
lock (saveLock) {
|
{
|
||||||
|
lock (saveLock)
|
||||||
|
{
|
||||||
File.WriteAllText(filePath, JsonConvert.SerializeObject(configs, Formatting.Indented));
|
File.WriteAllText(filePath, JsonConvert.SerializeObject(configs, Formatting.Indented));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ServerSpecificConfig : INotifyPropertyChanged {
|
internal class ServerSpecificConfig : INotifyPropertyChanged
|
||||||
|
{
|
||||||
[JsonProperty("VoicePlusTextEnabled")]
|
[JsonProperty("VoicePlusTextEnabled")]
|
||||||
private bool voicePlusTextEnabled;
|
private bool voicePlusTextEnabled;
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
@ -78,7 +87,8 @@ namespace NadekoBot.Classes {
|
|||||||
set {
|
set {
|
||||||
listOfSelfAssignableRoles = value;
|
listOfSelfAssignableRoles = value;
|
||||||
if (value != null)
|
if (value != null)
|
||||||
listOfSelfAssignableRoles.CollectionChanged += (s, e) => {
|
listOfSelfAssignableRoles.CollectionChanged += (s, e) =>
|
||||||
|
{
|
||||||
if (!SpecificConfigurations.Instantiated) return;
|
if (!SpecificConfigurations.Instantiated) return;
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
};
|
};
|
||||||
@ -92,34 +102,39 @@ namespace NadekoBot.Classes {
|
|||||||
set {
|
set {
|
||||||
observingStreams = value;
|
observingStreams = value;
|
||||||
if (value != null)
|
if (value != null)
|
||||||
observingStreams.CollectionChanged += (s, e) => {
|
observingStreams.CollectionChanged += (s, e) =>
|
||||||
|
{
|
||||||
if (!SpecificConfigurations.Instantiated) return;
|
if (!SpecificConfigurations.Instantiated) return;
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerSpecificConfig() {
|
public ServerSpecificConfig()
|
||||||
|
{
|
||||||
ListOfSelfAssignableRoles = new ObservableCollection<ulong>();
|
ListOfSelfAssignableRoles = new ObservableCollection<ulong>();
|
||||||
ObservingStreams = new ObservableCollection<StreamNotificationConfig>();
|
ObservingStreams = new ObservableCollection<StreamNotificationConfig>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged = delegate { SpecificConfigurations.Default.Save(); };
|
public event PropertyChangedEventHandler PropertyChanged = delegate { SpecificConfigurations.Default.Save(); };
|
||||||
|
|
||||||
private void OnPropertyChanged([CallerMemberName] string propertyName = null) {
|
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
Console.WriteLine("property changed");
|
Console.WriteLine("property changed");
|
||||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
|
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StreamNotificationConfig : IEquatable<StreamNotificationConfig> {
|
public class StreamNotificationConfig : IEquatable<StreamNotificationConfig>
|
||||||
|
{
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
public StreamType Type { get; set; }
|
public StreamType Type { get; set; }
|
||||||
public ulong ServerId { get; set; }
|
public ulong ServerId { get; set; }
|
||||||
public ulong ChannelId { get; set; }
|
public ulong ChannelId { get; set; }
|
||||||
public bool LastStatus { get; set; }
|
public bool LastStatus { get; set; }
|
||||||
|
|
||||||
public enum StreamType {
|
public enum StreamType
|
||||||
|
{
|
||||||
Twitch,
|
Twitch,
|
||||||
Beam,
|
Beam,
|
||||||
Hitbox,
|
Hitbox,
|
||||||
@ -131,7 +146,8 @@ namespace NadekoBot.Classes {
|
|||||||
this.Type == other.Type &&
|
this.Type == other.Type &&
|
||||||
this.ServerId == other.ServerId;
|
this.ServerId == other.ServerId;
|
||||||
|
|
||||||
public override int GetHashCode() {
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
return (int)((int)ServerId + Username.Length + (int)Type);
|
return (int)((int)ServerId + Username.Length + (int)Type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Classes._DataModels
|
namespace NadekoBot.Classes._DataModels
|
||||||
{
|
{
|
||||||
class userPokeTypes : IDataModel
|
class UserPokeTypes : IDataModel
|
||||||
{
|
{
|
||||||
public long UserId { get; set; }
|
public long UserId { get; set; }
|
||||||
public int type { get; set; }
|
public int type { get; set; }
|
||||||
|
14
NadekoBot/Classes/_DataModels/Reminder.cs
Normal file
14
NadekoBot/Classes/_DataModels/Reminder.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace NadekoBot.Classes._DataModels
|
||||||
|
{
|
||||||
|
class Reminder : IDataModel
|
||||||
|
{
|
||||||
|
public DateTime When { get; set; }
|
||||||
|
public long ChannelId { get; set; }
|
||||||
|
public long ServerId { get; set; }
|
||||||
|
public long UserId { get; set; }
|
||||||
|
public string Message { get; set; }
|
||||||
|
public bool IsPrivate { get; set; }
|
||||||
|
}
|
||||||
|
}
|
56
NadekoBot/Commands/Bomberman.cs
Normal file
56
NadekoBot/Commands/Bomberman.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
using Discord;
|
||||||
|
using Discord.Commands;
|
||||||
|
using NadekoBot.Classes;
|
||||||
|
using NadekoBot.Modules;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace NadekoBot.Commands
|
||||||
|
{
|
||||||
|
class Bomberman : DiscordCommand
|
||||||
|
{
|
||||||
|
public Bomberman(DiscordModule module) : base(module)
|
||||||
|
{
|
||||||
|
NadekoBot.Client.MessageReceived += async (s, e) =>
|
||||||
|
{
|
||||||
|
if (e.Channel.Id != bombGame.ChannelId) return;
|
||||||
|
|
||||||
|
var text = e.Message.Text;
|
||||||
|
await e.Message.Delete();
|
||||||
|
HandleBombermanCommand(e.User, text);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleBombermanCommand(User user, string text)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
//only one bomberman game can run at any one time
|
||||||
|
public static BombermanGame bombGame = null;
|
||||||
|
private readonly object locker = new object();
|
||||||
|
internal override void Init(CommandGroupBuilder cgb)
|
||||||
|
{
|
||||||
|
cgb.CreateCommand($"{Module.Prefix}bmb")
|
||||||
|
.Description("Creates a bomberman game for this channel or join existing one." +
|
||||||
|
" If you are 4th player - Game will start. After game starts " +
|
||||||
|
" everything written in the channel will be autodeleted and treated as a bomberman command." +
|
||||||
|
" only one bomberman game can run at any one time per bot. Game will run at 1FPS." +
|
||||||
|
" You must have manage messages permissions in order to create the game.")
|
||||||
|
.Do(e =>
|
||||||
|
{
|
||||||
|
lock (locker)
|
||||||
|
{
|
||||||
|
if (bombGame == null || bombGame.Ended)
|
||||||
|
{
|
||||||
|
if (!e.User.ServerPermissions.ManageMessages ||
|
||||||
|
!e.Server.GetUser(NadekoBot.Client.CurrentUser.Id).ServerPermissions.ManageMessages)
|
||||||
|
{
|
||||||
|
e.Channel.SendMessage("Both you and Nadeko need manage messages permissions to start a new bomberman game.").Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,27 +1,29 @@
|
|||||||
using System;
|
using Discord;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Discord;
|
|
||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
using NadekoBot.Classes;
|
using NadekoBot.Classes;
|
||||||
using NadekoBot.Classes.Permissions;
|
using NadekoBot.Classes.Permissions;
|
||||||
using NadekoBot.Modules;
|
using NadekoBot.Modules;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using ServerPermissions = NadekoBot.Classes.Permissions.ServerPermissions;
|
using ServerPermissions = NadekoBot.Classes.Permissions.ServerPermissions;
|
||||||
|
|
||||||
namespace NadekoBot.Commands {
|
namespace NadekoBot.Commands
|
||||||
internal class FilterWords : DiscordCommand {
|
{
|
||||||
public FilterWords(DiscordModule module) : base(module) {
|
internal class FilterWords : DiscordCommand
|
||||||
NadekoBot.Client.MessageReceived += async (sender, args) => {
|
{
|
||||||
|
public FilterWords(DiscordModule module) : base(module)
|
||||||
|
{
|
||||||
|
NadekoBot.Client.MessageReceived += async (sender, args) =>
|
||||||
|
{
|
||||||
if (args.Channel.IsPrivate || args.User.Id == NadekoBot.Client.CurrentUser.Id) return;
|
if (args.Channel.IsPrivate || args.User.Id == NadekoBot.Client.CurrentUser.Id) return;
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
ServerPermissions serverPerms;
|
ServerPermissions serverPerms;
|
||||||
if (!IsChannelOrServerFiltering(args.Channel, out serverPerms)) return;
|
if (!IsChannelOrServerFiltering(args.Channel, out serverPerms)) return;
|
||||||
|
|
||||||
var wordsInMessage = args.Message.RawText.ToLowerInvariant().Split(' ');
|
var wordsInMessage = args.Message.RawText.ToLowerInvariant().Split(' ');
|
||||||
if (serverPerms.Words.Any(w => wordsInMessage.Contains(w))) {
|
if (serverPerms.Words.Any(w => wordsInMessage.Contains(w)))
|
||||||
|
{
|
||||||
await args.Message.Delete();
|
await args.Message.Delete();
|
||||||
IncidentsHandler.Add(args.Server.Id, $"User [{args.User.Name}/{args.User.Id}] posted " +
|
IncidentsHandler.Add(args.Server.Id, $"User [{args.User.Name}/{args.User.Id}] posted " +
|
||||||
$"BANNED WORD in [{args.Channel.Name}/{args.Channel.Id}] channel. " +
|
$"BANNED WORD in [{args.Channel.Name}/{args.Channel.Id}] channel. " +
|
||||||
@ -30,11 +32,13 @@ namespace NadekoBot.Commands {
|
|||||||
await args.Channel.SendMessage($"{args.User.Mention} One or more of the words you used " +
|
await args.Channel.SendMessage($"{args.User.Mention} One or more of the words you used " +
|
||||||
$"in that sentence are not allowed here.");
|
$"in that sentence are not allowed here.");
|
||||||
}
|
}
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsChannelOrServerFiltering(Channel channel, out ServerPermissions serverPerms) {
|
private static bool IsChannelOrServerFiltering(Channel channel, out ServerPermissions serverPerms)
|
||||||
|
{
|
||||||
if (!PermissionsHandler.PermissionsDict.TryGetValue(channel.Server.Id, out serverPerms)) return false;
|
if (!PermissionsHandler.PermissionsDict.TryGetValue(channel.Server.Id, out serverPerms)) return false;
|
||||||
|
|
||||||
if (serverPerms.Permissions.FilterWords)
|
if (serverPerms.Permissions.FilterWords)
|
||||||
@ -44,7 +48,8 @@ namespace NadekoBot.Commands {
|
|||||||
return serverPerms.ChannelPermissions.TryGetValue(channel.Id, out perms) && perms.FilterWords;
|
return serverPerms.ChannelPermissions.TryGetValue(channel.Id, out perms) && perms.FilterWords;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override void Init(CommandGroupBuilder cgb) {
|
internal override void Init(CommandGroupBuilder cgb)
|
||||||
|
{
|
||||||
cgb.CreateCommand(Module.Prefix + "cfw")
|
cgb.CreateCommand(Module.Prefix + "cfw")
|
||||||
.Alias(Module.Prefix + "channelfilterwords")
|
.Alias(Module.Prefix + "channelfilterwords")
|
||||||
.Description("Enables or disables automatic deleting of messages containing banned words on the channel." +
|
.Description("Enables or disables automatic deleting of messages containing banned words on the channel." +
|
||||||
@ -52,12 +57,15 @@ namespace NadekoBot.Commands {
|
|||||||
"\n**Usage**: ;cfi enable #general-chat")
|
"\n**Usage**: ;cfi enable #general-chat")
|
||||||
.Parameter("bool")
|
.Parameter("bool")
|
||||||
.Parameter("channel", ParameterType.Optional)
|
.Parameter("channel", ParameterType.Optional)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||||
var chanStr = e.GetArg("channel")?.ToLowerInvariant().Trim();
|
var chanStr = e.GetArg("channel")?.ToLowerInvariant().Trim();
|
||||||
|
|
||||||
if (chanStr != "all") {
|
if (chanStr != "all")
|
||||||
|
{
|
||||||
var chan = string.IsNullOrWhiteSpace(chanStr)
|
var chan = string.IsNullOrWhiteSpace(chanStr)
|
||||||
? e.Channel
|
? e.Channel
|
||||||
: PermissionHelper.ValidateChannel(e.Server, chanStr);
|
: PermissionHelper.ValidateChannel(e.Server, chanStr);
|
||||||
@ -67,11 +75,14 @@ namespace NadekoBot.Commands {
|
|||||||
}
|
}
|
||||||
//all channels
|
//all channels
|
||||||
|
|
||||||
foreach (var curChannel in e.Server.TextChannels) {
|
foreach (var curChannel in e.Server.TextChannels)
|
||||||
|
{
|
||||||
PermissionsHandler.SetChannelWordPermission(curChannel, state);
|
PermissionsHandler.SetChannelWordPermission(curChannel, state);
|
||||||
}
|
}
|
||||||
await e.Channel.SendMessage($"Word filtering has been **{(state ? "enabled" : "disabled")}** for **ALL** channels.");
|
await e.Channel.SendMessage($"Word filtering has been **{(state ? "enabled" : "disabled")}** for **ALL** channels.");
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage($"💢 Error: {ex.Message}");
|
await e.Channel.SendMessage($"💢 Error: {ex.Message}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -81,15 +92,19 @@ namespace NadekoBot.Commands {
|
|||||||
.Description("Adds a new word to the list of filtered words" +
|
.Description("Adds a new word to the list of filtered words" +
|
||||||
"\n**Usage**: ;aw poop")
|
"\n**Usage**: ;aw poop")
|
||||||
.Parameter("word", ParameterType.Unparsed)
|
.Parameter("word", ParameterType.Unparsed)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
var word = e.GetArg("word");
|
var word = e.GetArg("word");
|
||||||
if (string.IsNullOrWhiteSpace(word))
|
if (string.IsNullOrWhiteSpace(word))
|
||||||
return;
|
return;
|
||||||
PermissionsHandler.AddFilteredWord(e.Server, word.ToLowerInvariant().Trim());
|
PermissionsHandler.AddFilteredWord(e.Server, word.ToLowerInvariant().Trim());
|
||||||
await e.Channel.SendMessage($"Successfully added new filtered word.");
|
await e.Channel.SendMessage($"Successfully added new filtered word.");
|
||||||
|
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage($"💢 Error: {ex.Message}");
|
await e.Channel.SendMessage($"💢 Error: {ex.Message}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -99,15 +114,19 @@ namespace NadekoBot.Commands {
|
|||||||
.Description("Removes the word from the list of filtered words" +
|
.Description("Removes the word from the list of filtered words" +
|
||||||
"\n**Usage**: ;rw poop")
|
"\n**Usage**: ;rw poop")
|
||||||
.Parameter("word", ParameterType.Unparsed)
|
.Parameter("word", ParameterType.Unparsed)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
var word = e.GetArg("word");
|
var word = e.GetArg("word");
|
||||||
if (string.IsNullOrWhiteSpace(word))
|
if (string.IsNullOrWhiteSpace(word))
|
||||||
return;
|
return;
|
||||||
PermissionsHandler.RemoveFilteredWord(e.Server, word.ToLowerInvariant().Trim());
|
PermissionsHandler.RemoveFilteredWord(e.Server, word.ToLowerInvariant().Trim());
|
||||||
await e.Channel.SendMessage($"Successfully removed filtered word.");
|
await e.Channel.SendMessage($"Successfully removed filtered word.");
|
||||||
|
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage($"💢 Error: {ex.Message}");
|
await e.Channel.SendMessage($"💢 Error: {ex.Message}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -116,14 +135,18 @@ namespace NadekoBot.Commands {
|
|||||||
.Alias(Module.Prefix + "listfilteredwords")
|
.Alias(Module.Prefix + "listfilteredwords")
|
||||||
.Description("Shows a list of filtered words" +
|
.Description("Shows a list of filtered words" +
|
||||||
"\n**Usage**: ;lfw")
|
"\n**Usage**: ;lfw")
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
ServerPermissions serverPerms;
|
ServerPermissions serverPerms;
|
||||||
if (!PermissionsHandler.PermissionsDict.TryGetValue(e.Server.Id, out serverPerms))
|
if (!PermissionsHandler.PermissionsDict.TryGetValue(e.Server.Id, out serverPerms))
|
||||||
return;
|
return;
|
||||||
await e.Channel.SendMessage($"There are `{serverPerms.Words.Count}` filtered words.\n" +
|
await e.Channel.SendMessage($"There are `{serverPerms.Words.Count}` filtered words.\n" +
|
||||||
string.Join("\n", serverPerms.Words));
|
string.Join("\n", serverPerms.Words));
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage($"💢 Error: {ex.Message}");
|
await e.Channel.SendMessage($"💢 Error: {ex.Message}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -132,13 +155,17 @@ namespace NadekoBot.Commands {
|
|||||||
.Alias(Module.Prefix + "serverfilterwords")
|
.Alias(Module.Prefix + "serverfilterwords")
|
||||||
.Description("Enables or disables automatic deleting of messages containing forbidden words on the server.\n**Usage**: ;sfi disable")
|
.Description("Enables or disables automatic deleting of messages containing forbidden words on the server.\n**Usage**: ;sfi disable")
|
||||||
.Parameter("bool")
|
.Parameter("bool")
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||||
PermissionsHandler.SetServerWordPermission(e.Server, state);
|
PermissionsHandler.SetServerWordPermission(e.Server, state);
|
||||||
await e.Channel.SendMessage($"Word filtering has been **{(state ? "enabled" : "disabled")}** on this server.");
|
await e.Channel.SendMessage($"Word filtering has been **{(state ? "enabled" : "disabled")}** on this server.");
|
||||||
|
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage($"💢 Error: {ex.Message}");
|
await e.Channel.SendMessage($"💢 Error: {ex.Message}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
85
NadekoBot/Commands/PlantPick.cs
Normal file
85
NadekoBot/Commands/PlantPick.cs
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
using Discord;
|
||||||
|
using Discord.Commands;
|
||||||
|
using NadekoBot.Classes;
|
||||||
|
using NadekoBot.Modules;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NadekoBot.Commands
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Flower picking/planting idea is given to me by its
|
||||||
|
/// inceptor Violent Crumble from Game Developers League discord server
|
||||||
|
/// (he has !cookie and !nom) Thanks a lot Violent!
|
||||||
|
/// Check out GDL (its a growing gamedev community):
|
||||||
|
/// https://discord.gg/0TYNJfCU4De7YIk8
|
||||||
|
/// </summary>
|
||||||
|
class PlantPick : DiscordCommand
|
||||||
|
{
|
||||||
|
public PlantPick(DiscordModule module) : base(module)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//channelid/messageid pair
|
||||||
|
ConcurrentDictionary<ulong, Message> plantedFlowerChannels = new ConcurrentDictionary<ulong, Message>();
|
||||||
|
|
||||||
|
private object locker = new object();
|
||||||
|
|
||||||
|
internal override void Init(CommandGroupBuilder cgb)
|
||||||
|
{
|
||||||
|
cgb.CreateCommand(Module.Prefix + "pick")
|
||||||
|
.Description("Picks a flower planted in this channel.")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
Message msg;
|
||||||
|
|
||||||
|
await e.Message.Delete();
|
||||||
|
if (!plantedFlowerChannels.TryRemove(e.Channel.Id, out msg))
|
||||||
|
return;
|
||||||
|
|
||||||
|
await msg.Delete();
|
||||||
|
await FlowersHandler.AddFlowersAsync(e.User, "Picked a flower.", 1, true);
|
||||||
|
msg = await e.Channel.SendMessage($"**{e.User.Name}** picked a {NadekoBot.Config.CurrencyName}!");
|
||||||
|
await Task.Delay(10000);
|
||||||
|
await msg.Delete();
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand(Module.Prefix + "plant")
|
||||||
|
.Description("Spend a flower to plant it in this channel. (If bot is restarted or crashes, flower will be lost)")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
lock (locker)
|
||||||
|
{
|
||||||
|
if (plantedFlowerChannels.ContainsKey(e.Channel.Id))
|
||||||
|
{
|
||||||
|
e.Channel.SendMessage($"There is already a {NadekoBot.Config.CurrencyName} in this channel.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var removed = FlowersHandler.RemoveFlowers(e.User, "Planted a flower.", 1);
|
||||||
|
if (!removed)
|
||||||
|
{
|
||||||
|
e.Channel.SendMessage($"You don't have any {NadekoBot.Config.CurrencyName}s.").Wait();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var rng = new Random();
|
||||||
|
var file = Directory.GetFiles("data/currency_images").OrderBy(s => rng.Next()).FirstOrDefault();
|
||||||
|
Message msg;
|
||||||
|
if (file == null)
|
||||||
|
msg = e.Channel.SendMessage("🌸").Result;
|
||||||
|
else
|
||||||
|
msg = e.Channel.SendFile(file).Result;
|
||||||
|
plantedFlowerChannels.TryAdd(e.Channel.Id, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg2 = await e.Channel.SendMessage($"Oh how Nice! **{e.User.Name}** planted a flower. Pick it using {Module.Prefix}pick");
|
||||||
|
await Task.Delay(20000);
|
||||||
|
await msg2.Delete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ using NadekoBot.Classes.Permissions;
|
|||||||
using NadekoBot.Modules;
|
using NadekoBot.Modules;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
@ -18,11 +19,15 @@ namespace NadekoBot.Commands
|
|||||||
{
|
{
|
||||||
Interval = new TimeSpan(0, 0, 15).TotalMilliseconds,
|
Interval = new TimeSpan(0, 0, 15).TotalMilliseconds,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private ConcurrentDictionary<string, Tuple<bool, string>> cachedStatuses = new ConcurrentDictionary<string, Tuple<bool, string>>();
|
||||||
|
|
||||||
public StreamNotifications(DiscordModule module) : base(module)
|
public StreamNotifications(DiscordModule module) : base(module)
|
||||||
{
|
{
|
||||||
|
|
||||||
checkTimer.Elapsed += async (s, e) =>
|
checkTimer.Elapsed += async (s, e) =>
|
||||||
{
|
{
|
||||||
|
cachedStatuses.Clear();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var streams = SpecificConfigurations.Default.AllConfigs.SelectMany(c => c.ObservingStreams);
|
var streams = SpecificConfigurations.Default.AllConfigs.SelectMany(c => c.ObservingStreams);
|
||||||
@ -74,23 +79,39 @@ namespace NadekoBot.Commands
|
|||||||
bool isLive;
|
bool isLive;
|
||||||
string response;
|
string response;
|
||||||
JObject data;
|
JObject data;
|
||||||
|
Tuple<bool, string> result;
|
||||||
switch (stream.Type)
|
switch (stream.Type)
|
||||||
{
|
{
|
||||||
case StreamNotificationConfig.StreamType.Hitbox:
|
case StreamNotificationConfig.StreamType.Hitbox:
|
||||||
response = await SearchHelper.GetResponseStringAsync($"https://api.hitbox.tv/media/status/{stream.Username}");
|
var hitboxUrl = $"https://api.hitbox.tv/media/status/{stream.Username}";
|
||||||
|
if (cachedStatuses.TryGetValue(hitboxUrl, out result))
|
||||||
|
return result;
|
||||||
|
response = await SearchHelper.GetResponseStringAsync(hitboxUrl);
|
||||||
data = JObject.Parse(response);
|
data = JObject.Parse(response);
|
||||||
isLive = data["media_is_live"].ToString() == "1";
|
isLive = data["media_is_live"].ToString() == "1";
|
||||||
return new Tuple<bool, string>(isLive, data["media_views"].ToString());
|
result = new Tuple<bool, string>(isLive, data["media_views"].ToString());
|
||||||
|
cachedStatuses.TryAdd(hitboxUrl, result);
|
||||||
|
return result;
|
||||||
case StreamNotificationConfig.StreamType.Twitch:
|
case StreamNotificationConfig.StreamType.Twitch:
|
||||||
response = await SearchHelper.GetResponseStringAsync($"https://api.twitch.tv/kraken/streams/{Uri.EscapeUriString(stream.Username)}");
|
var twitchUrl = $"https://api.twitch.tv/kraken/streams/{Uri.EscapeUriString(stream.Username)}";
|
||||||
|
if (cachedStatuses.TryGetValue(twitchUrl, out result))
|
||||||
|
return result;
|
||||||
|
response = await SearchHelper.GetResponseStringAsync(twitchUrl);
|
||||||
data = JObject.Parse(response);
|
data = JObject.Parse(response);
|
||||||
isLive = !string.IsNullOrWhiteSpace(data["stream"].ToString());
|
isLive = !string.IsNullOrWhiteSpace(data["stream"].ToString());
|
||||||
return new Tuple<bool, string>(isLive, isLive ? data["stream"]["viewers"].ToString() : "0");
|
result = new Tuple<bool, string>(isLive, isLive ? data["stream"]["viewers"].ToString() : "0");
|
||||||
|
cachedStatuses.TryAdd(twitchUrl, result);
|
||||||
|
return result;
|
||||||
case StreamNotificationConfig.StreamType.Beam:
|
case StreamNotificationConfig.StreamType.Beam:
|
||||||
response = await SearchHelper.GetResponseStringAsync($"https://beam.pro/api/v1/channels/{stream.Username}");
|
var beamUrl = $"https://beam.pro/api/v1/channels/{stream.Username}";
|
||||||
|
if (cachedStatuses.TryGetValue(beamUrl, out result))
|
||||||
|
return result;
|
||||||
|
response = await SearchHelper.GetResponseStringAsync(beamUrl);
|
||||||
data = JObject.Parse(response);
|
data = JObject.Parse(response);
|
||||||
isLive = data["online"].ToObject<bool>() == true;
|
isLive = data["online"].ToObject<bool>() == true;
|
||||||
return new Tuple<bool, string>(isLive, data["viewersCurrent"].ToString());
|
result = new Tuple<bool, string>(isLive, data["viewersCurrent"].ToString());
|
||||||
|
cachedStatuses.TryAdd(beamUrl, result);
|
||||||
|
return result;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4,19 +4,19 @@ using Discord.Modules;
|
|||||||
using NadekoBot.Classes;
|
using NadekoBot.Classes;
|
||||||
using NadekoBot.Classes._DataModels;
|
using NadekoBot.Classes._DataModels;
|
||||||
using NadekoBot.Classes.Permissions;
|
using NadekoBot.Classes.Permissions;
|
||||||
using NadekoBot.Commands;
|
|
||||||
using NadekoBot.Extensions;
|
using NadekoBot.Extensions;
|
||||||
|
using NadekoBot.Modules.Administration.Commands;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace NadekoBot.Modules
|
namespace NadekoBot.Modules.Administration
|
||||||
{
|
{
|
||||||
internal class Administration : DiscordModule
|
internal class AdministrationModule : DiscordModule
|
||||||
{
|
{
|
||||||
public Administration()
|
public AdministrationModule()
|
||||||
{
|
{
|
||||||
commands.Add(new ServerGreetCommand(this));
|
commands.Add(new ServerGreetCommand(this));
|
||||||
commands.Add(new LogCommand(this));
|
commands.Add(new LogCommand(this));
|
||||||
@ -26,6 +26,7 @@ namespace NadekoBot.Modules
|
|||||||
commands.Add(new VoicePlusTextCommand(this));
|
commands.Add(new VoicePlusTextCommand(this));
|
||||||
commands.Add(new CrossServerTextChannel(this));
|
commands.Add(new CrossServerTextChannel(this));
|
||||||
commands.Add(new SelfAssignedRolesCommand(this));
|
commands.Add(new SelfAssignedRolesCommand(this));
|
||||||
|
commands.Add(new Remind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Administration;
|
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Administration;
|
||||||
@ -227,6 +228,7 @@ namespace NadekoBot.Modules
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await e.Server.Ban(usr);
|
await e.Server.Ban(usr);
|
||||||
|
|
||||||
await e.Channel.SendMessage("Banned user " + usr.Name + " Id: " + usr.Id);
|
await e.Channel.SendMessage("Banned user " + usr.Name + " Id: " + usr.Id);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@ -456,6 +458,7 @@ namespace NadekoBot.Modules
|
|||||||
cgb.CreateCommand(Prefix + "st").Alias(Prefix + "settopic")
|
cgb.CreateCommand(Prefix + "st").Alias(Prefix + "settopic")
|
||||||
.Alias(Prefix + "topic")
|
.Alias(Prefix + "topic")
|
||||||
.Description("Sets a topic on the current channel.")
|
.Description("Sets a topic on the current channel.")
|
||||||
|
.AddCheck(SimpleCheckers.ManageChannels())
|
||||||
.Parameter("topic", ParameterType.Unparsed)
|
.Parameter("topic", ParameterType.Unparsed)
|
||||||
.Do(async e =>
|
.Do(async e =>
|
||||||
{
|
{
|
@ -1,36 +1,48 @@
|
|||||||
using System;
|
using Discord;
|
||||||
|
using Discord.Commands;
|
||||||
|
using NadekoBot.Classes.Permissions;
|
||||||
|
using NadekoBot.Commands;
|
||||||
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Discord;
|
|
||||||
using Discord.Commands;
|
|
||||||
using NadekoBot.Classes.Permissions;
|
|
||||||
using NadekoBot.Modules;
|
|
||||||
|
|
||||||
namespace NadekoBot.Commands {
|
namespace NadekoBot.Modules.Administration.Commands
|
||||||
class CrossServerTextChannel : DiscordCommand {
|
{
|
||||||
public CrossServerTextChannel(DiscordModule module) : base(module) {
|
class CrossServerTextChannel : DiscordCommand
|
||||||
NadekoBot.Client.MessageReceived += async (s, e) => {
|
{
|
||||||
try {
|
public CrossServerTextChannel(DiscordModule module) : base(module)
|
||||||
|
{
|
||||||
|
NadekoBot.Client.MessageReceived += async (s, e) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
if (e.User.Id == NadekoBot.Client.CurrentUser.Id) return;
|
if (e.User.Id == NadekoBot.Client.CurrentUser.Id) return;
|
||||||
foreach (var subscriber in Subscribers) {
|
foreach (var subscriber in Subscribers)
|
||||||
|
{
|
||||||
var set = subscriber.Value;
|
var set = subscriber.Value;
|
||||||
if (!set.Contains(e.Channel))
|
if (!set.Contains(e.Channel))
|
||||||
continue;
|
continue;
|
||||||
foreach (var chan in set.Except(new[] { e.Channel })) {
|
foreach (var chan in set.Except(new[] { e.Channel }))
|
||||||
|
{
|
||||||
await chan.SendMessage(GetText(e.Server, e.Channel, e.User, e.Message));
|
await chan.SendMessage(GetText(e.Server, e.Channel, e.User, e.Message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
};
|
};
|
||||||
NadekoBot.Client.MessageUpdated += async (s, e) => {
|
NadekoBot.Client.MessageUpdated += async (s, e) =>
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
if (e.After?.User?.Id == null || e.After.User.Id == NadekoBot.Client.CurrentUser.Id) return;
|
if (e.After?.User?.Id == null || e.After.User.Id == NadekoBot.Client.CurrentUser.Id) return;
|
||||||
foreach (var subscriber in Subscribers) {
|
foreach (var subscriber in Subscribers)
|
||||||
|
{
|
||||||
var set = subscriber.Value;
|
var set = subscriber.Value;
|
||||||
if (!set.Contains(e.Channel))
|
if (!set.Contains(e.Channel))
|
||||||
continue;
|
continue;
|
||||||
foreach (var chan in set.Except(new[] { e.Channel })) {
|
foreach (var chan in set.Except(new[] { e.Channel }))
|
||||||
|
{
|
||||||
var msg = chan.Messages
|
var msg = chan.Messages
|
||||||
.FirstOrDefault(m =>
|
.FirstOrDefault(m =>
|
||||||
m.RawText == GetText(e.Server, e.Channel, e.User, e.Before));
|
m.RawText == GetText(e.Server, e.Channel, e.User, e.Before));
|
||||||
@ -39,7 +51,8 @@ namespace NadekoBot.Commands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,15 +61,18 @@ namespace NadekoBot.Commands {
|
|||||||
|
|
||||||
public static readonly ConcurrentDictionary<int, HashSet<Channel>> Subscribers = new ConcurrentDictionary<int, HashSet<Channel>>();
|
public static readonly ConcurrentDictionary<int, HashSet<Channel>> Subscribers = new ConcurrentDictionary<int, HashSet<Channel>>();
|
||||||
|
|
||||||
internal override void Init(CommandGroupBuilder cgb) {
|
internal override void Init(CommandGroupBuilder cgb)
|
||||||
|
{
|
||||||
cgb.CreateCommand(Module.Prefix + "scsc")
|
cgb.CreateCommand(Module.Prefix + "scsc")
|
||||||
.Description("Starts an instance of cross server channel. You will get a token as a DM" +
|
.Description("Starts an instance of cross server channel. You will get a token as a DM" +
|
||||||
"that other people will use to tune in to the same instance")
|
"that other people will use to tune in to the same instance")
|
||||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var token = new Random().Next();
|
var token = new Random().Next();
|
||||||
var set = new HashSet<Channel>();
|
var set = new HashSet<Channel>();
|
||||||
if (Subscribers.TryAdd(token, set)) {
|
if (Subscribers.TryAdd(token, set))
|
||||||
|
{
|
||||||
set.Add(e.Channel);
|
set.Add(e.Channel);
|
||||||
await e.User.SendMessage("This is your CSC token:" + token.ToString());
|
await e.User.SendMessage("This is your CSC token:" + token.ToString());
|
||||||
}
|
}
|
||||||
@ -66,7 +82,8 @@ namespace NadekoBot.Commands {
|
|||||||
.Description("Joins current channel to an instance of cross server channel using the token.")
|
.Description("Joins current channel to an instance of cross server channel using the token.")
|
||||||
.Parameter("token")
|
.Parameter("token")
|
||||||
.AddCheck(SimpleCheckers.ManageServer())
|
.AddCheck(SimpleCheckers.ManageServer())
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
int token;
|
int token;
|
||||||
if (!int.TryParse(e.GetArg("token"), out token))
|
if (!int.TryParse(e.GetArg("token"), out token))
|
||||||
return;
|
return;
|
||||||
@ -80,8 +97,10 @@ namespace NadekoBot.Commands {
|
|||||||
cgb.CreateCommand(Module.Prefix + "lcsc")
|
cgb.CreateCommand(Module.Prefix + "lcsc")
|
||||||
.Description("Leaves Cross server channel instance from this channel")
|
.Description("Leaves Cross server channel instance from this channel")
|
||||||
.AddCheck(SimpleCheckers.ManageServer())
|
.AddCheck(SimpleCheckers.ManageServer())
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
foreach (var subscriber in Subscribers) {
|
{
|
||||||
|
foreach (var subscriber in Subscribers)
|
||||||
|
{
|
||||||
subscriber.Value.Remove(e.Channel);
|
subscriber.Value.Remove(e.Channel);
|
||||||
}
|
}
|
||||||
await e.Channel.SendMessage(":ok:");
|
await e.Channel.SendMessage(":ok:");
|
@ -2,13 +2,13 @@
|
|||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
using NadekoBot.Classes;
|
using NadekoBot.Classes;
|
||||||
using NadekoBot.Classes.Permissions;
|
using NadekoBot.Classes.Permissions;
|
||||||
using NadekoBot.Modules;
|
using NadekoBot.Commands;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace NadekoBot.Commands
|
namespace NadekoBot.Modules.Administration.Commands
|
||||||
{
|
{
|
||||||
internal class LogCommand : DiscordCommand
|
internal class LogCommand : DiscordCommand
|
||||||
{
|
{
|
@ -1,15 +1,18 @@
|
|||||||
using System;
|
using Discord;
|
||||||
using System.Timers;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using Discord;
|
|
||||||
using NadekoBot.Classes.Permissions;
|
|
||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
using NadekoBot.Modules;
|
using NadekoBot.Classes.Permissions;
|
||||||
|
using NadekoBot.Commands;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Timers;
|
||||||
|
|
||||||
namespace NadekoBot.Commands {
|
namespace NadekoBot.Modules.Administration.Commands
|
||||||
class MessageRepeater : DiscordCommand {
|
{
|
||||||
|
class MessageRepeater : DiscordCommand
|
||||||
|
{
|
||||||
private readonly ConcurrentDictionary<Server, Repeater> repeaters = new ConcurrentDictionary<Server, Repeater>();
|
private readonly ConcurrentDictionary<Server, Repeater> repeaters = new ConcurrentDictionary<Server, Repeater>();
|
||||||
private class Repeater {
|
private class Repeater
|
||||||
|
{
|
||||||
[Newtonsoft.Json.JsonIgnore]
|
[Newtonsoft.Json.JsonIgnore]
|
||||||
public Timer MessageTimer { get; set; }
|
public Timer MessageTimer { get; set; }
|
||||||
[Newtonsoft.Json.JsonIgnore]
|
[Newtonsoft.Json.JsonIgnore]
|
||||||
@ -20,21 +23,27 @@ namespace NadekoBot.Commands {
|
|||||||
public string RepeatingMessage { get; set; }
|
public string RepeatingMessage { get; set; }
|
||||||
public int Interval { get; set; }
|
public int Interval { get; set; }
|
||||||
|
|
||||||
public Repeater Start() {
|
public Repeater Start()
|
||||||
|
{
|
||||||
MessageTimer = new Timer { Interval = Interval };
|
MessageTimer = new Timer { Interval = Interval };
|
||||||
MessageTimer.Elapsed += async (s, e) => {
|
MessageTimer.Elapsed += async (s, e) =>
|
||||||
|
{
|
||||||
var ch = RepeatingChannel;
|
var ch = RepeatingChannel;
|
||||||
var msg = RepeatingMessage;
|
var msg = RepeatingMessage;
|
||||||
if (ch != null && !string.IsNullOrWhiteSpace(msg)) {
|
if (ch != null && !string.IsNullOrWhiteSpace(msg))
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
await ch.SendMessage(msg);
|
await ch.SendMessage(msg);
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal override void Init(CommandGroupBuilder cgb) {
|
internal override void Init(CommandGroupBuilder cgb)
|
||||||
|
{
|
||||||
|
|
||||||
cgb.CreateCommand(Module.Prefix + "repeat")
|
cgb.CreateCommand(Module.Prefix + "repeat")
|
||||||
.Description("Repeat a message every X minutes. If no parameters are specified, " +
|
.Description("Repeat a message every X minutes. If no parameters are specified, " +
|
||||||
@ -42,12 +51,14 @@ namespace NadekoBot.Commands {
|
|||||||
.Parameter("minutes", ParameterType.Optional)
|
.Parameter("minutes", ParameterType.Optional)
|
||||||
.Parameter("msg", ParameterType.Unparsed)
|
.Parameter("msg", ParameterType.Unparsed)
|
||||||
.AddCheck(SimpleCheckers.ManageMessages())
|
.AddCheck(SimpleCheckers.ManageMessages())
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var minutesStr = e.GetArg("minutes");
|
var minutesStr = e.GetArg("minutes");
|
||||||
var msg = e.GetArg("msg");
|
var msg = e.GetArg("msg");
|
||||||
|
|
||||||
// if both null, disable
|
// if both null, disable
|
||||||
if (string.IsNullOrWhiteSpace(msg) && string.IsNullOrWhiteSpace(minutesStr)) {
|
if (string.IsNullOrWhiteSpace(msg) && string.IsNullOrWhiteSpace(minutesStr))
|
||||||
|
{
|
||||||
await e.Channel.SendMessage("Repeating disabled");
|
await e.Channel.SendMessage("Repeating disabled");
|
||||||
Repeater rep;
|
Repeater rep;
|
||||||
if (repeaters.TryGetValue(e.Server, out rep))
|
if (repeaters.TryGetValue(e.Server, out rep))
|
||||||
@ -55,14 +66,16 @@ namespace NadekoBot.Commands {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int minutes;
|
int minutes;
|
||||||
if (!int.TryParse(minutesStr, out minutes) || minutes < 1 || minutes > 720) {
|
if (!int.TryParse(minutesStr, out minutes) || minutes < 1 || minutes > 720)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage("Invalid value");
|
await e.Channel.SendMessage("Invalid value");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var repeater = repeaters.GetOrAdd(
|
var repeater = repeaters.GetOrAdd(
|
||||||
e.Server,
|
e.Server,
|
||||||
s => new Repeater {
|
s => new Repeater
|
||||||
|
{
|
||||||
Interval = minutes * 60 * 1000,
|
Interval = minutes * 60 * 1000,
|
||||||
RepeatingChannel = e.Channel,
|
RepeatingChannel = e.Channel,
|
||||||
RepeatingChannelId = e.Channel.Id,
|
RepeatingChannelId = e.Channel.Id,
|
||||||
@ -82,6 +95,6 @@ namespace NadekoBot.Commands {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessageRepeater(DiscordModule module) : base(module) {}
|
public MessageRepeater(DiscordModule module) : base(module) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,15 +1,17 @@
|
|||||||
using System;
|
using Discord.Commands;
|
||||||
|
using NadekoBot.Classes.JSONModels;
|
||||||
|
using NadekoBot.Commands;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Discord.Commands;
|
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
using NadekoBot.Classes.JSONModels;
|
|
||||||
using NadekoBot.Modules;
|
|
||||||
|
|
||||||
namespace NadekoBot.Commands {
|
namespace NadekoBot.Modules.Administration.Commands
|
||||||
internal class PlayingRotate : DiscordCommand {
|
{
|
||||||
|
internal class PlayingRotate : DiscordCommand
|
||||||
|
{
|
||||||
private static readonly Timer timer = new Timer(12000);
|
private static readonly Timer timer = new Timer(12000);
|
||||||
|
|
||||||
public static Dictionary<string, Func<string>> PlayingPlaceholders { get; } =
|
public static Dictionary<string, Func<string>> PlayingPlaceholders { get; } =
|
||||||
@ -34,16 +36,21 @@ namespace NadekoBot.Commands {
|
|||||||
|
|
||||||
private readonly object playingPlaceholderLock = new object();
|
private readonly object playingPlaceholderLock = new object();
|
||||||
|
|
||||||
public PlayingRotate(DiscordModule module) : base(module) {
|
public PlayingRotate(DiscordModule module) : base(module)
|
||||||
|
{
|
||||||
var i = -1;
|
var i = -1;
|
||||||
timer.Elapsed += (s, e) => {
|
timer.Elapsed += (s, e) =>
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
i++;
|
i++;
|
||||||
var status = "";
|
var status = "";
|
||||||
lock (playingPlaceholderLock) {
|
lock (playingPlaceholderLock)
|
||||||
|
{
|
||||||
if (PlayingPlaceholders.Count == 0)
|
if (PlayingPlaceholders.Count == 0)
|
||||||
return;
|
return;
|
||||||
if (i >= PlayingPlaceholders.Count) {
|
if (i >= PlayingPlaceholders.Count)
|
||||||
|
{
|
||||||
i = -1;
|
i = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -54,14 +61,17 @@ namespace NadekoBot.Commands {
|
|||||||
if (string.IsNullOrWhiteSpace(status))
|
if (string.IsNullOrWhiteSpace(status))
|
||||||
return;
|
return;
|
||||||
Task.Run(() => { NadekoBot.Client.SetGame(status); });
|
Task.Run(() => { NadekoBot.Client.SetGame(status); });
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
};
|
};
|
||||||
|
|
||||||
timer.Enabled = NadekoBot.Config.IsRotatingStatus;
|
timer.Enabled = NadekoBot.Config.IsRotatingStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Func<CommandEventArgs, Task> DoFunc() => async e => {
|
public Func<CommandEventArgs, Task> DoFunc() => async e =>
|
||||||
lock (playingPlaceholderLock) {
|
{
|
||||||
|
lock (playingPlaceholderLock)
|
||||||
|
{
|
||||||
if (timer.Enabled)
|
if (timer.Enabled)
|
||||||
timer.Stop();
|
timer.Stop();
|
||||||
else
|
else
|
||||||
@ -72,7 +82,8 @@ namespace NadekoBot.Commands {
|
|||||||
await e.Channel.SendMessage($"❗`Rotating playing status has been {(timer.Enabled ? "enabled" : "disabled")}.`");
|
await e.Channel.SendMessage($"❗`Rotating playing status has been {(timer.Enabled ? "enabled" : "disabled")}.`");
|
||||||
};
|
};
|
||||||
|
|
||||||
internal override void Init(CommandGroupBuilder cgb) {
|
internal override void Init(CommandGroupBuilder cgb)
|
||||||
|
{
|
||||||
cgb.CreateCommand(Module.Prefix + "rotateplaying")
|
cgb.CreateCommand(Module.Prefix + "rotateplaying")
|
||||||
.Alias(Module.Prefix + "ropl")
|
.Alias(Module.Prefix + "ropl")
|
||||||
.Description("Toggles rotation of playing status of the dynamic strings you specified earlier.")
|
.Description("Toggles rotation of playing status of the dynamic strings you specified earlier.")
|
||||||
@ -85,11 +96,13 @@ namespace NadekoBot.Commands {
|
|||||||
"Supported placeholders: " + string.Join(", ", PlayingPlaceholders.Keys))
|
"Supported placeholders: " + string.Join(", ", PlayingPlaceholders.Keys))
|
||||||
.Parameter("text", ParameterType.Unparsed)
|
.Parameter("text", ParameterType.Unparsed)
|
||||||
.AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly())
|
.AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly())
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var arg = e.GetArg("text");
|
var arg = e.GetArg("text");
|
||||||
if (string.IsNullOrWhiteSpace(arg))
|
if (string.IsNullOrWhiteSpace(arg))
|
||||||
return;
|
return;
|
||||||
lock (playingPlaceholderLock) {
|
lock (playingPlaceholderLock)
|
||||||
|
{
|
||||||
NadekoBot.Config.RotatingStatuses.Add(arg);
|
NadekoBot.Config.RotatingStatuses.Add(arg);
|
||||||
ConfigHandler.SaveConfig();
|
ConfigHandler.SaveConfig();
|
||||||
}
|
}
|
||||||
@ -100,12 +113,14 @@ namespace NadekoBot.Commands {
|
|||||||
.Alias(Module.Prefix + "lipl")
|
.Alias(Module.Prefix + "lipl")
|
||||||
.Description("Lists all playing statuses with their corresponding number.")
|
.Description("Lists all playing statuses with their corresponding number.")
|
||||||
.AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly())
|
.AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly())
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
if (NadekoBot.Config.RotatingStatuses.Count == 0)
|
if (NadekoBot.Config.RotatingStatuses.Count == 0)
|
||||||
await e.Channel.SendMessage("`There are no playing strings. " +
|
await e.Channel.SendMessage("`There are no playing strings. " +
|
||||||
"Add some with .addplaying [text] command.`");
|
"Add some with .addplaying [text] command.`");
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
for (var i = 0; i < NadekoBot.Config.RotatingStatuses.Count; i++) {
|
for (var i = 0; i < NadekoBot.Config.RotatingStatuses.Count; i++)
|
||||||
|
{
|
||||||
sb.AppendLine($"`{i + 1}.` {NadekoBot.Config.RotatingStatuses[i]}");
|
sb.AppendLine($"`{i + 1}.` {NadekoBot.Config.RotatingStatuses[i]}");
|
||||||
}
|
}
|
||||||
await e.Channel.SendMessage(sb.ToString());
|
await e.Channel.SendMessage(sb.ToString());
|
||||||
@ -116,11 +131,13 @@ namespace NadekoBot.Commands {
|
|||||||
.Description("Removes a playing string on a given number.")
|
.Description("Removes a playing string on a given number.")
|
||||||
.Parameter("number", ParameterType.Required)
|
.Parameter("number", ParameterType.Required)
|
||||||
.AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly())
|
.AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly())
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var arg = e.GetArg("number");
|
var arg = e.GetArg("number");
|
||||||
int num;
|
int num;
|
||||||
string str;
|
string str;
|
||||||
lock (playingPlaceholderLock) {
|
lock (playingPlaceholderLock)
|
||||||
|
{
|
||||||
if (!int.TryParse(arg.Trim(), out num) || num <= 0 || num > NadekoBot.Config.RotatingStatuses.Count)
|
if (!int.TryParse(arg.Trim(), out num) || num <= 0 || num > NadekoBot.Config.RotatingStatuses.Count)
|
||||||
return;
|
return;
|
||||||
str = NadekoBot.Config.RotatingStatuses[num - 1];
|
str = NadekoBot.Config.RotatingStatuses[num - 1];
|
@ -1,28 +1,36 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
using NadekoBot.Classes.Permissions;
|
using NadekoBot.Classes.Permissions;
|
||||||
using NadekoBot.Modules;
|
using NadekoBot.Commands;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
namespace NadekoBot.Commands {
|
namespace NadekoBot.Modules.Administration.Commands
|
||||||
internal class RatelimitCommand : DiscordCommand {
|
{
|
||||||
|
internal class RatelimitCommand : DiscordCommand
|
||||||
|
{
|
||||||
|
|
||||||
public static ConcurrentDictionary<ulong, ConcurrentDictionary<ulong, DateTime>> RatelimitingChannels = new ConcurrentDictionary<ulong, ConcurrentDictionary<ulong, DateTime>>();
|
public static ConcurrentDictionary<ulong, ConcurrentDictionary<ulong, DateTime>> RatelimitingChannels = new ConcurrentDictionary<ulong, ConcurrentDictionary<ulong, DateTime>>();
|
||||||
|
|
||||||
private static readonly TimeSpan ratelimitTime = new TimeSpan(0, 0, 0, 5);
|
private static readonly TimeSpan ratelimitTime = new TimeSpan(0, 0, 0, 5);
|
||||||
|
|
||||||
public RatelimitCommand(DiscordModule module) : base(module) {
|
public RatelimitCommand(DiscordModule module) : base(module)
|
||||||
NadekoBot.Client.MessageReceived += async (s, e) => {
|
{
|
||||||
|
NadekoBot.Client.MessageReceived += async (s, e) =>
|
||||||
|
{
|
||||||
if (e.Channel.IsPrivate || e.User.Id == NadekoBot.Client.CurrentUser.Id)
|
if (e.Channel.IsPrivate || e.User.Id == NadekoBot.Client.CurrentUser.Id)
|
||||||
return;
|
return;
|
||||||
ConcurrentDictionary<ulong, DateTime> userTimePair;
|
ConcurrentDictionary<ulong, DateTime> userTimePair;
|
||||||
if (!RatelimitingChannels.TryGetValue(e.Channel.Id, out userTimePair)) return;
|
if (!RatelimitingChannels.TryGetValue(e.Channel.Id, out userTimePair)) return;
|
||||||
DateTime lastMessageTime;
|
DateTime lastMessageTime;
|
||||||
if (userTimePair.TryGetValue(e.User.Id, out lastMessageTime)) {
|
if (userTimePair.TryGetValue(e.User.Id, out lastMessageTime))
|
||||||
if (DateTime.Now - lastMessageTime < ratelimitTime) {
|
{
|
||||||
try {
|
if (DateTime.Now - lastMessageTime < ratelimitTime)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
await e.Message.Delete();
|
await e.Message.Delete();
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -30,23 +38,27 @@ namespace NadekoBot.Commands {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override void Init(CommandGroupBuilder cgb) {
|
internal override void Init(CommandGroupBuilder cgb)
|
||||||
|
{
|
||||||
cgb.CreateCommand(Module.Prefix + "slowmode")
|
cgb.CreateCommand(Module.Prefix + "slowmode")
|
||||||
.Description("Toggles slow mode. When ON, users will be able to send only 1 message every 5 seconds.")
|
.Description("Toggles slow mode. When ON, users will be able to send only 1 message every 5 seconds.")
|
||||||
.Parameter("minutes", ParameterType.Optional)
|
.Parameter("minutes", ParameterType.Optional)
|
||||||
.AddCheck(SimpleCheckers.ManageMessages())
|
.AddCheck(SimpleCheckers.ManageMessages())
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
//var minutesStr = e.GetArg("minutes");
|
//var minutesStr = e.GetArg("minutes");
|
||||||
//if (string.IsNullOrWhiteSpace(minutesStr)) {
|
//if (string.IsNullOrWhiteSpace(minutesStr)) {
|
||||||
// RatelimitingChannels.Remove(e.Channel.Id);
|
// RatelimitingChannels.Remove(e.Channel.Id);
|
||||||
// return;
|
// return;
|
||||||
//}
|
//}
|
||||||
ConcurrentDictionary<ulong, DateTime> throwaway;
|
ConcurrentDictionary<ulong, DateTime> throwaway;
|
||||||
if (RatelimitingChannels.TryRemove(e.Channel.Id, out throwaway)) {
|
if (RatelimitingChannels.TryRemove(e.Channel.Id, out throwaway))
|
||||||
|
{
|
||||||
await e.Channel.SendMessage("Slow mode disabled.");
|
await e.Channel.SendMessage("Slow mode disabled.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (RatelimitingChannels.TryAdd(e.Channel.Id, new ConcurrentDictionary<ulong, DateTime>())) {
|
if (RatelimitingChannels.TryAdd(e.Channel.Id, new ConcurrentDictionary<ulong, DateTime>()))
|
||||||
|
{
|
||||||
await e.Channel.SendMessage("Slow mode initiated. " +
|
await e.Channel.SendMessage("Slow mode initiated. " +
|
||||||
"Users can't send more than 1 message every 5 seconds.");
|
"Users can't send more than 1 message every 5 seconds.");
|
||||||
}
|
}
|
166
NadekoBot/Modules/Administration/Commands/Remind.cs
Normal file
166
NadekoBot/Modules/Administration/Commands/Remind.cs
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
using Discord;
|
||||||
|
using Discord.Commands;
|
||||||
|
using NadekoBot.Classes;
|
||||||
|
using NadekoBot.Classes._DataModels;
|
||||||
|
using NadekoBot.Commands;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Timers;
|
||||||
|
|
||||||
|
namespace NadekoBot.Modules.Administration.Commands
|
||||||
|
{
|
||||||
|
class Remind : DiscordCommand
|
||||||
|
{
|
||||||
|
|
||||||
|
Regex regex = new Regex(@"^(?:(?<months>\d)mo)?(?:(?<weeks>\d)w)?(?:(?<days>\d{1,2})d)?(?:(?<hours>\d{1,2})h)?(?:(?<minutes>\d{1,2})m)?$",
|
||||||
|
RegexOptions.Compiled | RegexOptions.Multiline);
|
||||||
|
|
||||||
|
List<Timer> reminders = new List<Timer>();
|
||||||
|
|
||||||
|
public Remind(DiscordModule module) : base(module)
|
||||||
|
{
|
||||||
|
var remList = DbHandler.Instance.GetAllRows<Reminder>();
|
||||||
|
|
||||||
|
Console.WriteLine(string.Join("\n-", remList.Select(r => r.When.ToString())));
|
||||||
|
reminders = remList.Select(StartNewReminder).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Timer StartNewReminder(Reminder r)
|
||||||
|
{
|
||||||
|
var now = DateTime.Now;
|
||||||
|
var twoMins = new TimeSpan(0, 2, 0);
|
||||||
|
TimeSpan time = (r.When - now) < twoMins
|
||||||
|
? twoMins //if the time is less than 2 minutes,
|
||||||
|
: r.When - now; //it will send the message 2 minutes after start
|
||||||
|
//To account for high bot startup times
|
||||||
|
|
||||||
|
var t = new Timer(time.TotalMilliseconds);
|
||||||
|
t.Elapsed += async (s, e) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Channel ch;
|
||||||
|
if (r.IsPrivate)
|
||||||
|
{
|
||||||
|
ch = NadekoBot.Client.PrivateChannels.FirstOrDefault(c => (long)c.Id == r.ChannelId);
|
||||||
|
if (ch == null)
|
||||||
|
ch = await NadekoBot.Client.CreatePrivateChannel((ulong)r.ChannelId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ch = NadekoBot.Client.GetServer((ulong)r.ServerId)?.GetChannel((ulong)r.ChannelId);
|
||||||
|
|
||||||
|
if (ch == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await ch.SendMessage($"❗⏰**I've been told to remind you to '{r.Message}' now by <@{r.UserId}>.**⏰❗");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Timer error! {ex}");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DbHandler.Instance.Delete<Reminder>(r.Id);
|
||||||
|
t.Stop();
|
||||||
|
t.Dispose();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
t.Start();
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override void Init(CommandGroupBuilder cgb)
|
||||||
|
{
|
||||||
|
cgb.CreateCommand(Module.Prefix + "remind")
|
||||||
|
.Parameter("meorchannel", ParameterType.Required)
|
||||||
|
.Parameter("time", ParameterType.Required)
|
||||||
|
.Parameter("message", ParameterType.Unparsed)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
var meorchStr = e.GetArg("meorchannel").ToUpperInvariant();
|
||||||
|
Channel ch;
|
||||||
|
bool isPrivate = false;
|
||||||
|
if (meorchStr == "ME")
|
||||||
|
{
|
||||||
|
isPrivate = true;
|
||||||
|
ch = await e.User.CreatePMChannel();
|
||||||
|
}
|
||||||
|
else if (meorchStr == "HERE")
|
||||||
|
{
|
||||||
|
ch = e.Channel;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ch = e.Server.FindChannels(meorchStr).FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == null)
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage($"{e.User.Mention} Something went wrong (channel cannot be found) ;(");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var timeStr = e.GetArg("time");
|
||||||
|
|
||||||
|
var m = regex.Match(timeStr);
|
||||||
|
|
||||||
|
if (m.Length == 0)
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage("Not a valid time format blablabla");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string output = "";
|
||||||
|
var namesAndValues = new Dictionary<string, int>();
|
||||||
|
|
||||||
|
foreach (var groupName in regex.GetGroupNames())
|
||||||
|
{
|
||||||
|
if (groupName == "0") continue;
|
||||||
|
int value = 0;
|
||||||
|
int.TryParse(m.Groups[groupName].Value, out value);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(m.Groups[groupName].Value))
|
||||||
|
{
|
||||||
|
namesAndValues[groupName] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (value < 1 ||
|
||||||
|
(groupName == "months" && value > 1) ||
|
||||||
|
(groupName == "weeks" && value > 4) ||
|
||||||
|
(groupName == "days" && value >= 7) ||
|
||||||
|
(groupName == "hours" && value > 23) ||
|
||||||
|
(groupName == "minutes" && value > 59))
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage($"Invalid {groupName} value.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
namesAndValues[groupName] = value;
|
||||||
|
output += m.Groups[groupName].Value + " " + groupName + " ";
|
||||||
|
}
|
||||||
|
var time = DateTime.Now + new TimeSpan(30 * namesAndValues["months"] +
|
||||||
|
7 * namesAndValues["weeks"] +
|
||||||
|
namesAndValues["days"],
|
||||||
|
namesAndValues["hours"],
|
||||||
|
namesAndValues["minutes"],
|
||||||
|
0);
|
||||||
|
|
||||||
|
var rem = new Reminder
|
||||||
|
{
|
||||||
|
ChannelId = (long)ch.Id,
|
||||||
|
IsPrivate = isPrivate,
|
||||||
|
When = time,
|
||||||
|
Message = e.GetArg("message"),
|
||||||
|
UserId = (long)e.User.Id,
|
||||||
|
ServerId = (long)e.Server.Id
|
||||||
|
};
|
||||||
|
DbHandler.Instance.InsertData(rem);
|
||||||
|
|
||||||
|
reminders.Add(StartNewReminder(rem));
|
||||||
|
|
||||||
|
await e.Channel.SendMessage($"⏰ I will remind \"{ch.Name}\" to \"{e.GetArg("message").ToString()}\" in {output}. ({time:d.M.yyyy.} at {time:HH:m})");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,29 +1,35 @@
|
|||||||
using System.Collections.Generic;
|
using Discord.Commands;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Discord.Commands;
|
|
||||||
using NadekoBot.Classes;
|
using NadekoBot.Classes;
|
||||||
using NadekoBot.Classes.Permissions;
|
using NadekoBot.Classes.Permissions;
|
||||||
using NadekoBot.Modules;
|
using NadekoBot.Commands;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace NadekoBot.Commands {
|
namespace NadekoBot.Modules.Administration.Commands
|
||||||
internal class SelfAssignedRolesCommand : DiscordCommand {
|
{
|
||||||
|
internal class SelfAssignedRolesCommand : DiscordCommand
|
||||||
|
{
|
||||||
public SelfAssignedRolesCommand(DiscordModule module) : base(module) { }
|
public SelfAssignedRolesCommand(DiscordModule module) : base(module) { }
|
||||||
internal override void Init(CommandGroupBuilder cgb) {
|
internal override void Init(CommandGroupBuilder cgb)
|
||||||
|
{
|
||||||
cgb.CreateCommand(".asar")
|
cgb.CreateCommand(".asar")
|
||||||
.Description("Adds a role, or list of roles separated by whitespace" +
|
.Description("Adds a role, or list of roles separated by whitespace" +
|
||||||
"(use quotations for multiword roles) to the list of self-assignable roles.\n**Usage**: .asar Gamer")
|
"(use quotations for multiword roles) to the list of self-assignable roles.\n**Usage**: .asar Gamer")
|
||||||
.Parameter("roles", ParameterType.Multiple)
|
.Parameter("roles", ParameterType.Multiple)
|
||||||
.AddCheck(SimpleCheckers.CanManageRoles)
|
.AddCheck(SimpleCheckers.CanManageRoles)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||||
var msg = new StringBuilder();
|
var msg = new StringBuilder();
|
||||||
foreach (var arg in e.Args) {
|
foreach (var arg in e.Args)
|
||||||
|
{
|
||||||
var role = e.Server.FindRoles(arg.Trim()).FirstOrDefault();
|
var role = e.Server.FindRoles(arg.Trim()).FirstOrDefault();
|
||||||
if (role == null)
|
if (role == null)
|
||||||
msg.AppendLine($":anger:Role **{arg}** not found.");
|
msg.AppendLine($":anger:Role **{arg}** not found.");
|
||||||
else {
|
else {
|
||||||
if (config.ListOfSelfAssignableRoles.Contains(role.Id)) {
|
if (config.ListOfSelfAssignableRoles.Contains(role.Id))
|
||||||
|
{
|
||||||
msg.AppendLine($":anger:Role **{role.Name}** is already in the list.");
|
msg.AppendLine($":anger:Role **{role.Name}** is already in the list.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -38,17 +44,20 @@ namespace NadekoBot.Commands {
|
|||||||
.Description("Removes a specified role from the list of self-assignable roles.")
|
.Description("Removes a specified role from the list of self-assignable roles.")
|
||||||
.Parameter("role", ParameterType.Unparsed)
|
.Parameter("role", ParameterType.Unparsed)
|
||||||
.AddCheck(SimpleCheckers.CanManageRoles)
|
.AddCheck(SimpleCheckers.CanManageRoles)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var roleName = e.GetArg("role")?.Trim();
|
var roleName = e.GetArg("role")?.Trim();
|
||||||
if (string.IsNullOrWhiteSpace(roleName))
|
if (string.IsNullOrWhiteSpace(roleName))
|
||||||
return;
|
return;
|
||||||
var role = e.Server.FindRoles(roleName).FirstOrDefault();
|
var role = e.Server.FindRoles(roleName).FirstOrDefault();
|
||||||
if (role == null) {
|
if (role == null)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage(":anger:That role does not exist.");
|
await e.Channel.SendMessage(":anger:That role does not exist.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||||
if (!config.ListOfSelfAssignableRoles.Contains(role.Id)) {
|
if (!config.ListOfSelfAssignableRoles.Contains(role.Id))
|
||||||
|
{
|
||||||
await e.Channel.SendMessage(":anger:That role is not self-assignable.");
|
await e.Channel.SendMessage(":anger:That role is not self-assignable.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -59,20 +68,25 @@ namespace NadekoBot.Commands {
|
|||||||
cgb.CreateCommand(".lsar")
|
cgb.CreateCommand(".lsar")
|
||||||
.Description("Lits all self-assignable roles.")
|
.Description("Lits all self-assignable roles.")
|
||||||
.Parameter("roles", ParameterType.Multiple)
|
.Parameter("roles", ParameterType.Multiple)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||||
var msg = new StringBuilder($"There are `{config.ListOfSelfAssignableRoles.Count}` self assignable roles:\n");
|
var msg = new StringBuilder($"There are `{config.ListOfSelfAssignableRoles.Count}` self assignable roles:\n");
|
||||||
var toRemove = new HashSet<ulong>();
|
var toRemove = new HashSet<ulong>();
|
||||||
foreach (var roleId in config.ListOfSelfAssignableRoles) {
|
foreach (var roleId in config.ListOfSelfAssignableRoles)
|
||||||
|
{
|
||||||
var role = e.Server.GetRole(roleId);
|
var role = e.Server.GetRole(roleId);
|
||||||
if (role == null) {
|
if (role == null)
|
||||||
|
{
|
||||||
msg.Append($"`{roleId} not found. Cleaned up.`, ");
|
msg.Append($"`{roleId} not found. Cleaned up.`, ");
|
||||||
toRemove.Add(roleId);
|
toRemove.Add(roleId);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
msg.Append($"**{role.Name}**, ");
|
msg.Append($"**{role.Name}**, ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (var id in toRemove) {
|
foreach (var id in toRemove)
|
||||||
|
{
|
||||||
config.ListOfSelfAssignableRoles.Remove(id);
|
config.ListOfSelfAssignableRoles.Remove(id);
|
||||||
}
|
}
|
||||||
await e.Channel.SendMessage(msg.ToString());
|
await e.Channel.SendMessage(msg.ToString());
|
||||||
@ -83,21 +97,25 @@ namespace NadekoBot.Commands {
|
|||||||
"Role must be on a list of self-assignable roles." +
|
"Role must be on a list of self-assignable roles." +
|
||||||
"\n**Usage**: .iam Gamer")
|
"\n**Usage**: .iam Gamer")
|
||||||
.Parameter("role", ParameterType.Unparsed)
|
.Parameter("role", ParameterType.Unparsed)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var roleName = e.GetArg("role")?.Trim();
|
var roleName = e.GetArg("role")?.Trim();
|
||||||
if (string.IsNullOrWhiteSpace(roleName))
|
if (string.IsNullOrWhiteSpace(roleName))
|
||||||
return;
|
return;
|
||||||
var role = e.Server.FindRoles(roleName).FirstOrDefault();
|
var role = e.Server.FindRoles(roleName).FirstOrDefault();
|
||||||
if (role == null) {
|
if (role == null)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage(":anger:That role does not exist.");
|
await e.Channel.SendMessage(":anger:That role does not exist.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||||
if (!config.ListOfSelfAssignableRoles.Contains(role.Id)) {
|
if (!config.ListOfSelfAssignableRoles.Contains(role.Id))
|
||||||
|
{
|
||||||
await e.Channel.SendMessage(":anger:That role is not self-assignable.");
|
await e.Channel.SendMessage(":anger:That role is not self-assignable.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e.User.HasRole(role)) {
|
if (e.User.HasRole(role))
|
||||||
|
{
|
||||||
await e.Channel.SendMessage($":anger:You already have {role.Name} role.");
|
await e.Channel.SendMessage($":anger:You already have {role.Name} role.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -111,21 +129,25 @@ namespace NadekoBot.Commands {
|
|||||||
"Role must be on a list of self-assignable roles." +
|
"Role must be on a list of self-assignable roles." +
|
||||||
"\n**Usage**: .iamn Gamer")
|
"\n**Usage**: .iamn Gamer")
|
||||||
.Parameter("role", ParameterType.Unparsed)
|
.Parameter("role", ParameterType.Unparsed)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var roleName = e.GetArg("role")?.Trim();
|
var roleName = e.GetArg("role")?.Trim();
|
||||||
if (string.IsNullOrWhiteSpace(roleName))
|
if (string.IsNullOrWhiteSpace(roleName))
|
||||||
return;
|
return;
|
||||||
var role = e.Server.FindRoles(roleName).FirstOrDefault();
|
var role = e.Server.FindRoles(roleName).FirstOrDefault();
|
||||||
if (role == null) {
|
if (role == null)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage(":anger:That role does not exist.");
|
await e.Channel.SendMessage(":anger:That role does not exist.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||||
if (!config.ListOfSelfAssignableRoles.Contains(role.Id)) {
|
if (!config.ListOfSelfAssignableRoles.Contains(role.Id))
|
||||||
|
{
|
||||||
await e.Channel.SendMessage(":anger:That role is not self-assignable.");
|
await e.Channel.SendMessage(":anger:That role is not self-assignable.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!e.User.HasRole(role)) {
|
if (!e.User.HasRole(role))
|
||||||
|
{
|
||||||
await e.Channel.SendMessage($":anger:You don't have {role.Name} role.");
|
await e.Channel.SendMessage($":anger:You don't have {role.Name} role.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
@ -1,12 +1,9 @@
|
|||||||
using System;
|
using Discord;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
using System.Collections.Concurrent;
|
using NadekoBot.Commands;
|
||||||
using NadekoBot.Extensions;
|
using NadekoBot.Extensions;
|
||||||
using Discord;
|
using System.Collections.Concurrent;
|
||||||
using NadekoBot.Modules;
|
using System.Linq;
|
||||||
|
|
||||||
/* Voltana's legacy
|
/* Voltana's legacy
|
||||||
public class AsyncLazy<T> : Lazy<Task<T>>
|
public class AsyncLazy<T> : Lazy<Task<T>>
|
||||||
@ -21,14 +18,17 @@ public class AsyncLazy<T> : Lazy<Task<T>>
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace NadekoBot.Commands {
|
namespace NadekoBot.Modules.Administration.Commands
|
||||||
internal class ServerGreetCommand : DiscordCommand {
|
{
|
||||||
|
internal class ServerGreetCommand : DiscordCommand
|
||||||
|
{
|
||||||
|
|
||||||
public static ConcurrentDictionary<ulong, AnnounceControls> AnnouncementsDictionary;
|
public static ConcurrentDictionary<ulong, AnnounceControls> AnnouncementsDictionary;
|
||||||
|
|
||||||
public static long Greeted = 0;
|
public static long Greeted = 0;
|
||||||
|
|
||||||
public ServerGreetCommand(DiscordModule module) : base(module) {
|
public ServerGreetCommand(DiscordModule module) : base(module)
|
||||||
|
{
|
||||||
AnnouncementsDictionary = new ConcurrentDictionary<ulong, AnnounceControls>();
|
AnnouncementsDictionary = new ConcurrentDictionary<ulong, AnnounceControls>();
|
||||||
|
|
||||||
NadekoBot.Client.UserJoined += UserJoined;
|
NadekoBot.Client.UserJoined += UserJoined;
|
||||||
@ -41,8 +41,10 @@ namespace NadekoBot.Commands {
|
|||||||
AnnouncementsDictionary.TryAdd((ulong)obj.ServerId, new AnnounceControls(obj));
|
AnnouncementsDictionary.TryAdd((ulong)obj.ServerId, new AnnounceControls(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void UserLeft(object sender, UserEventArgs e) {
|
private async void UserLeft(object sender, UserEventArgs e)
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id) ||
|
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id) ||
|
||||||
!AnnouncementsDictionary[e.Server.Id].Bye) return;
|
!AnnouncementsDictionary[e.Server.Id].Bye) return;
|
||||||
|
|
||||||
@ -52,9 +54,11 @@ namespace NadekoBot.Commands {
|
|||||||
if (string.IsNullOrEmpty(msg))
|
if (string.IsNullOrEmpty(msg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (controls.ByePM) {
|
if (controls.ByePM)
|
||||||
|
{
|
||||||
Greeted++;
|
Greeted++;
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
await e.User.SendMessage($"`Farewell Message From {e.Server?.Name}`\n" + msg);
|
await e.User.SendMessage($"`Farewell Message From {e.Server?.Name}`\n" + msg);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
@ -68,8 +72,10 @@ namespace NadekoBot.Commands {
|
|||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void UserJoined(object sender, Discord.UserEventArgs e) {
|
private async void UserJoined(object sender, Discord.UserEventArgs e)
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id) ||
|
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id) ||
|
||||||
!AnnouncementsDictionary[e.Server.Id].Greet) return;
|
!AnnouncementsDictionary[e.Server.Id].Greet) return;
|
||||||
|
|
||||||
@ -79,7 +85,8 @@ namespace NadekoBot.Commands {
|
|||||||
var msg = controls.GreetText.Replace("%user%", e.User.Mention).Trim();
|
var msg = controls.GreetText.Replace("%user%", e.User.Mention).Trim();
|
||||||
if (string.IsNullOrEmpty(msg))
|
if (string.IsNullOrEmpty(msg))
|
||||||
return;
|
return;
|
||||||
if (controls.GreetPM) {
|
if (controls.GreetPM)
|
||||||
|
{
|
||||||
Greeted++;
|
Greeted++;
|
||||||
await e.User.SendMessage($"`Welcome Message From {e.Server.Name}`\n" + msg);
|
await e.User.SendMessage($"`Welcome Message From {e.Server.Name}`\n" + msg);
|
||||||
}
|
}
|
||||||
@ -92,7 +99,8 @@ namespace NadekoBot.Commands {
|
|||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AnnounceControls {
|
public class AnnounceControls
|
||||||
|
{
|
||||||
private Classes._DataModels.Announcement _model { get; }
|
private Classes._DataModels.Announcement _model { get; }
|
||||||
|
|
||||||
public bool Greet {
|
public bool Greet {
|
||||||
@ -139,28 +147,36 @@ namespace NadekoBot.Commands {
|
|||||||
set { _model.ServerId = (long)value; }
|
set { _model.ServerId = (long)value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public AnnounceControls(Classes._DataModels.Announcement model) {
|
public AnnounceControls(Classes._DataModels.Announcement model)
|
||||||
|
{
|
||||||
this._model = model;
|
this._model = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AnnounceControls(ulong serverId) {
|
public AnnounceControls(ulong serverId)
|
||||||
|
{
|
||||||
this._model = new Classes._DataModels.Announcement();
|
this._model = new Classes._DataModels.Announcement();
|
||||||
ServerId = serverId;
|
ServerId = serverId;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool ToggleBye(ulong id) {
|
internal bool ToggleBye(ulong id)
|
||||||
if (Bye) {
|
{
|
||||||
|
if (Bye)
|
||||||
|
{
|
||||||
return Bye = false;
|
return Bye = false;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
ByeChannel = id;
|
ByeChannel = id;
|
||||||
return Bye = true;
|
return Bye = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool ToggleGreet(ulong id) {
|
internal bool ToggleGreet(ulong id)
|
||||||
if (Greet) {
|
{
|
||||||
|
if (Greet)
|
||||||
|
{
|
||||||
return Greet = false;
|
return Greet = false;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
GreetChannel = id;
|
GreetChannel = id;
|
||||||
return Greet = true;
|
return Greet = true;
|
||||||
}
|
}
|
||||||
@ -168,16 +184,19 @@ namespace NadekoBot.Commands {
|
|||||||
internal bool ToggleGreetPM() => GreetPM = !GreetPM;
|
internal bool ToggleGreetPM() => GreetPM = !GreetPM;
|
||||||
internal bool ToggleByePM() => ByePM = !ByePM;
|
internal bool ToggleByePM() => ByePM = !ByePM;
|
||||||
|
|
||||||
private void Save() {
|
private void Save()
|
||||||
|
{
|
||||||
Classes.DbHandler.Instance.Save(_model);
|
Classes.DbHandler.Instance.Save(_model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override void Init(CommandGroupBuilder cgb) {
|
internal override void Init(CommandGroupBuilder cgb)
|
||||||
|
{
|
||||||
|
|
||||||
cgb.CreateCommand(Module.Prefix + "greet")
|
cgb.CreateCommand(Module.Prefix + "greet")
|
||||||
.Description("Enables or Disables anouncements on the current channel when someone joins the server.")
|
.Description("Enables or Disables anouncements on the current channel when someone joins the server.")
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
if (!e.User.ServerPermissions.ManageServer) return;
|
if (!e.User.ServerPermissions.ManageServer) return;
|
||||||
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
|
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
|
||||||
AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
|
AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
|
||||||
@ -193,7 +212,8 @@ namespace NadekoBot.Commands {
|
|||||||
cgb.CreateCommand(Module.Prefix + "greetmsg")
|
cgb.CreateCommand(Module.Prefix + "greetmsg")
|
||||||
.Description("Sets a new announce message. Type %user% if you want to mention the new member.\n**Usage**: .greetmsg Welcome to the server, %user%.")
|
.Description("Sets a new announce message. Type %user% if you want to mention the new member.\n**Usage**: .greetmsg Welcome to the server, %user%.")
|
||||||
.Parameter("msg", ParameterType.Unparsed)
|
.Parameter("msg", ParameterType.Unparsed)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
if (!e.User.ServerPermissions.ManageServer) return;
|
if (!e.User.ServerPermissions.ManageServer) return;
|
||||||
if (e.GetArg("msg") == null) return;
|
if (e.GetArg("msg") == null) return;
|
||||||
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
|
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
|
||||||
@ -207,7 +227,8 @@ namespace NadekoBot.Commands {
|
|||||||
|
|
||||||
cgb.CreateCommand(Module.Prefix + "bye")
|
cgb.CreateCommand(Module.Prefix + "bye")
|
||||||
.Description("Enables or Disables anouncements on the current channel when someone leaves the server.")
|
.Description("Enables or Disables anouncements on the current channel when someone leaves the server.")
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
if (!e.User.ServerPermissions.ManageServer) return;
|
if (!e.User.ServerPermissions.ManageServer) return;
|
||||||
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
|
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
|
||||||
AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
|
AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
|
||||||
@ -223,7 +244,8 @@ namespace NadekoBot.Commands {
|
|||||||
cgb.CreateCommand(Module.Prefix + "byemsg")
|
cgb.CreateCommand(Module.Prefix + "byemsg")
|
||||||
.Description("Sets a new announce leave message. Type %user% if you want to mention the new member.\n**Usage**: .byemsg %user% has left the server.")
|
.Description("Sets a new announce leave message. Type %user% if you want to mention the new member.\n**Usage**: .byemsg %user% has left the server.")
|
||||||
.Parameter("msg", ParameterType.Unparsed)
|
.Parameter("msg", ParameterType.Unparsed)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
if (!e.User.ServerPermissions.ManageServer) return;
|
if (!e.User.ServerPermissions.ManageServer) return;
|
||||||
if (e.GetArg("msg") == null) return;
|
if (e.GetArg("msg") == null) return;
|
||||||
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
|
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
|
||||||
@ -237,7 +259,8 @@ namespace NadekoBot.Commands {
|
|||||||
|
|
||||||
cgb.CreateCommand(Module.Prefix + "byepm")
|
cgb.CreateCommand(Module.Prefix + "byepm")
|
||||||
.Description("Toggles whether the good bye messages will be sent in a PM or in the text channel.")
|
.Description("Toggles whether the good bye messages will be sent in a PM or in the text channel.")
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
if (!e.User.ServerPermissions.ManageServer) return;
|
if (!e.User.ServerPermissions.ManageServer) return;
|
||||||
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
|
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
|
||||||
AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
|
AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
|
||||||
@ -253,7 +276,8 @@ namespace NadekoBot.Commands {
|
|||||||
|
|
||||||
cgb.CreateCommand(Module.Prefix + "greetpm")
|
cgb.CreateCommand(Module.Prefix + "greetpm")
|
||||||
.Description("Toggles whether the greet messages will be sent in a PM or in the text channel.")
|
.Description("Toggles whether the greet messages will be sent in a PM or in the text channel.")
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
if (!e.User.ServerPermissions.ManageServer) return;
|
if (!e.User.ServerPermissions.ManageServer) return;
|
||||||
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
|
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
|
||||||
AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
|
AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
|
@ -1,34 +1,40 @@
|
|||||||
using System;
|
using Discord;
|
||||||
|
using Discord.Commands;
|
||||||
|
using NadekoBot.Commands;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Discord.Commands;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using Discord;
|
|
||||||
using NadekoBot.Modules;
|
|
||||||
|
|
||||||
namespace NadekoBot.Commands {
|
namespace NadekoBot.Modules.Administration.Commands
|
||||||
internal class VoiceNotificationCommand : DiscordCommand {
|
{
|
||||||
|
internal class VoiceNotificationCommand : DiscordCommand
|
||||||
|
{
|
||||||
|
|
||||||
//voicechannel/text channel
|
//voicechannel/text channel
|
||||||
private readonly ConcurrentDictionary<Channel, Channel> subscribers = new ConcurrentDictionary<Channel, Channel>();
|
private readonly ConcurrentDictionary<Channel, Channel> subscribers = new ConcurrentDictionary<Channel, Channel>();
|
||||||
|
|
||||||
public Func<CommandEventArgs, Task> DoFunc() => async e => {
|
public Func<CommandEventArgs, Task> DoFunc() => async e =>
|
||||||
|
{
|
||||||
var arg = e.GetArg("voice_name");
|
var arg = e.GetArg("voice_name");
|
||||||
if (string.IsNullOrWhiteSpace("voice_name"))
|
if (string.IsNullOrWhiteSpace("voice_name"))
|
||||||
return;
|
return;
|
||||||
var voiceChannel = e.Server.FindChannels(arg, ChannelType.Voice).FirstOrDefault();
|
var voiceChannel = e.Server.FindChannels(arg, ChannelType.Voice).FirstOrDefault();
|
||||||
if (voiceChannel == null)
|
if (voiceChannel == null)
|
||||||
return;
|
return;
|
||||||
if (subscribers.ContainsKey(voiceChannel)) {
|
if (subscribers.ContainsKey(voiceChannel))
|
||||||
|
{
|
||||||
await e.Channel.SendMessage("`Voice channel notifications disabled.`");
|
await e.Channel.SendMessage("`Voice channel notifications disabled.`");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (subscribers.TryAdd(voiceChannel, e.Channel)) {
|
if (subscribers.TryAdd(voiceChannel, e.Channel))
|
||||||
|
{
|
||||||
await e.Channel.SendMessage("`Voice channel notifications enabled.`");
|
await e.Channel.SendMessage("`Voice channel notifications enabled.`");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
internal override void Init(CommandGroupBuilder cgb) {
|
internal override void Init(CommandGroupBuilder cgb)
|
||||||
|
{
|
||||||
cgb.CreateCommand(Module.Prefix + "voicenotif")
|
cgb.CreateCommand(Module.Prefix + "voicenotif")
|
||||||
.Description("Enables notifications on who joined/left the voice channel.\n**Usage**:.voicenotif Karaoke club")
|
.Description("Enables notifications on who joined/left the voice channel.\n**Usage**:.voicenotif Karaoke club")
|
||||||
.Parameter("voice_name", ParameterType.Unparsed)
|
.Parameter("voice_name", ParameterType.Unparsed)
|
@ -1,20 +1,24 @@
|
|||||||
using System;
|
using Discord;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using Discord;
|
|
||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
using NadekoBot.Classes;
|
using NadekoBot.Classes;
|
||||||
using NadekoBot.Classes.Permissions;
|
using NadekoBot.Classes.Permissions;
|
||||||
using NadekoBot.Modules;
|
using NadekoBot.Commands;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using ChPermOverride = Discord.ChannelPermissionOverrides;
|
using ChPermOverride = Discord.ChannelPermissionOverrides;
|
||||||
|
|
||||||
namespace NadekoBot.Commands {
|
namespace NadekoBot.Modules.Administration.Commands
|
||||||
internal class VoicePlusTextCommand : DiscordCommand {
|
{
|
||||||
|
internal class VoicePlusTextCommand : DiscordCommand
|
||||||
|
{
|
||||||
|
|
||||||
public VoicePlusTextCommand(DiscordModule module) : base(module) {
|
public VoicePlusTextCommand(DiscordModule module) : base(module)
|
||||||
|
{
|
||||||
// changing servers may cause bugs
|
// changing servers may cause bugs
|
||||||
NadekoBot.Client.UserUpdated += async (sender, e) => {
|
NadekoBot.Client.UserUpdated += async (sender, e) =>
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
if (e.Server == null)
|
if (e.Server == null)
|
||||||
return;
|
return;
|
||||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||||
@ -24,20 +28,24 @@ namespace NadekoBot.Commands {
|
|||||||
var serverPerms = e.Server.GetUser(NadekoBot.Client.CurrentUser.Id)?.ServerPermissions;
|
var serverPerms = e.Server.GetUser(NadekoBot.Client.CurrentUser.Id)?.ServerPermissions;
|
||||||
if (serverPerms == null)
|
if (serverPerms == null)
|
||||||
return;
|
return;
|
||||||
if (!serverPerms.Value.ManageChannels || !serverPerms.Value.ManageRoles) {
|
if (!serverPerms.Value.ManageChannels || !serverPerms.Value.ManageRoles)
|
||||||
|
{
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
await e.Server.Owner.SendMessage(
|
await e.Server.Owner.SendMessage(
|
||||||
"I don't have manage server and/or Manage Channels permission," +
|
"I don't have manage server and/or Manage Channels permission," +
|
||||||
$" so I cannot run voice+text on **{e.Server.Name}** server.");
|
$" so I cannot run voice+text on **{e.Server.Name}** server.");
|
||||||
} catch { } // meh
|
}
|
||||||
|
catch { } // meh
|
||||||
config.VoicePlusTextEnabled = false;
|
config.VoicePlusTextEnabled = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var beforeVch = e.Before.VoiceChannel;
|
var beforeVch = e.Before.VoiceChannel;
|
||||||
if (beforeVch != null) {
|
if (beforeVch != null)
|
||||||
|
{
|
||||||
var textChannel =
|
var textChannel =
|
||||||
e.Server.FindChannels(GetChannelName(beforeVch.Name), ChannelType.Text).FirstOrDefault();
|
e.Server.FindChannels(GetChannelName(beforeVch.Name), ChannelType.Text).FirstOrDefault();
|
||||||
if (textChannel != null)
|
if (textChannel != null)
|
||||||
@ -46,12 +54,14 @@ namespace NadekoBot.Commands {
|
|||||||
sendMessages: PermValue.Deny));
|
sendMessages: PermValue.Deny));
|
||||||
}
|
}
|
||||||
var afterVch = e.After.VoiceChannel;
|
var afterVch = e.After.VoiceChannel;
|
||||||
if (afterVch != null) {
|
if (afterVch != null)
|
||||||
|
{
|
||||||
var textChannel = e.Server.FindChannels(
|
var textChannel = e.Server.FindChannels(
|
||||||
GetChannelName(afterVch.Name),
|
GetChannelName(afterVch.Name),
|
||||||
ChannelType.Text)
|
ChannelType.Text)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
if (textChannel == null) {
|
if (textChannel == null)
|
||||||
|
{
|
||||||
textChannel = (await e.Server.CreateChannel(GetChannelName(afterVch.Name), ChannelType.Text));
|
textChannel = (await e.Server.CreateChannel(GetChannelName(afterVch.Name), ChannelType.Text));
|
||||||
await textChannel.AddPermissionsRule(e.Server.EveryoneRole,
|
await textChannel.AddPermissionsRule(e.Server.EveryoneRole,
|
||||||
new ChPermOverride(readMessages: PermValue.Deny,
|
new ChPermOverride(readMessages: PermValue.Deny,
|
||||||
@ -61,7 +71,9 @@ namespace NadekoBot.Commands {
|
|||||||
new ChPermOverride(readMessages: PermValue.Allow,
|
new ChPermOverride(readMessages: PermValue.Allow,
|
||||||
sendMessages: PermValue.Allow));
|
sendMessages: PermValue.Allow));
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
Console.WriteLine(ex);
|
Console.WriteLine(ex);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -70,22 +82,30 @@ namespace NadekoBot.Commands {
|
|||||||
private string GetChannelName(string voiceName) =>
|
private string GetChannelName(string voiceName) =>
|
||||||
voiceName.Replace(" ", "-").Trim() + "-voice";
|
voiceName.Replace(" ", "-").Trim() + "-voice";
|
||||||
|
|
||||||
internal override void Init(CommandGroupBuilder cgb) {
|
internal override void Init(CommandGroupBuilder cgb)
|
||||||
|
{
|
||||||
cgb.CreateCommand(Module.Prefix + "v+t")
|
cgb.CreateCommand(Module.Prefix + "v+t")
|
||||||
.Alias(Module.Prefix + "voice+text")
|
.Alias(Module.Prefix + "voice+text")
|
||||||
.Description("Creates a text channel for each voice channel only users in that voice channel can see." +
|
.Description("Creates a text channel for each voice channel only users in that voice channel can see." +
|
||||||
"If you are server owner, keep in mind you will see them all the time regardless.")
|
"If you are server owner, keep in mind you will see them all the time regardless.")
|
||||||
.AddCheck(SimpleCheckers.ManageChannels())
|
.AddCheck(SimpleCheckers.ManageChannels())
|
||||||
.AddCheck(SimpleCheckers.CanManageRoles)
|
.AddCheck(SimpleCheckers.CanManageRoles)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||||
if (config.VoicePlusTextEnabled == true) {
|
if (config.VoicePlusTextEnabled == true)
|
||||||
|
{
|
||||||
config.VoicePlusTextEnabled = false;
|
config.VoicePlusTextEnabled = false;
|
||||||
foreach (var textChannel in e.Server.TextChannels.Where(c => c.Name.EndsWith("-voice"))) {
|
foreach (var textChannel in e.Server.TextChannels.Where(c => c.Name.EndsWith("-voice")))
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
await textChannel.Delete();
|
await textChannel.Delete();
|
||||||
} catch {
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
await
|
await
|
||||||
e.Channel.SendMessage(
|
e.Channel.SendMessage(
|
||||||
":anger: Error: Most likely i don't have permissions to do this.");
|
":anger: Error: Most likely i don't have permissions to do this.");
|
||||||
@ -99,7 +119,9 @@ namespace NadekoBot.Commands {
|
|||||||
await e.Channel.SendMessage("Successfuly enabled voice + text feature. " +
|
await e.Channel.SendMessage("Successfuly enabled voice + text feature. " +
|
||||||
"**Make sure the bot has manage roles and manage channels permissions**");
|
"**Make sure the bot has manage roles and manage channels permissions**");
|
||||||
|
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage(ex.ToString());
|
await e.Channel.SendMessage(ex.ToString());
|
||||||
}
|
}
|
||||||
});
|
});
|
@ -1,16 +1,14 @@
|
|||||||
using System;
|
using Discord.Commands;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Discord.Commands;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using Discord.Modules;
|
using Discord.Modules;
|
||||||
using NadekoBot.Classes.ClashOfClans;
|
using NadekoBot.Classes.ClashOfClans;
|
||||||
using NadekoBot.Modules;
|
using NadekoBot.Modules;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace NadekoBot.Commands {
|
namespace NadekoBot.Commands
|
||||||
|
{
|
||||||
internal class ClashOfClans : DiscordModule
|
internal class ClashOfClans : DiscordModule
|
||||||
{
|
{
|
||||||
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.ClashOfClans;
|
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.ClashOfClans;
|
||||||
@ -19,8 +17,10 @@ namespace NadekoBot.Commands {
|
|||||||
|
|
||||||
private readonly object writeLock = new object();
|
private readonly object writeLock = new object();
|
||||||
|
|
||||||
public override void Install(ModuleManager manager) {
|
public override void Install(ModuleManager manager)
|
||||||
manager.CreateCommands("", cgb => {
|
{
|
||||||
|
manager.CreateCommands("", cgb =>
|
||||||
|
{
|
||||||
|
|
||||||
cgb.CreateCommand(Prefix + "createwar")
|
cgb.CreateCommand(Prefix + "createwar")
|
||||||
.Alias(Prefix + "cw")
|
.Alias(Prefix + "cw")
|
||||||
@ -28,38 +28,48 @@ namespace NadekoBot.Commands {
|
|||||||
$"Creates a new war by specifying a size (>10 and multiple of 5) and enemy clan name.\n**Usage**:{Prefix}cw 15 The Enemy Clan")
|
$"Creates a new war by specifying a size (>10 and multiple of 5) and enemy clan name.\n**Usage**:{Prefix}cw 15 The Enemy Clan")
|
||||||
.Parameter("size")
|
.Parameter("size")
|
||||||
.Parameter("enemy_clan", ParameterType.Unparsed)
|
.Parameter("enemy_clan", ParameterType.Unparsed)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
if (!e.User.ServerPermissions.ManageChannels)
|
if (!e.User.ServerPermissions.ManageChannels)
|
||||||
return;
|
return;
|
||||||
List<ClashWar> wars;
|
List<ClashWar> wars;
|
||||||
if (!ClashWars.TryGetValue(e.Server.Id, out wars)) {
|
if (!ClashWars.TryGetValue(e.Server.Id, out wars))
|
||||||
|
{
|
||||||
wars = new List<ClashWar>();
|
wars = new List<ClashWar>();
|
||||||
if (!ClashWars.TryAdd(e.Server.Id, wars))
|
if (!ClashWars.TryAdd(e.Server.Id, wars))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var enemyClan = e.GetArg("enemy_clan");
|
var enemyClan = e.GetArg("enemy_clan");
|
||||||
if (string.IsNullOrWhiteSpace(enemyClan)) {
|
if (string.IsNullOrWhiteSpace(enemyClan))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int size;
|
int size;
|
||||||
if (!int.TryParse(e.GetArg("size"), out size) || size < 10 || size > 50 || size % 5 != 0) {
|
if (!int.TryParse(e.GetArg("size"), out size) || size < 10 || size > 50 || size % 5 != 0)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage("💢🔰 Not a Valid war size");
|
await e.Channel.SendMessage("💢🔰 Not a Valid war size");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var cw = new ClashWar(enemyClan, size, e);
|
var cw = new ClashWar(enemyClan, size, e);
|
||||||
//cw.Start();
|
//cw.Start();
|
||||||
wars.Add(cw);
|
wars.Add(cw);
|
||||||
cw.OnUserTimeExpired += async (u) => {
|
cw.OnUserTimeExpired += async (u) =>
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
await
|
await
|
||||||
e.Channel.SendMessage(
|
e.Channel.SendMessage(
|
||||||
$"❗🔰**Claim from @{u} for a war against {cw.ShortPrint()} has expired.**");
|
$"❗🔰**Claim from @{u} for a war against {cw.ShortPrint()} has expired.**");
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
};
|
};
|
||||||
cw.OnWarEnded += async () => {
|
cw.OnWarEnded += async () =>
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
await e.Channel.SendMessage($"❗🔰**War against {cw.ShortPrint()} ended.**");
|
await e.Channel.SendMessage($"❗🔰**War against {cw.ShortPrint()} ended.**");
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
};
|
};
|
||||||
await e.Channel.SendMessage($"❗🔰**CREATED CLAN WAR AGAINST {cw.ShortPrint()}**");
|
await e.Channel.SendMessage($"❗🔰**CREATED CLAN WAR AGAINST {cw.ShortPrint()}**");
|
||||||
//war with the index X started.
|
//war with the index X started.
|
||||||
@ -69,18 +79,23 @@ namespace NadekoBot.Commands {
|
|||||||
.Alias(Prefix + "startwar")
|
.Alias(Prefix + "startwar")
|
||||||
.Description("Starts a war with a given number.")
|
.Description("Starts a war with a given number.")
|
||||||
.Parameter("number", ParameterType.Required)
|
.Parameter("number", ParameterType.Required)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var warsInfo = GetInfo(e);
|
var warsInfo = GetInfo(e);
|
||||||
if (warsInfo == null) {
|
if (warsInfo == null)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage("💢🔰 **That war does not exist.**");
|
await e.Channel.SendMessage("💢🔰 **That war does not exist.**");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var war = warsInfo.Item1[warsInfo.Item2];
|
var war = warsInfo.Item1[warsInfo.Item2];
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
var startTask = war.Start();
|
var startTask = war.Start();
|
||||||
await e.Channel.SendMessage($"🔰**STARTED WAR AGAINST {war.ShortPrint()}**");
|
await e.Channel.SendMessage($"🔰**STARTED WAR AGAINST {war.ShortPrint()}**");
|
||||||
await startTask;
|
await startTask;
|
||||||
} catch {
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
await e.Channel.SendMessage($"🔰**WAR AGAINST {war.ShortPrint()} IS ALREADY STARTED**");
|
await e.Channel.SendMessage($"🔰**WAR AGAINST {war.ShortPrint()} IS ALREADY STARTED**");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -89,13 +104,16 @@ namespace NadekoBot.Commands {
|
|||||||
.Alias(Prefix + "lw")
|
.Alias(Prefix + "lw")
|
||||||
.Description($"Shows the active war claims by a number. Shows all wars in a short way if no number is specified.\n**Usage**: {Prefix}lw [war_number] or {Prefix}lw")
|
.Description($"Shows the active war claims by a number. Shows all wars in a short way if no number is specified.\n**Usage**: {Prefix}lw [war_number] or {Prefix}lw")
|
||||||
.Parameter("number", ParameterType.Optional)
|
.Parameter("number", ParameterType.Optional)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
// if number is null, print all wars in a short way
|
// if number is null, print all wars in a short way
|
||||||
if (string.IsNullOrWhiteSpace(e.GetArg("number"))) {
|
if (string.IsNullOrWhiteSpace(e.GetArg("number")))
|
||||||
|
{
|
||||||
//check if there are any wars
|
//check if there are any wars
|
||||||
List<ClashWar> wars = null;
|
List<ClashWar> wars = null;
|
||||||
ClashWars.TryGetValue(e.Server.Id, out wars);
|
ClashWars.TryGetValue(e.Server.Id, out wars);
|
||||||
if (wars == null || wars.Count == 0) {
|
if (wars == null || wars.Count == 0)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage("🔰 **No active wars.**");
|
await e.Channel.SendMessage("🔰 **No active wars.**");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -103,7 +121,8 @@ namespace NadekoBot.Commands {
|
|||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
sb.AppendLine("🔰 **LIST OF ACTIVE WARS**");
|
sb.AppendLine("🔰 **LIST OF ACTIVE WARS**");
|
||||||
sb.AppendLine("**-------------------------**");
|
sb.AppendLine("**-------------------------**");
|
||||||
for (var i = 0; i < wars.Count; i++) {
|
for (var i = 0; i < wars.Count; i++)
|
||||||
|
{
|
||||||
sb.AppendLine($"**#{i + 1}.** `Enemy:` **{wars[i].EnemyClan}**");
|
sb.AppendLine($"**#{i + 1}.** `Enemy:` **{wars[i].EnemyClan}**");
|
||||||
sb.AppendLine($"\t\t`Size:` **{wars[i].Size} v {wars[i].Size}**");
|
sb.AppendLine($"\t\t`Size:` **{wars[i].Size} v {wars[i].Size}**");
|
||||||
sb.AppendLine("**-------------------------**");
|
sb.AppendLine("**-------------------------**");
|
||||||
@ -113,7 +132,8 @@ namespace NadekoBot.Commands {
|
|||||||
}
|
}
|
||||||
//if number is not null, print the war needed
|
//if number is not null, print the war needed
|
||||||
var warsInfo = GetInfo(e);
|
var warsInfo = GetInfo(e);
|
||||||
if (warsInfo == null) {
|
if (warsInfo == null)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage("💢🔰 **That war does not exist.**");
|
await e.Channel.SendMessage("💢🔰 **That war does not exist.**");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -127,14 +147,17 @@ namespace NadekoBot.Commands {
|
|||||||
.Parameter("number")
|
.Parameter("number")
|
||||||
.Parameter("baseNumber")
|
.Parameter("baseNumber")
|
||||||
.Parameter("other_name", ParameterType.Unparsed)
|
.Parameter("other_name", ParameterType.Unparsed)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var warsInfo = GetInfo(e);
|
var warsInfo = GetInfo(e);
|
||||||
if (warsInfo == null || warsInfo.Item1.Count == 0) {
|
if (warsInfo == null || warsInfo.Item1.Count == 0)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage("💢🔰 **That war does not exist.**");
|
await e.Channel.SendMessage("💢🔰 **That war does not exist.**");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int baseNum;
|
int baseNum;
|
||||||
if (!int.TryParse(e.GetArg("baseNumber"), out baseNum)) {
|
if (!int.TryParse(e.GetArg("baseNumber"), out baseNum))
|
||||||
|
{
|
||||||
await e.Channel.SendMessage("💢🔰 **Invalid base number.**");
|
await e.Channel.SendMessage("💢🔰 **Invalid base number.**");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -142,11 +165,14 @@ namespace NadekoBot.Commands {
|
|||||||
string.IsNullOrWhiteSpace(e.GetArg("other_name")) ?
|
string.IsNullOrWhiteSpace(e.GetArg("other_name")) ?
|
||||||
e.User.Name :
|
e.User.Name :
|
||||||
e.GetArg("other_name");
|
e.GetArg("other_name");
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
var war = warsInfo.Item1[warsInfo.Item2];
|
var war = warsInfo.Item1[warsInfo.Item2];
|
||||||
war.Call(usr, baseNum - 1);
|
war.Call(usr, baseNum - 1);
|
||||||
await e.Channel.SendMessage($"🔰**{usr}** claimed a base #{baseNum} for a war against {war.ShortPrint()}");
|
await e.Channel.SendMessage($"🔰**{usr}** claimed a base #{baseNum} for a war against {war.ShortPrint()}");
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage($"💢🔰 {ex.Message}");
|
await e.Channel.SendMessage($"💢🔰 {ex.Message}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -156,9 +182,11 @@ namespace NadekoBot.Commands {
|
|||||||
.Description($"Finish your claim if you destroyed a base. Optional second argument finishes for someone else.\n**Usage**: {Prefix}cf [war_number] [optional_other_name]")
|
.Description($"Finish your claim if you destroyed a base. Optional second argument finishes for someone else.\n**Usage**: {Prefix}cf [war_number] [optional_other_name]")
|
||||||
.Parameter("number", ParameterType.Required)
|
.Parameter("number", ParameterType.Required)
|
||||||
.Parameter("other_name", ParameterType.Unparsed)
|
.Parameter("other_name", ParameterType.Unparsed)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var warInfo = GetInfo(e);
|
var warInfo = GetInfo(e);
|
||||||
if (warInfo == null || warInfo.Item1.Count == 0) {
|
if (warInfo == null || warInfo.Item1.Count == 0)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage("💢🔰 **That war does not exist.**");
|
await e.Channel.SendMessage("💢🔰 **That war does not exist.**");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -168,10 +196,13 @@ namespace NadekoBot.Commands {
|
|||||||
e.GetArg("other_name");
|
e.GetArg("other_name");
|
||||||
|
|
||||||
var war = warInfo.Item1[warInfo.Item2];
|
var war = warInfo.Item1[warInfo.Item2];
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
var baseNum = war.FinishClaim(usr);
|
var baseNum = war.FinishClaim(usr);
|
||||||
await e.Channel.SendMessage($"❗🔰{e.User.Mention} **DESTROYED** a base #{baseNum + 1} in a war against {war.ShortPrint()}");
|
await e.Channel.SendMessage($"❗🔰{e.User.Mention} **DESTROYED** a base #{baseNum + 1} in a war against {war.ShortPrint()}");
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage($"💢🔰 {ex.Message}");
|
await e.Channel.SendMessage($"💢🔰 {ex.Message}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -182,9 +213,11 @@ namespace NadekoBot.Commands {
|
|||||||
.Description($"Removes your claim from a certain war. Optional second argument denotes a person in whos place to unclaim\n**Usage**: {Prefix}uc [war_number] [optional_other_name]")
|
.Description($"Removes your claim from a certain war. Optional second argument denotes a person in whos place to unclaim\n**Usage**: {Prefix}uc [war_number] [optional_other_name]")
|
||||||
.Parameter("number", ParameterType.Required)
|
.Parameter("number", ParameterType.Required)
|
||||||
.Parameter("other_name", ParameterType.Unparsed)
|
.Parameter("other_name", ParameterType.Unparsed)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var warsInfo = GetInfo(e);
|
var warsInfo = GetInfo(e);
|
||||||
if (warsInfo == null || warsInfo.Item1.Count == 0) {
|
if (warsInfo == null || warsInfo.Item1.Count == 0)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage("💢🔰 **That war does not exist.**");
|
await e.Channel.SendMessage("💢🔰 **That war does not exist.**");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -192,11 +225,14 @@ namespace NadekoBot.Commands {
|
|||||||
string.IsNullOrWhiteSpace(e.GetArg("other_name")) ?
|
string.IsNullOrWhiteSpace(e.GetArg("other_name")) ?
|
||||||
e.User.Name :
|
e.User.Name :
|
||||||
e.GetArg("other_name");
|
e.GetArg("other_name");
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
var war = warsInfo.Item1[warsInfo.Item2];
|
var war = warsInfo.Item1[warsInfo.Item2];
|
||||||
var baseNumber = war.Uncall(usr);
|
var baseNumber = war.Uncall(usr);
|
||||||
await e.Channel.SendMessage($"🔰 @{usr} has **UNCLAIMED** a base #{baseNumber + 1} from a war against {war.ShortPrint()}");
|
await e.Channel.SendMessage($"🔰 @{usr} has **UNCLAIMED** a base #{baseNumber + 1} from a war against {war.ShortPrint()}");
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage($"💢🔰 {ex.Message}");
|
await e.Channel.SendMessage($"💢🔰 {ex.Message}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -205,9 +241,11 @@ namespace NadekoBot.Commands {
|
|||||||
.Alias(Prefix + "ew")
|
.Alias(Prefix + "ew")
|
||||||
.Description($"Ends the war with a given index.\n**Usage**:{Prefix}ew [war_number]")
|
.Description($"Ends the war with a given index.\n**Usage**:{Prefix}ew [war_number]")
|
||||||
.Parameter("number")
|
.Parameter("number")
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var warsInfo = GetInfo(e);
|
var warsInfo = GetInfo(e);
|
||||||
if (warsInfo == null) {
|
if (warsInfo == null)
|
||||||
|
{
|
||||||
await e.Channel.SendMessage("💢🔰 That war does not exist.");
|
await e.Channel.SendMessage("💢🔰 That war does not exist.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -219,18 +257,21 @@ namespace NadekoBot.Commands {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Tuple<List<ClashWar>, int> GetInfo(CommandEventArgs e) {
|
private static Tuple<List<ClashWar>, int> GetInfo(CommandEventArgs e)
|
||||||
|
{
|
||||||
//check if there are any wars
|
//check if there are any wars
|
||||||
List<ClashWar> wars = null;
|
List<ClashWar> wars = null;
|
||||||
ClashWars.TryGetValue(e.Server.Id, out wars);
|
ClashWars.TryGetValue(e.Server.Id, out wars);
|
||||||
if (wars == null || wars.Count == 0) {
|
if (wars == null || wars.Count == 0)
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// get the number of the war
|
// get the number of the war
|
||||||
int num;
|
int num;
|
||||||
if (string.IsNullOrWhiteSpace(e.GetArg("number")))
|
if (string.IsNullOrWhiteSpace(e.GetArg("number")))
|
||||||
num = 0;
|
num = 0;
|
||||||
else if (!int.TryParse(e.GetArg("number"), out num) || num > wars.Count) {
|
else if (!int.TryParse(e.GetArg("number"), out num) || num > wars.Count)
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
num -= 1;
|
num -= 1;
|
||||||
|
@ -159,6 +159,7 @@ namespace NadekoBot.Modules
|
|||||||
});
|
});
|
||||||
|
|
||||||
cgb.CreateCommand("how are you")
|
cgb.CreateCommand("how are you")
|
||||||
|
.Alias("how are you?")
|
||||||
.Description("Replies positive only if bot owner is online.")
|
.Description("Replies positive only if bot owner is online.")
|
||||||
.Do(async e =>
|
.Do(async e =>
|
||||||
{
|
{
|
||||||
|
@ -19,7 +19,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
internal override void Init(CommandGroupBuilder cgb)
|
internal override void Init(CommandGroupBuilder cgb)
|
||||||
{
|
{
|
||||||
cgb.CreateCommand(Module.Prefix + "roll")
|
cgb.CreateCommand(Module.Prefix + "roll")
|
||||||
.Description("Rolls 2 dice from 0-10. If you supply a number [x] it rolls up to 30 normal dice.\n**Usage**: $roll [x]")
|
.Description("Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice.\n**Usage**: $roll [x]")
|
||||||
.Parameter("num", ParameterType.Optional)
|
.Parameter("num", ParameterType.Optional)
|
||||||
.Do(Roll0to10Func());
|
.Do(Roll0to10Func());
|
||||||
cgb.CreateCommand(Module.Prefix + "nroll")
|
cgb.CreateCommand(Module.Prefix + "nroll")
|
||||||
@ -28,7 +28,13 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
.Do(Roll0to5Func());
|
.Do(Roll0to5Func());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Image GetDice(int num) => Properties.Resources.ResourceManager.GetObject("_" + num) as Image;
|
private Image GetDice(int num) => num != 10
|
||||||
|
? Properties.Resources.ResourceManager.GetObject("_" + num) as Image
|
||||||
|
: new[]
|
||||||
|
{
|
||||||
|
(Properties.Resources.ResourceManager.GetObject("_" + 1) as Image),
|
||||||
|
(Properties.Resources.ResourceManager.GetObject("_" + 0) as Image),
|
||||||
|
}.Merge();
|
||||||
|
|
||||||
private Func<CommandEventArgs, Task> Roll0to10Func()
|
private Func<CommandEventArgs, Task> Roll0to10Func()
|
||||||
{
|
{
|
||||||
@ -37,30 +43,24 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
{
|
{
|
||||||
if (e.Args[0] == "")
|
if (e.Args[0] == "")
|
||||||
{
|
{
|
||||||
var num1 = r.Next(0, 10);
|
var gen = r.Next(0, 101);
|
||||||
var num2 = r.Next(0, 10);
|
|
||||||
|
|
||||||
Image[] images;
|
var num1 = gen / 10;
|
||||||
|
var num2 = gen % 10;
|
||||||
|
|
||||||
if (num1 == 0 && num2 == 0 && r.Next(0, 2) == 1)
|
var imageStream = new Image[2] { GetDice(num1), GetDice(num2) }.Merge().ToStream(ImageFormat.Png);
|
||||||
{
|
|
||||||
images = new Image[3] { GetDice(1), GetDice(0), GetDice(0) };
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
images = new Image[2] { GetDice(num1), GetDice(num2) };
|
|
||||||
}
|
|
||||||
|
|
||||||
var bitmap = images.Merge();
|
await e.Channel.SendFile("dice.png", imageStream);
|
||||||
await e.Channel.SendFile("dice.png", bitmap.ToStream(ImageFormat.Png));
|
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var num = int.Parse(e.Args[0]);
|
var num = int.Parse(e.Args[0]);
|
||||||
if (num < 1) num = 1;
|
if (num < 1) num = 1;
|
||||||
if (num > 30)
|
if (num > 30)
|
||||||
{
|
{
|
||||||
await e.Channel.SendMessage("You can roll up to 30 dies at a time.");
|
await e.Channel.SendMessage("You can roll up to 30 dice at a time.");
|
||||||
num = 30;
|
num = 30;
|
||||||
}
|
}
|
||||||
var dices = new List<Image>(num);
|
var dices = new List<Image>(num);
|
||||||
@ -113,7 +113,8 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
throw new ArgumentException("First argument should be bigger than the second one.");
|
throw new ArgumentException("First argument should be bigger than the second one.");
|
||||||
rolled = new Random().Next(arr[0], arr[1] + 1);
|
rolled = new Random().Next(arr[0], arr[1] + 1);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
rolled = new Random().Next(0, int.Parse(e.GetArg("range")) + 1);
|
rolled = new Random().Next(0, int.Parse(e.GetArg("range")) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,9 +33,11 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
.Description("Prints a name and ID of a random user from the online list from the (optional) role.")
|
.Description("Prints a name and ID of a random user from the online list from the (optional) role.")
|
||||||
.Parameter("role", ParameterType.Optional)
|
.Parameter("role", ParameterType.Optional)
|
||||||
.Do(RaffleFunc());
|
.Do(RaffleFunc());
|
||||||
|
|
||||||
cgb.CreateCommand(Prefix + "$$")
|
cgb.CreateCommand(Prefix + "$$")
|
||||||
.Description(string.Format("Check how much {0}s you have.", NadekoBot.Config.CurrencyName))
|
.Description(string.Format("Check how much {0}s you have.", NadekoBot.Config.CurrencyName))
|
||||||
.Do(NadekoFlowerCheckFunc());
|
.Do(NadekoFlowerCheckFunc());
|
||||||
|
|
||||||
cgb.CreateCommand(Prefix + "give")
|
cgb.CreateCommand(Prefix + "give")
|
||||||
.Description(string.Format("Give someone a certain amount of {0}s", NadekoBot.Config.CurrencyName))
|
.Description(string.Format("Give someone a certain amount of {0}s", NadekoBot.Config.CurrencyName))
|
||||||
.Parameter("amount", ParameterType.Required)
|
.Parameter("amount", ParameterType.Required)
|
||||||
@ -61,12 +63,56 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await FlowersHandler.RemoveFlowersAsync(e.User, "Gift", (int)amount);
|
FlowersHandler.RemoveFlowers(e.User, "Gift", (int)amount);
|
||||||
await FlowersHandler.AddFlowersAsync(mentionedUser, "Gift", (int)amount);
|
await FlowersHandler.AddFlowersAsync(mentionedUser, "Gift", (int)amount);
|
||||||
|
|
||||||
await e.Channel.SendMessage($"{e.User.Mention} successfully sent {amount} {NadekoBot.Config.CurrencyName}s to {mentionedUser.Mention}!");
|
await e.Channel.SendMessage($"{e.User.Mention} successfully sent {amount} {NadekoBot.Config.CurrencyName}s to {mentionedUser.Mention}!");
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand(Prefix + "award")
|
||||||
|
.Description("Gives someone a certain amount of flowers. **Owner only!**")
|
||||||
|
.AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly())
|
||||||
|
.Parameter("amount", ParameterType.Required)
|
||||||
|
.Parameter("receiver", ParameterType.Unparsed)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
var amountStr = e.GetArg("amount")?.Trim();
|
||||||
|
long amount;
|
||||||
|
if (!long.TryParse(amountStr, out amount) || amount < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var mentionedUser = e.Message.MentionedUsers.FirstOrDefault(u =>
|
||||||
|
u.Id != NadekoBot.Client.CurrentUser.Id);
|
||||||
|
if (mentionedUser == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await FlowersHandler.AddFlowersAsync(mentionedUser, $"Awarded by bot owner. ({e.User.Name}/{e.User.Id})", (int)amount);
|
||||||
|
|
||||||
|
await e.Channel.SendMessage($"{e.User.Mention} successfully awarded {amount} {NadekoBot.Config.CurrencyName}s to {mentionedUser.Mention}!");
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand(Prefix + "take")
|
||||||
|
.Description("Takes a certain amount of flowers from someone. **Owner only!**")
|
||||||
|
.AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly())
|
||||||
|
.Parameter("amount", ParameterType.Required)
|
||||||
|
.Parameter("rektperson", ParameterType.Unparsed)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
var amountStr = e.GetArg("amount")?.Trim();
|
||||||
|
long amount;
|
||||||
|
if (!long.TryParse(amountStr, out amount) || amount < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var mentionedUser = e.Message.MentionedUsers.FirstOrDefault(u =>
|
||||||
|
u.Id != NadekoBot.Client.CurrentUser.Id);
|
||||||
|
if (mentionedUser == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
FlowersHandler.RemoveFlowers(mentionedUser, $"Taken by bot owner.({e.User.Name}/{e.User.Id})", (int)amount);
|
||||||
|
|
||||||
|
await e.Channel.SendMessage($"{e.User.Mention} successfully took {amount} {NadekoBot.Config.CurrencyName}s from {mentionedUser.Mention}!");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,28 +1,32 @@
|
|||||||
using System;
|
using Discord.Commands;
|
||||||
using System.Linq;
|
|
||||||
using Discord.Modules;
|
using Discord.Modules;
|
||||||
using NadekoBot.Commands;
|
using NadekoBot.Commands;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using System.IO;
|
|
||||||
using Discord.Commands;
|
|
||||||
using NadekoBot.Extensions;
|
using NadekoBot.Extensions;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace NadekoBot.Modules {
|
namespace NadekoBot.Modules
|
||||||
internal class Games : DiscordModule {
|
{
|
||||||
|
internal class Games : DiscordModule
|
||||||
|
{
|
||||||
private readonly Random rng = new Random();
|
private readonly Random rng = new Random();
|
||||||
|
|
||||||
public Games() {
|
public Games()
|
||||||
|
{
|
||||||
commands.Add(new Trivia(this));
|
commands.Add(new Trivia(this));
|
||||||
commands.Add(new SpeedTyping(this));
|
commands.Add(new SpeedTyping(this));
|
||||||
commands.Add(new PollCommand(this));
|
commands.Add(new PollCommand(this));
|
||||||
|
commands.Add(new PlantPick(this));
|
||||||
//commands.Add(new BetrayGame(this));
|
//commands.Add(new BetrayGame(this));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Games;
|
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Games;
|
||||||
|
|
||||||
public override void Install(ModuleManager manager) {
|
public override void Install(ModuleManager manager)
|
||||||
manager.CreateCommands("", cgb => {
|
{
|
||||||
|
manager.CreateCommands("", cgb =>
|
||||||
|
{
|
||||||
|
|
||||||
cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance);
|
cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance);
|
||||||
|
|
||||||
@ -30,8 +34,9 @@ namespace NadekoBot.Modules {
|
|||||||
|
|
||||||
cgb.CreateCommand(Prefix + "choose")
|
cgb.CreateCommand(Prefix + "choose")
|
||||||
.Description("Chooses a thing from a list of things\n**Usage**: >choose Get up;Sleep;Sleep more")
|
.Description("Chooses a thing from a list of things\n**Usage**: >choose Get up;Sleep;Sleep more")
|
||||||
.Parameter("list", Discord.Commands.ParameterType.Unparsed)
|
.Parameter("list", ParameterType.Unparsed)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var arg = e.GetArg("list");
|
var arg = e.GetArg("list");
|
||||||
if (string.IsNullOrWhiteSpace(arg))
|
if (string.IsNullOrWhiteSpace(arg))
|
||||||
return;
|
return;
|
||||||
@ -43,24 +48,29 @@ namespace NadekoBot.Modules {
|
|||||||
|
|
||||||
cgb.CreateCommand(Prefix + "8ball")
|
cgb.CreateCommand(Prefix + "8ball")
|
||||||
.Description("Ask the 8ball a yes/no question.")
|
.Description("Ask the 8ball a yes/no question.")
|
||||||
.Parameter("question", Discord.Commands.ParameterType.Unparsed)
|
.Parameter("question", ParameterType.Unparsed)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var question = e.GetArg("question");
|
var question = e.GetArg("question");
|
||||||
if (string.IsNullOrWhiteSpace(question))
|
if (string.IsNullOrWhiteSpace(question))
|
||||||
return;
|
return;
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
await e.Channel.SendMessage(
|
await e.Channel.SendMessage(
|
||||||
$":question: **Question**: `{question}` \n🎱 **8Ball Answers**: `{NadekoBot.Config._8BallResponses[rng.Next(0, NadekoBot.Config._8BallResponses.Length)]}`");
|
$":question: **Question**: `{question}` \n🎱 **8Ball Answers**: `{NadekoBot.Config._8BallResponses[rng.Next(0, NadekoBot.Config._8BallResponses.Length)]}`");
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
});
|
});
|
||||||
|
|
||||||
cgb.CreateCommand(Prefix + "rps")
|
cgb.CreateCommand(Prefix + "rps")
|
||||||
.Description("Play a game of rocket paperclip scissors with nadkeo.\n**Usage**: >rps scissors")
|
.Description("Play a game of rocket paperclip scissors with Nadeko.\n**Usage**: >rps scissors")
|
||||||
.Parameter("input", ParameterType.Required)
|
.Parameter("input", ParameterType.Required)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var input = e.GetArg("input").Trim();
|
var input = e.GetArg("input").Trim();
|
||||||
int pick;
|
int pick;
|
||||||
switch (input) {
|
switch (input)
|
||||||
|
{
|
||||||
case "r":
|
case "r":
|
||||||
case "rock":
|
case "rock":
|
||||||
case "rocket":
|
case "rocket":
|
||||||
@ -96,7 +106,8 @@ namespace NadekoBot.Modules {
|
|||||||
.Description("Prints a customizable Linux interjection")
|
.Description("Prints a customizable Linux interjection")
|
||||||
.Parameter("gnu", ParameterType.Required)
|
.Parameter("gnu", ParameterType.Required)
|
||||||
.Parameter("linux", ParameterType.Required)
|
.Parameter("linux", ParameterType.Required)
|
||||||
.Do(async e => {
|
.Do(async e =>
|
||||||
|
{
|
||||||
var guhnoo = e.Args[0];
|
var guhnoo = e.Args[0];
|
||||||
var loonix = e.Args[1];
|
var loonix = e.Args[1];
|
||||||
|
|
||||||
@ -112,7 +123,8 @@ There really is a {loonix}, and these people are using it, but it is just a part
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetRPSPick(int i) {
|
private string GetRPSPick(int i)
|
||||||
|
{
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
return "rocket";
|
return "rocket";
|
||||||
else if (i == 1)
|
else if (i == 1)
|
||||||
|
@ -70,6 +70,7 @@ namespace NadekoBot.Modules
|
|||||||
|
|
||||||
cgb.CreateCommand("n")
|
cgb.CreateCommand("n")
|
||||||
.Alias("next")
|
.Alias("next")
|
||||||
|
.Alias("skip")
|
||||||
.Description("Goes to the next song in the queue.")
|
.Description("Goes to the next song in the queue.")
|
||||||
.Do(e =>
|
.Do(e =>
|
||||||
{
|
{
|
||||||
@ -138,7 +139,15 @@ namespace NadekoBot.Modules
|
|||||||
await e.Channel.SendMessage("🎵 No active music player.");
|
await e.Channel.SendMessage("🎵 No active music player.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var toSend = "🎵 **" + musicPlayer.Playlist.Count + "** `tracks currently queued.` ";
|
var currentSong = musicPlayer.CurrentSong;
|
||||||
|
if (currentSong == null)
|
||||||
|
return;
|
||||||
|
var toSend = $"🎵`Now Playing` {currentSong.PrettyName} " + $"{currentSong.PrettyCurrentTime()}\n";
|
||||||
|
if (musicPlayer.RepeatSong)
|
||||||
|
toSend += "🔂";
|
||||||
|
else if (musicPlayer.RepeatPlaylist)
|
||||||
|
toSend += "🔁";
|
||||||
|
toSend += $" **{musicPlayer.Playlist.Count}** `tracks currently queued.` ";
|
||||||
if (musicPlayer.Playlist.Count >= MusicPlayer.MaximumPlaylistSize)
|
if (musicPlayer.Playlist.Count >= MusicPlayer.MaximumPlaylistSize)
|
||||||
toSend += "**Song queue is full!**\n";
|
toSend += "**Song queue is full!**\n";
|
||||||
else
|
else
|
||||||
@ -156,9 +165,10 @@ namespace NadekoBot.Modules
|
|||||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||||
return;
|
return;
|
||||||
var currentSong = musicPlayer.CurrentSong;
|
var currentSong = musicPlayer.CurrentSong;
|
||||||
if (currentSong != null)
|
if (currentSong == null)
|
||||||
await e.Channel.SendMessage($"🎵`Now Playing` {currentSong.PrettyName} " +
|
return;
|
||||||
$"{currentSong.PrettyCurrentTime()}");
|
await e.Channel.SendMessage($"🎵`Now Playing` {currentSong.PrettyName} " +
|
||||||
|
$"{currentSong.PrettyCurrentTime()}");
|
||||||
});
|
});
|
||||||
|
|
||||||
cgb.CreateCommand("vol")
|
cgb.CreateCommand("vol")
|
||||||
@ -303,7 +313,7 @@ namespace NadekoBot.Modules
|
|||||||
});
|
});
|
||||||
|
|
||||||
cgb.CreateCommand("radio").Alias("ra")
|
cgb.CreateCommand("radio").Alias("ra")
|
||||||
.Description("Queues a direct radio stream from a link.")
|
.Description("Queues a radio stream from a link. It can be a direct mp3 radio stream, .m3u, .pls .asx or .xspf")
|
||||||
.Parameter("radio_link", ParameterType.Required)
|
.Parameter("radio_link", ParameterType.Required)
|
||||||
.Do(async e =>
|
.Do(async e =>
|
||||||
{
|
{
|
||||||
@ -385,6 +395,34 @@ namespace NadekoBot.Modules
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand("rcs")
|
||||||
|
.Alias("repeatcurrentsong")
|
||||||
|
.Description("Toggles repeat of current song.")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
MusicPlayer musicPlayer;
|
||||||
|
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||||
|
return;
|
||||||
|
var currentSong = musicPlayer.CurrentSong;
|
||||||
|
if (currentSong == null)
|
||||||
|
return;
|
||||||
|
var currentValue = musicPlayer.ToggleRepeatSong();
|
||||||
|
await e.Channel.SendMessage(currentValue ?
|
||||||
|
$"🎵🔂`Repeating track:`{currentSong.PrettyName}" :
|
||||||
|
$"🎵🔂`Current track repeat stopped.`");
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand("rpl")
|
||||||
|
.Alias("repeatplaylist")
|
||||||
|
.Description("Toggles repeat of all songs in the queue (every song that finishes is added to the end of the queue).")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
MusicPlayer musicPlayer;
|
||||||
|
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||||
|
return;
|
||||||
|
var currentValue = musicPlayer.ToggleRepeatPlaylist();
|
||||||
|
await e.Channel.SendMessage($"🎵🔁`Repeat playlist {(currentValue ? "enabled" : "disabled")}`");
|
||||||
|
});
|
||||||
//cgb.CreateCommand("debug")
|
//cgb.CreateCommand("debug")
|
||||||
// .Description("Does something magical. **BOT OWNER ONLY**")
|
// .Description("Does something magical. **BOT OWNER ONLY**")
|
||||||
// .AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly())
|
// .AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly())
|
||||||
|
@ -79,7 +79,11 @@ namespace NadekoBot.Modules.Pokemon
|
|||||||
{"bullet punch",16},
|
{"bullet punch",16},
|
||||||
{"metal burst",16},
|
{"metal burst",16},
|
||||||
{"gear grind",16},
|
{"gear grind",16},
|
||||||
{"magnet bomb",16}
|
{"magnet bomb",16},
|
||||||
|
{"fairy wind",17},
|
||||||
|
{"draining kiss",17},
|
||||||
|
{"dazzling gleam",17},
|
||||||
|
{"play rough",17}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon
|
namespace NadekoBot.Modules.Pokemon
|
||||||
{
|
{
|
||||||
class PokeStats
|
class PokeStats
|
||||||
{
|
{
|
||||||
//Health left
|
//Health left
|
||||||
public int HP { get; set; } = 500;
|
public int Hp { get; set; } = 500;
|
||||||
|
public int MaxHp { get; } = 500;
|
||||||
//Amount of moves made since last time attacked
|
//Amount of moves made since last time attacked
|
||||||
public int MovesMade { get; set; } = 0;
|
public int MovesMade { get; set; } = 0;
|
||||||
//Last people attacked
|
//Last people attacked
|
||||||
|
@ -1,378 +1,318 @@
|
|||||||
using System;
|
using Discord.Commands;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Discord.Modules;
|
using Discord.Modules;
|
||||||
using Discord.Commands;
|
|
||||||
using NadekoBot.Commands;
|
|
||||||
using NadekoBot.Classes;
|
using NadekoBot.Classes;
|
||||||
using NadekoBot.Extensions;
|
|
||||||
using NadekoBot.Classes._DataModels;
|
using NadekoBot.Classes._DataModels;
|
||||||
using NadekoBot.Classes.Permissions;
|
using NadekoBot.Classes.Permissions;
|
||||||
using System.Collections.Concurrent;
|
using NadekoBot.Extensions;
|
||||||
using NadekoBot.Modules.Pokemon.PokeTypes;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using NadekoBot.Modules.Pokemon.PokeTypes.Extensions;
|
using NadekoBot.Modules.Pokemon.PokeTypes.Extensions;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon
|
namespace NadekoBot.Modules.Pokemon
|
||||||
{
|
{
|
||||||
|
class PokemonModule : DiscordModule
|
||||||
class PokemonGame : DiscordModule
|
|
||||||
{
|
{
|
||||||
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Pokemon;
|
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Pokemon;
|
||||||
public readonly int BaseHealth = 500;
|
|
||||||
//private Dictionary<ulong, Pokestats> stats = new Dictionary<ulong, Pokestats>();
|
|
||||||
private ConcurrentDictionary<ulong, PokeStats> Stats = new ConcurrentDictionary<ulong, PokeStats>();
|
private ConcurrentDictionary<ulong, PokeStats> Stats = new ConcurrentDictionary<ulong, PokeStats>();
|
||||||
|
|
||||||
|
public PokemonModule()
|
||||||
public PokemonGame()
|
|
||||||
{
|
{
|
||||||
//Something?
|
DbHandler.Instance.DeleteAll<PokeMoves>();
|
||||||
}
|
DbHandler.Instance.InsertMany(
|
||||||
public override void Install(ModuleManager manager)
|
DefaultMoves.DefaultMovesList.Select(move => new PokeMoves
|
||||||
{
|
|
||||||
manager.CreateCommands("", cgb =>
|
|
||||||
{
|
|
||||||
cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance);
|
|
||||||
|
|
||||||
commands.ForEach(cmd => cmd.Init(cgb));
|
|
||||||
|
|
||||||
cgb.CreateCommand(Prefix + "attack")
|
|
||||||
.Description("Attacks a target with the given move")
|
|
||||||
.Parameter("move", ParameterType.Required)
|
|
||||||
.Parameter("target", ParameterType.Unparsed)
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
{
|
||||||
var move = e.GetArg("move");
|
move = move.Key,
|
||||||
var target = e.Server.FindUsers(e.GetArg("target")).FirstOrDefault();
|
type = move.Value
|
||||||
if (target == null)
|
}));
|
||||||
{
|
|
||||||
await e.Channel.SendMessage("No such person.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Checking stats first, then move
|
|
||||||
//Set up the userstats
|
|
||||||
PokeStats userStats;
|
|
||||||
userStats = Stats.GetOrAdd(e.User.Id, defaultStats());
|
|
||||||
|
|
||||||
//Check if able to move
|
|
||||||
//User not able if HP < 0, has made more than 4 attacks
|
|
||||||
if (userStats.HP < 0)
|
|
||||||
{
|
|
||||||
await e.Channel.SendMessage($"{e.User.Mention} has fainted and was not able to move!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (userStats.MovesMade >= 5)
|
|
||||||
{
|
|
||||||
await e.Channel.SendMessage($"{e.User.Mention} has used too many moves in a row and was not able to move!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (userStats.LastAttacked.Contains(target.Id))
|
|
||||||
{
|
|
||||||
await e.Channel.SendMessage($"{e.User.Mention} can't attack again without retaliation!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//get target stats
|
|
||||||
PokeStats targetStats;
|
|
||||||
targetStats = Stats.GetOrAdd(target.Id, defaultStats());
|
|
||||||
|
|
||||||
//If target's HP is below 0, no use attacking
|
|
||||||
if (targetStats.HP <= 0)
|
|
||||||
{
|
|
||||||
await e.Channel.SendMessage($"{target.Mention} has already fainted!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check whether move can be used
|
|
||||||
IPokeType userType = getPokeType(e.User.Id);
|
|
||||||
|
|
||||||
var enabledMoves = userType.GetMoves();
|
|
||||||
if (!enabledMoves.Contains(move.ToLowerInvariant()))
|
|
||||||
{
|
|
||||||
await e.Channel.SendMessage($"{e.User.Mention} was not able to use **{move}**, use {Prefix}listmoves to see moves you can use");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get target type
|
|
||||||
IPokeType targetType = getPokeType(target.Id);
|
|
||||||
//generate damage
|
|
||||||
int damage = getDamage(userType, targetType);
|
|
||||||
//apply damage to target
|
|
||||||
targetStats.HP -= damage;
|
|
||||||
|
|
||||||
var response = $"{e.User.Mention} used **{move}**{userType.GetImage()} on {target.Mention}{targetType.GetImage()} for **{damage}** damage";
|
|
||||||
|
|
||||||
//Damage type
|
|
||||||
if (damage < 40)
|
|
||||||
{
|
|
||||||
response += "\nIt's not effective..";
|
|
||||||
}
|
|
||||||
else if (damage > 60)
|
|
||||||
{
|
|
||||||
response += "\nIt's super effective!";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
response += "\nIt's somewhat effective";
|
|
||||||
}
|
|
||||||
|
|
||||||
//check fainted
|
|
||||||
|
|
||||||
if (targetStats.HP <= 0)
|
|
||||||
{
|
|
||||||
response += $"\n**{target.Name}** has fainted!";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
response += $"\n**{target.Name}** has {targetStats.HP} HP remaining";
|
|
||||||
}
|
|
||||||
|
|
||||||
//update other stats
|
|
||||||
userStats.LastAttacked.Add(target.Id);
|
|
||||||
userStats.MovesMade++;
|
|
||||||
targetStats.MovesMade = 0;
|
|
||||||
if (targetStats.LastAttacked.Contains(e.User.Id))
|
|
||||||
{
|
|
||||||
targetStats.LastAttacked.Remove(e.User.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
//update dictionary
|
|
||||||
//This can stay the same right?
|
|
||||||
Stats[e.User.Id] = userStats;
|
|
||||||
Stats[target.Id] = targetStats;
|
|
||||||
|
|
||||||
await e.Channel.SendMessage(response);
|
|
||||||
});
|
|
||||||
|
|
||||||
cgb.CreateCommand(Prefix + "listmoves")
|
|
||||||
.Description("Lists the moves you are able to use")
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
|
||||||
var userType = getPokeType(e.User.Id);
|
|
||||||
List<string> movesList = userType.GetMoves();
|
|
||||||
var str = "**Moves:**";
|
|
||||||
foreach (string m in movesList)
|
|
||||||
{
|
|
||||||
str += $"\n{userType.GetImage()}{m}";
|
|
||||||
}
|
|
||||||
await e.Channel.SendMessage(str);
|
|
||||||
});
|
|
||||||
|
|
||||||
cgb.CreateCommand(Prefix + "addmove")
|
|
||||||
.Description($"Adds move given to database.\n**Usage**: {Prefix}addmove flame fire")
|
|
||||||
.Parameter("movename", ParameterType.Required)
|
|
||||||
.Parameter("movetype", ParameterType.Required)
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
|
||||||
//Implement NadekoFlowers????
|
|
||||||
string newMove = e.GetArg("movename").ToLowerInvariant();
|
|
||||||
var newType = PokemonTypesMain.stringToPokeType(e.GetArg("movetype").ToUpperInvariant());
|
|
||||||
int typeNum = newType.GetNum();
|
|
||||||
var db = DbHandler.Instance.GetAllRows<PokeMoves>().Select(x => x.move);
|
|
||||||
if (db.Contains(newMove))
|
|
||||||
{
|
|
||||||
await e.Channel.SendMessage($"{newMove} already exists");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await Task.Run(() =>
|
|
||||||
{
|
|
||||||
DbHandler.Instance.InsertData(new Classes._DataModels.PokeMoves
|
|
||||||
{
|
|
||||||
move = newMove,
|
|
||||||
type = typeNum
|
|
||||||
});
|
|
||||||
});
|
|
||||||
await e.Channel.SendMessage($"Added {newType.GetImage()}{newMove}");
|
|
||||||
});
|
|
||||||
|
|
||||||
cgb.CreateCommand(Prefix + "heal")
|
|
||||||
.Description($"Heals someone. Revives those that fainted. Costs a NadekoFlower \n**Usage**:{Prefix}revive @someone")
|
|
||||||
.Parameter("target", ParameterType.Required)
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
|
||||||
var usr = e.Server.FindUsers(e.GetArg("target")).FirstOrDefault();
|
|
||||||
if (usr == null)
|
|
||||||
{
|
|
||||||
await e.Channel.SendMessage("No such person.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Stats.ContainsKey(usr.Id))
|
|
||||||
{
|
|
||||||
|
|
||||||
var targetStats = Stats[usr.Id];
|
|
||||||
int HP = targetStats.HP;
|
|
||||||
if (targetStats.HP == BaseHealth)
|
|
||||||
{
|
|
||||||
await e.Channel.SendMessage($"{usr.Name} already has full HP!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//Payment~
|
|
||||||
var amount = 1;
|
|
||||||
var pts = Classes.DbHandler.Instance.GetStateByUserId((long)e.User.Id)?.Value ?? 0;
|
|
||||||
if (pts < amount)
|
|
||||||
{
|
|
||||||
await e.Channel.SendMessage($"{e.User.Mention} you don't have enough NadekoFlowers! \nYou still need {amount - pts} to be able to do this!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var up = (usr.Id == e.User.Id) ? "yourself" : usr.Name;
|
|
||||||
await FlowersHandler.RemoveFlowersAsync(e.User, $"heal {up}", amount);
|
|
||||||
//healing
|
|
||||||
targetStats.HP = BaseHealth;
|
|
||||||
if (HP < 0)
|
|
||||||
{
|
|
||||||
//Could heal only for half HP?
|
|
||||||
Stats[usr.Id].HP = (BaseHealth / 2);
|
|
||||||
await e.Channel.SendMessage($"{e.User.Name} revived {usr.Name} for 🌸");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await e.Channel.SendMessage($"{e.User.Name} healed {usr.Name} for {BaseHealth - HP} HP with a 🌸");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await e.Channel.SendMessage($"{usr.Name} already has full HP!");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cgb.CreateCommand(Prefix + "type")
|
|
||||||
.Description($"Get the poketype of the target.\n**Usage**: {Prefix}type @someone")
|
|
||||||
.Parameter("target", ParameterType.Required)
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
|
||||||
var usr = e.Server.FindUsers(e.GetArg("target")).FirstOrDefault();
|
|
||||||
if (usr == null)
|
|
||||||
{
|
|
||||||
await e.Channel.SendMessage("No such person.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pType = getPokeType(usr.Id);
|
|
||||||
await e.Channel.SendMessage($"Type of {usr.Name} is **{pType.GetName().ToLowerInvariant()}**{pType.GetImage()}");
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
cgb.CreateCommand(Prefix + "setdefaultmoves")
|
|
||||||
.Description($"Sets the moves DB to the default state and returns them all **OWNER ONLY**")
|
|
||||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
|
||||||
//clear DB
|
|
||||||
var db = DbHandler.Instance.GetAllRows<PokeMoves>();
|
|
||||||
foreach (PokeMoves p in db)
|
|
||||||
{
|
|
||||||
DbHandler.Instance.Delete<PokeMoves>(p.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var entry in DefaultMoves.DefaultMovesList)
|
|
||||||
{
|
|
||||||
DbHandler.Instance.InsertData(new Classes._DataModels.PokeMoves
|
|
||||||
{
|
|
||||||
move = entry.Key,
|
|
||||||
type = entry.Value
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var str = "**Reset moves to default**.\n**Moves:**";
|
|
||||||
//could sort, but meh
|
|
||||||
var dbMoves = DbHandler.Instance.GetAllRows<PokeMoves>();
|
|
||||||
foreach (PokeMoves m in dbMoves)
|
|
||||||
{
|
|
||||||
var t = PokemonTypesMain.IntToPokeType(m.type);
|
|
||||||
|
|
||||||
str += $"\n{t.GetImage()}{m.move}";
|
|
||||||
}
|
|
||||||
|
|
||||||
await e.Channel.SendMessage(str);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
cgb.CreateCommand(Prefix + "settype")
|
|
||||||
.Description($"Set your poketype. Costs a NadekoFlower.\n**Usage**: {Prefix}settype fire")
|
|
||||||
.Parameter("targetType", ParameterType.Required)
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
|
||||||
var targetTypeString = e.GetArg("targetType");
|
|
||||||
var targetType = PokemonTypesMain.stringToPokeType(targetTypeString.ToUpperInvariant());
|
|
||||||
if (targetType == null)
|
|
||||||
{
|
|
||||||
await e.Channel.SendMessage("Invalid type specified. Type must be one of:\nNORMAL, FIRE, WATER, ELECTRIC, GRASS, ICE, FIGHTING, POISON, GROUND, FLYING, PSYCHIC, BUG, ROCK, GHOST, DRAGON, DARK, STEEL");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (targetType == getPokeType(e.User.Id))
|
|
||||||
{
|
|
||||||
await e.Channel.SendMessage($"Your type is already {targetType.GetName().ToLowerInvariant()}{targetType.GetImage()}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Payment~
|
|
||||||
var amount = 1;
|
|
||||||
var pts = Classes.DbHandler.Instance.GetStateByUserId((long)e.User.Id)?.Value ?? 0;
|
|
||||||
if (pts < amount)
|
|
||||||
{
|
|
||||||
await e.Channel.SendMessage($"{e.User.Mention} you don't have enough NadekoFlowers! \nYou still need {amount - pts} to be able to do this!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await FlowersHandler.RemoveFlowersAsync(e.User, $"set usertype to {targetTypeString}", amount);
|
|
||||||
//Actually changing the type here
|
|
||||||
var preTypes = DbHandler.Instance.GetAllRows<userPokeTypes>();
|
|
||||||
Dictionary<long, int> Dict = preTypes.ToDictionary(x => x.UserId, y => y.Id);
|
|
||||||
if (Dict.ContainsKey((long)e.User.Id))
|
|
||||||
{
|
|
||||||
//delete previous type
|
|
||||||
DbHandler.Instance.Delete<userPokeTypes>(Dict[(long)e.User.Id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
DbHandler.Instance.InsertData(new Classes._DataModels.userPokeTypes
|
|
||||||
{
|
|
||||||
UserId = (long)e.User.Id,
|
|
||||||
type = targetType.GetNum()
|
|
||||||
});
|
|
||||||
|
|
||||||
//Now for the response
|
|
||||||
|
|
||||||
await e.Channel.SendMessage($"Set type of {e.User.Mention} to {targetTypeString}{targetType.GetImage()} for a 🌸");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int GetDamage(PokeType usertype, PokeType targetType)
|
||||||
|
|
||||||
|
|
||||||
private int getDamage(IPokeType usertype, IPokeType targetType)
|
|
||||||
{
|
{
|
||||||
Random rng = new Random();
|
var rng = new Random();
|
||||||
int damage = rng.Next(40, 60);
|
int damage = rng.Next(40, 60);
|
||||||
double multiplier = 1;
|
var multiplier = usertype.Multiplier(targetType);
|
||||||
multiplier = usertype.GetMagnifier(targetType);
|
|
||||||
damage = (int)(damage * multiplier);
|
damage = (int)(damage * multiplier);
|
||||||
return damage;
|
return damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IPokeType getPokeType(ulong id)
|
private PokeType GetPokeType(ulong id)
|
||||||
{
|
{
|
||||||
|
|
||||||
var db = DbHandler.Instance.GetAllRows<userPokeTypes>();
|
var db = DbHandler.Instance.GetAllRows<UserPokeTypes>();
|
||||||
Dictionary<long, int> setTypes = db.ToDictionary(x => x.UserId, y => y.type);
|
Dictionary<long, int> setTypes = db.ToDictionary(x => x.UserId, y => y.type);
|
||||||
if (setTypes.ContainsKey((long)id))
|
if (setTypes.ContainsKey((long)id))
|
||||||
{
|
{
|
||||||
return PokemonTypesMain.IntToPokeType(setTypes[(long)id]);
|
return PokemonTypesMain.IntToPokeType(setTypes[(long)id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int remainder = (int)id % 16;
|
int remainder = Math.Abs((int)(id % 18));
|
||||||
|
|
||||||
return PokemonTypesMain.IntToPokeType(remainder);
|
return PokemonTypesMain.IntToPokeType(remainder);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private PokeStats defaultStats()
|
public override void Install(ModuleManager manager)
|
||||||
{
|
{
|
||||||
PokeStats s = new PokeStats();
|
manager.CreateCommands("", cgb =>
|
||||||
s.HP = BaseHealth;
|
{
|
||||||
return s;
|
cgb.AddCheck(PermissionChecker.Instance);
|
||||||
|
|
||||||
|
commands.ForEach(cmd => cmd.Init(cgb));
|
||||||
|
|
||||||
|
cgb.CreateCommand(Prefix + "attack")
|
||||||
|
.Description("Attacks a target with the given move")
|
||||||
|
.Parameter("move", ParameterType.Required)
|
||||||
|
.Parameter("target", ParameterType.Unparsed)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
var move = e.GetArg("move");
|
||||||
|
var targetStr = e.GetArg("target")?.Trim();
|
||||||
|
if (string.IsNullOrWhiteSpace(targetStr))
|
||||||
|
return;
|
||||||
|
var target = e.Server.FindUsers(targetStr).FirstOrDefault();
|
||||||
|
if (target == null)
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage("No such person.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (target == e.User)
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage("You can't attack yourself.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Checking stats first, then move
|
||||||
|
//Set up the userstats
|
||||||
|
PokeStats userStats;
|
||||||
|
userStats = Stats.GetOrAdd(e.User.Id, new PokeStats());
|
||||||
|
|
||||||
|
//Check if able to move
|
||||||
|
//User not able if HP < 0, has made more than 4 attacks
|
||||||
|
if (userStats.Hp < 0)
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage($"{e.User.Mention} has fainted and was not able to move!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (userStats.MovesMade >= 5)
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage($"{e.User.Mention} has used too many moves in a row and was not able to move!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (userStats.LastAttacked.Contains(target.Id))
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage($"{e.User.Mention} can't attack again without retaliation!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//get target stats
|
||||||
|
PokeStats targetStats;
|
||||||
|
targetStats = Stats.GetOrAdd(target.Id, new PokeStats());
|
||||||
|
|
||||||
|
//If target's HP is below 0, no use attacking
|
||||||
|
if (targetStats.Hp <= 0)
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage($"{target.Mention} has already fainted!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check whether move can be used
|
||||||
|
PokeType userType = GetPokeType(e.User.Id);
|
||||||
|
|
||||||
|
var enabledMoves = userType.GetMoves();
|
||||||
|
if (!enabledMoves.Contains(move.ToLowerInvariant()))
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage($"{e.User.Mention} was not able to use **{move}**, use {Prefix}listmoves to see moves you can use");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//get target type
|
||||||
|
PokeType targetType = GetPokeType(target.Id);
|
||||||
|
//generate damage
|
||||||
|
int damage = GetDamage(userType, targetType);
|
||||||
|
//apply damage to target
|
||||||
|
targetStats.Hp -= damage;
|
||||||
|
|
||||||
|
var response = $"{e.User.Mention} used **{move}**{userType.Image} on {target.Mention}{targetType.Image} for **{damage}** damage";
|
||||||
|
|
||||||
|
//Damage type
|
||||||
|
if (damage < 40)
|
||||||
|
{
|
||||||
|
response += "\nIt's not effective..";
|
||||||
|
}
|
||||||
|
else if (damage > 60)
|
||||||
|
{
|
||||||
|
response += "\nIt's super effective!";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response += "\nIt's somewhat effective";
|
||||||
|
}
|
||||||
|
|
||||||
|
//check fainted
|
||||||
|
|
||||||
|
if (targetStats.Hp <= 0)
|
||||||
|
{
|
||||||
|
response += $"\n**{target.Name}** has fainted!";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response += $"\n**{target.Name}** has {targetStats.Hp} HP remaining";
|
||||||
|
}
|
||||||
|
|
||||||
|
//update other stats
|
||||||
|
userStats.LastAttacked.Add(target.Id);
|
||||||
|
userStats.MovesMade++;
|
||||||
|
targetStats.MovesMade = 0;
|
||||||
|
if (targetStats.LastAttacked.Contains(e.User.Id))
|
||||||
|
{
|
||||||
|
targetStats.LastAttacked.Remove(e.User.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
//update dictionary
|
||||||
|
//This can stay the same right?
|
||||||
|
Stats[e.User.Id] = userStats;
|
||||||
|
Stats[target.Id] = targetStats;
|
||||||
|
|
||||||
|
await e.Channel.SendMessage(response);
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand(Prefix + "ml")
|
||||||
|
.Alias("movelist")
|
||||||
|
.Description("Lists the moves you are able to use")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
var userType = GetPokeType(e.User.Id);
|
||||||
|
List<string> movesList = userType.GetMoves();
|
||||||
|
var str = $"**Moves for `{userType.Name}` type.**";
|
||||||
|
foreach (string m in movesList)
|
||||||
|
{
|
||||||
|
str += $"\n{userType.Image}{m}";
|
||||||
|
}
|
||||||
|
await e.Channel.SendMessage(str);
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand(Prefix + "heal")
|
||||||
|
.Description($"Heals someone. Revives those that fainted. Costs a NadekoFlower \n**Usage**:{Prefix}revive @someone")
|
||||||
|
.Parameter("target", ParameterType.Unparsed)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
var targetStr = e.GetArg("target")?.Trim();
|
||||||
|
if (string.IsNullOrWhiteSpace(targetStr))
|
||||||
|
return;
|
||||||
|
var usr = e.Server.FindUsers(targetStr).FirstOrDefault();
|
||||||
|
if (usr == null)
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage("No such person.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Stats.ContainsKey(usr.Id))
|
||||||
|
{
|
||||||
|
|
||||||
|
var targetStats = Stats[usr.Id];
|
||||||
|
int HP = targetStats.Hp;
|
||||||
|
if (targetStats.Hp == targetStats.MaxHp)
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage($"{usr.Name} already has full HP!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Payment~
|
||||||
|
var amount = 1;
|
||||||
|
var pts = Classes.DbHandler.Instance.GetStateByUserId((long)e.User.Id)?.Value ?? 0;
|
||||||
|
if (pts < amount)
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage($"{e.User.Mention} you don't have enough {NadekoBot.Config.CurrencyName}s! \nYou still need {amount - pts} to be able to do this!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var target = (usr.Id == e.User.Id) ? "yourself" : usr.Name;
|
||||||
|
FlowersHandler.RemoveFlowers(e.User, $"Poke-Heal {target}", amount);
|
||||||
|
//healing
|
||||||
|
targetStats.Hp = targetStats.MaxHp;
|
||||||
|
if (HP < 0)
|
||||||
|
{
|
||||||
|
//Could heal only for half HP?
|
||||||
|
Stats[usr.Id].Hp = (targetStats.MaxHp / 2);
|
||||||
|
await e.Channel.SendMessage($"{e.User.Name} revived {usr.Name} with one {NadekoBot.Config.CurrencySign}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await e.Channel.SendMessage($"{e.User.Name} healed {usr.Name} for {targetStats.MaxHp - HP} HP with a 🌸");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage($"{usr.Name} already has full HP!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand(Prefix + "type")
|
||||||
|
.Description($"Get the poketype of the target.\n**Usage**: {Prefix}type @someone")
|
||||||
|
.Parameter("target", ParameterType.Unparsed)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
var usrStr = e.GetArg("target")?.Trim();
|
||||||
|
if (string.IsNullOrWhiteSpace(usrStr))
|
||||||
|
return;
|
||||||
|
var usr = e.Server.FindUsers(usrStr).FirstOrDefault();
|
||||||
|
if (usr == null)
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage("No such person.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var pType = GetPokeType(usr.Id);
|
||||||
|
await e.Channel.SendMessage($"Type of {usr.Name} is **{pType.Name.ToLowerInvariant()}**{pType.Image}");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand(Prefix + "settype")
|
||||||
|
.Description($"Set your poketype. Costs a {NadekoBot.Config.CurrencyName}.\n**Usage**: {Prefix}settype fire")
|
||||||
|
.Parameter("targetType", ParameterType.Unparsed)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
var targetTypeStr = e.GetArg("targetType")?.ToUpperInvariant();
|
||||||
|
if (string.IsNullOrWhiteSpace(targetTypeStr))
|
||||||
|
return;
|
||||||
|
var targetType = PokemonTypesMain.stringToPokeType(targetTypeStr);
|
||||||
|
if (targetType == null)
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage("Invalid type specified. Type must be one of:\nNORMAL, FIRE, WATER, ELECTRIC, GRASS, ICE, FIGHTING, POISON, GROUND, FLYING, PSYCHIC, BUG, ROCK, GHOST, DRAGON, DARK, STEEL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (targetType == GetPokeType(e.User.Id))
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage($"Your type is already {targetType.Name.ToLowerInvariant()}{targetType.Image}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Payment~
|
||||||
|
var amount = 1;
|
||||||
|
var pts = DbHandler.Instance.GetStateByUserId((long)e.User.Id)?.Value ?? 0;
|
||||||
|
if (pts < amount)
|
||||||
|
{
|
||||||
|
await e.Channel.SendMessage($"{e.User.Mention} you don't have enough {NadekoBot.Config.CurrencyName}s! \nYou still need {amount - pts} to be able to do this!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FlowersHandler.RemoveFlowers(e.User, $"set usertype to {targetTypeStr}", amount);
|
||||||
|
//Actually changing the type here
|
||||||
|
var preTypes = DbHandler.Instance.GetAllRows<UserPokeTypes>();
|
||||||
|
Dictionary<long, int> Dict = preTypes.ToDictionary(x => x.UserId, y => y.Id);
|
||||||
|
if (Dict.ContainsKey((long)e.User.Id))
|
||||||
|
{
|
||||||
|
//delete previous type
|
||||||
|
DbHandler.Instance.Delete<UserPokeTypes>(Dict[(long)e.User.Id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
DbHandler.Instance.InsertData(new UserPokeTypes
|
||||||
|
{
|
||||||
|
UserId = (long)e.User.Id,
|
||||||
|
type = targetType.Num
|
||||||
|
});
|
||||||
|
|
||||||
|
//Now for the response
|
||||||
|
|
||||||
|
await e.Channel.SendMessage($"Set type of {e.User.Mention} to {targetTypeStr}{targetType.Image} for a {NadekoBot.Config.CurrencySign}");
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,22 +1,16 @@
|
|||||||
using System;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NadekoBot.Modules.Pokemon;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Classes._DataModels; using NadekoBot.Modules.Pokemon.PokeTypes;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
{
|
{
|
||||||
class BugType : IPokeType
|
class BugType : PokeType
|
||||||
{
|
{
|
||||||
static readonly string name = "BUG";
|
static readonly string name = "BUG";
|
||||||
public static int numType = 11;
|
public static int numType = 11;
|
||||||
|
|
||||||
public double GetMagnifier(IPokeType target)
|
public double Multiplier(PokeType target)
|
||||||
{
|
{
|
||||||
switch (target.GetName())
|
switch (target.Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
case "FIRE": return 0.5;
|
case "FIRE": return 0.5;
|
||||||
@ -24,8 +18,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
case "FIGHTING": return 0.5;
|
case "FIGHTING": return 0.5;
|
||||||
case "POISON": return 0.5;
|
case "POISON": return 0.5;
|
||||||
case "FLYING": return 0.5;
|
case "FLYING": return 0.5;
|
||||||
|
case "GHOST": return 0.5;
|
||||||
case "PSYCHIC": return 2;
|
case "PSYCHIC": return 2;
|
||||||
case "ROCK": return 0.5;
|
case "ROCK": return 0.5;
|
||||||
|
case "FAIRY": return 0.5;
|
||||||
case "DARK": return 2;
|
case "DARK": return 2;
|
||||||
case "STEEL": return 0.5;
|
case "STEEL": return 0.5;
|
||||||
default: return 1;
|
default: return 1;
|
||||||
@ -33,24 +29,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
}
|
}
|
||||||
List<string> moves = new List<string>();
|
List<string> moves = new List<string>();
|
||||||
|
|
||||||
|
public string Name => name;
|
||||||
|
|
||||||
|
public string Image => "🐛";
|
||||||
|
|
||||||
|
public int Num => numType;
|
||||||
public string GetName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string GetImage()
|
|
||||||
{
|
|
||||||
return "🐛";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetNum()
|
|
||||||
{
|
|
||||||
return numType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,52 +1,32 @@
|
|||||||
using System;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NadekoBot.Modules.Pokemon;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Classes._DataModels; using NadekoBot.Modules.Pokemon.PokeTypes;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
{
|
{
|
||||||
class DarkType : IPokeType
|
class DarkType : PokeType
|
||||||
{
|
{
|
||||||
static readonly string name = "DARK";
|
static readonly string name = "DARK";
|
||||||
public static int numType = 15;
|
public static int numType = 15;
|
||||||
|
|
||||||
public double GetMagnifier(IPokeType target)
|
public double Multiplier(PokeType target)
|
||||||
{
|
{
|
||||||
switch (target.GetName())
|
switch (target.Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
case "FIGHTING": return 0.5;
|
case "FIGHTING": return 0.5;
|
||||||
case "PSYCHIC": return 2;
|
case "PSYCHIC": return 2;
|
||||||
case "GHOST": return 2;
|
case "GHOST": return 2;
|
||||||
case "DARK": return 0.5;
|
case "DARK": return 0.5;
|
||||||
case "STEEL": return 0.5;
|
case "FAIRY": return 0.5;
|
||||||
default: return 1;
|
default: return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<string> moves = new List<string>();
|
List<string> moves = new List<string>();
|
||||||
|
|
||||||
|
public string Name => name;
|
||||||
|
|
||||||
|
public string Image => "🕶";
|
||||||
|
|
||||||
|
public int Num => numType;
|
||||||
public string GetName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string GetImage()
|
|
||||||
{
|
|
||||||
return "🕶";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetNum()
|
|
||||||
{
|
|
||||||
return numType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,21 @@
|
|||||||
using System;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NadekoBot.Modules.Pokemon;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Classes._DataModels; using NadekoBot.Modules.Pokemon.PokeTypes;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
{
|
{
|
||||||
class DragonType : IPokeType
|
class DragonType : PokeType
|
||||||
{
|
{
|
||||||
static readonly string name = "DRAGON";
|
static readonly string name = "DRAGON";
|
||||||
public static int numType = 14;
|
public static int numType = 14;
|
||||||
|
|
||||||
public double GetMagnifier(IPokeType target)
|
public double Multiplier(PokeType target)
|
||||||
{
|
{
|
||||||
switch (target.GetName())
|
switch (target.Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
case "DRAGON": return 2;
|
case "DRAGON": return 2;
|
||||||
case "STEEL": return 0.5;
|
case "STEEL": return 0.5;
|
||||||
|
case "FAIRY": return 0;
|
||||||
default: return 1;
|
default: return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -29,21 +24,12 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string GetName()
|
public string Name => name;
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string GetImage()
|
public string Image => "🐉";
|
||||||
{
|
|
||||||
return "🐉";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetNum()
|
public int Num => numType;
|
||||||
{
|
|
||||||
return numType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,16 @@
|
|||||||
using System;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NadekoBot.Modules.Pokemon;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Classes._DataModels; using NadekoBot.Modules.Pokemon.PokeTypes;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
{
|
{
|
||||||
class ElectricType : IPokeType
|
class ElectricType : PokeType
|
||||||
{
|
{
|
||||||
static readonly string name = "ELECTRIC";
|
static readonly string name = "ELECTRIC";
|
||||||
public static int numType = 3;
|
public static int numType = 3;
|
||||||
|
|
||||||
public double GetMagnifier(IPokeType target)
|
public double Multiplier(PokeType target)
|
||||||
{
|
{
|
||||||
switch (target.GetName())
|
switch (target.Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
case "WATER": return 2;
|
case "WATER": return 2;
|
||||||
@ -33,20 +27,11 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string GetName()
|
public string Name => name;
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public string GetImage()
|
public string Image => "⚡️";
|
||||||
{
|
|
||||||
return "⚡️";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetNum()
|
public int Num => numType;
|
||||||
{
|
|
||||||
return numType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
33
NadekoBot/Modules/Pokemon/PokemonTypes/FairyType.cs
Normal file
33
NadekoBot/Modules/Pokemon/PokemonTypes/FairyType.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
|
{
|
||||||
|
class FairyType : PokeType
|
||||||
|
{
|
||||||
|
static readonly string name = "FAIRY";
|
||||||
|
public static int numType = 17;
|
||||||
|
|
||||||
|
public double Multiplier(PokeType target)
|
||||||
|
{
|
||||||
|
switch (target.Name)
|
||||||
|
{
|
||||||
|
|
||||||
|
case "FIGHTING": return 2;
|
||||||
|
case "FIRE": return 0.5;
|
||||||
|
case "DARK": return 0.5;
|
||||||
|
case "POISON": return 0.5;
|
||||||
|
case "STEEL": return 2;
|
||||||
|
case "DRAGON": return 2;
|
||||||
|
default: return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<string> moves = new List<string>();
|
||||||
|
|
||||||
|
public string Name => name;
|
||||||
|
|
||||||
|
public string Image => "💫";
|
||||||
|
|
||||||
|
public int Num => numType;
|
||||||
|
}
|
||||||
|
}
|
@ -1,22 +1,16 @@
|
|||||||
using System;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NadekoBot.Modules.Pokemon;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Classes._DataModels; using NadekoBot.Modules.Pokemon.PokeTypes;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
{
|
{
|
||||||
class FightingType : IPokeType
|
class FightingType : PokeType
|
||||||
{
|
{
|
||||||
static readonly string name = "FIGHTING";
|
static readonly string name = "FIGHTING";
|
||||||
public static int numType = 6;
|
public static int numType = 6;
|
||||||
|
|
||||||
public double GetMagnifier(IPokeType target)
|
public double Multiplier(PokeType target)
|
||||||
{
|
{
|
||||||
switch (target.GetName())
|
switch (target.Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
case "NORMAL": return 2;
|
case "NORMAL": return 2;
|
||||||
@ -29,6 +23,7 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
case "GHOST": return 0;
|
case "GHOST": return 0;
|
||||||
case "DARK": return 2;
|
case "DARK": return 2;
|
||||||
case "STEEL": return 2;
|
case "STEEL": return 2;
|
||||||
|
case "FAIRY": return 0.5;
|
||||||
default: return 1;
|
default: return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,20 +32,11 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string GetName()
|
public string Name => name;
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public string GetImage()
|
public string Image => "✊";
|
||||||
{
|
|
||||||
return "✊";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetNum()
|
public int Num => numType;
|
||||||
{
|
|
||||||
return numType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,18 @@
|
|||||||
using System;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NadekoBot.Modules.Pokemon;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Classes._DataModels; using NadekoBot.Modules.Pokemon.PokeTypes;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
{
|
{
|
||||||
class FireType : IPokeType
|
class FireType : PokeType
|
||||||
{
|
{
|
||||||
static readonly string name = "FIRE";
|
static readonly string name = "FIRE";
|
||||||
public static int numType = 1;
|
public static int numType = 1;
|
||||||
|
|
||||||
public double GetMagnifier(IPokeType target)
|
public double Multiplier(PokeType target)
|
||||||
{
|
{
|
||||||
switch (target.GetName())
|
switch (target.Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
case "FIRE": return 0.5;
|
case "FIRE": return 0.5;
|
||||||
@ -33,25 +27,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<string> moves = new List<string>();
|
List<string> moves = new List<string>();
|
||||||
|
public string Name => name;
|
||||||
|
|
||||||
|
public string Image => "🔥";
|
||||||
|
|
||||||
|
public int Num => numType;
|
||||||
|
|
||||||
public string GetName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string GetImage()
|
|
||||||
{
|
|
||||||
return "🔥";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetNum()
|
|
||||||
{
|
|
||||||
return numType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,16 @@
|
|||||||
using System;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NadekoBot.Modules.Pokemon;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Classes._DataModels; using NadekoBot.Modules.Pokemon.PokeTypes;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
{
|
{
|
||||||
class FlyingType : IPokeType
|
class FlyingType : PokeType
|
||||||
{
|
{
|
||||||
static readonly string name = "FLYING";
|
static readonly string name = "FLYING";
|
||||||
public static int numType = 9;
|
public static int numType = 9;
|
||||||
|
|
||||||
public double GetMagnifier(IPokeType target)
|
public double Multiplier(PokeType target)
|
||||||
{
|
{
|
||||||
switch (target.GetName())
|
switch (target.Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
case "ELECTRIC": return 0.5;
|
case "ELECTRIC": return 0.5;
|
||||||
@ -33,21 +27,12 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string GetName()
|
public string Name => name;
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string GetImage()
|
public string Image => "☁";
|
||||||
{
|
|
||||||
return "☁";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetNum()
|
public int Num => numType;
|
||||||
{
|
|
||||||
return numType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,16 @@
|
|||||||
using System;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NadekoBot.Modules.Pokemon;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Classes._DataModels; using NadekoBot.Modules.Pokemon.PokeTypes;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
{
|
{
|
||||||
class GhostType : IPokeType
|
class GhostType : PokeType
|
||||||
{
|
{
|
||||||
static readonly string name = "GHOST";
|
static readonly string name = "GHOST";
|
||||||
public static int numType = 13;
|
public static int numType = 13;
|
||||||
|
|
||||||
public double GetMagnifier(IPokeType target)
|
public double Multiplier(PokeType target)
|
||||||
{
|
{
|
||||||
switch (target.GetName())
|
switch (target.Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
case "NORMAL": return 0;
|
case "NORMAL": return 0;
|
||||||
@ -32,21 +26,12 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string GetName()
|
public string Name => name;
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string GetImage()
|
public string Image => "👻";
|
||||||
{
|
|
||||||
return "👻";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetNum()
|
public int Num => numType;
|
||||||
{
|
|
||||||
return numType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,16 @@
|
|||||||
using System;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NadekoBot.Modules.Pokemon;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Classes._DataModels; using NadekoBot.Modules.Pokemon.PokeTypes;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
{
|
{
|
||||||
class GrassType : IPokeType
|
class GrassType : PokeType
|
||||||
{
|
{
|
||||||
static readonly string name = "GRASS";
|
static readonly string name = "GRASS";
|
||||||
public static int numType = 4;
|
public static int numType = 4;
|
||||||
|
|
||||||
public double GetMagnifier(IPokeType target)
|
public double Multiplier(PokeType target)
|
||||||
{
|
{
|
||||||
switch (target.GetName())
|
switch (target.Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
case "FIRE": return 0.5;
|
case "FIRE": return 0.5;
|
||||||
@ -35,20 +29,11 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string GetName()
|
public string Name => name;
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public string GetImage()
|
public string Image => "🌿";
|
||||||
{
|
|
||||||
return "🌿";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetNum()
|
public int Num => numType;
|
||||||
{
|
|
||||||
return numType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,16 @@
|
|||||||
using System;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NadekoBot.Modules.Pokemon;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Classes._DataModels; using NadekoBot.Modules.Pokemon.PokeTypes;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
{
|
{
|
||||||
class GroundType : IPokeType
|
class GroundType : PokeType
|
||||||
{
|
{
|
||||||
static readonly string name = "GROUND";
|
static readonly string name = "GROUND";
|
||||||
public static int numType = 8;
|
public static int numType = 8;
|
||||||
|
|
||||||
public double GetMagnifier(IPokeType target)
|
public double Multiplier(PokeType target)
|
||||||
{
|
{
|
||||||
switch (target.GetName())
|
switch (target.Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
case "FIRE": return 2;
|
case "FIRE": return 2;
|
||||||
@ -32,24 +26,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
}
|
}
|
||||||
List<string> moves = new List<string>();
|
List<string> moves = new List<string>();
|
||||||
|
|
||||||
|
public string Name => name;
|
||||||
|
|
||||||
|
public string Image => "🗻";
|
||||||
|
|
||||||
|
public int Num => numType;
|
||||||
public string GetName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string GetImage()
|
|
||||||
{
|
|
||||||
return "🗻";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetNum()
|
|
||||||
{
|
|
||||||
return numType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,23 +5,23 @@ using System.Collections.Generic;
|
|||||||
namespace NadekoBot.Modules.Pokemon.PokeTypes.Extensions
|
namespace NadekoBot.Modules.Pokemon.PokeTypes.Extensions
|
||||||
{
|
{
|
||||||
public static class IPokeTypeExtensions
|
public static class IPokeTypeExtensions
|
||||||
|
{
|
||||||
|
public static List<string> GetMoves(this PokeType poketype)
|
||||||
{
|
{
|
||||||
public static List<string> GetMoves(this IPokeType poketype)
|
var db = DbHandler.Instance.GetAllRows<PokeMoves>();
|
||||||
|
List<string> moves = new List<string>();
|
||||||
|
foreach (PokeMoves p in db)
|
||||||
{
|
{
|
||||||
var db = DbHandler.Instance.GetAllRows<PokeMoves>();
|
if (p.type == poketype.Num)
|
||||||
List<string> moves = new List<string>();
|
|
||||||
foreach (PokeMoves p in db)
|
|
||||||
{
|
{
|
||||||
if (p.type == poketype.GetNum())
|
if (!moves.Contains(p.move))
|
||||||
{
|
{
|
||||||
if (!moves.Contains(p.move))
|
moves.Add(p.move);
|
||||||
{
|
|
||||||
moves.Add(p.move);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return moves;
|
|
||||||
}
|
}
|
||||||
|
return moves;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,22 +1,16 @@
|
|||||||
using System;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NadekoBot.Modules.Pokemon;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Classes._DataModels; using NadekoBot.Modules.Pokemon.PokeTypes;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
{
|
{
|
||||||
class IceType : IPokeType
|
class IceType : PokeType
|
||||||
{
|
{
|
||||||
static readonly string name = "ICE";
|
static readonly string name = "ICE";
|
||||||
public static int numType = 5;
|
public static int numType = 5;
|
||||||
|
|
||||||
public double GetMagnifier(IPokeType target)
|
public double Multiplier(PokeType target)
|
||||||
{
|
{
|
||||||
switch (target.GetName())
|
switch (target.Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
case "FIRE": return 0.5;
|
case "FIRE": return 0.5;
|
||||||
@ -32,23 +26,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
}
|
}
|
||||||
List<string> moves = new List<string>();
|
List<string> moves = new List<string>();
|
||||||
|
|
||||||
|
public string Name => name;
|
||||||
|
|
||||||
|
public string Image => "❄";
|
||||||
|
|
||||||
|
public int Num => numType;
|
||||||
public string GetName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public string GetImage()
|
|
||||||
{
|
|
||||||
return "❄";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetNum()
|
|
||||||
{
|
|
||||||
return numType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,18 @@
|
|||||||
using System;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NadekoBot.Modules.Pokemon;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Classes._DataModels;
|
|
||||||
using NadekoBot.Modules.Pokemon.PokeTypes;
|
|
||||||
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
{
|
{
|
||||||
class NormalType : IPokeType
|
class NormalType : PokeType
|
||||||
{
|
{
|
||||||
static readonly string name = "NORMAL";
|
static readonly string name = "NORMAL";
|
||||||
public static int type_num = 0;
|
public static int type_num = 0;
|
||||||
|
|
||||||
public double GetMagnifier(IPokeType target)
|
public double Multiplier(PokeType target)
|
||||||
{
|
{
|
||||||
switch (target.GetName())
|
switch (target.Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
case "ROCK": return 0.5;
|
case "ROCK": return 0.5;
|
||||||
case "GHOST": return 0;
|
case "GHOST": return 0;
|
||||||
case "STEEL": return 0.5;
|
case "STEEL": return 0.5;
|
||||||
@ -29,24 +21,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
}
|
}
|
||||||
List<string> moves = new List<string>();
|
List<string> moves = new List<string>();
|
||||||
|
|
||||||
|
public string Name => name;
|
||||||
|
|
||||||
|
public string Image => "⭕️";
|
||||||
|
|
||||||
|
public int Num => type_num;
|
||||||
public string GetName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string GetImage()
|
|
||||||
{
|
|
||||||
return "⭕️";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetNum()
|
|
||||||
{
|
|
||||||
return type_num;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,16 @@
|
|||||||
using System;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NadekoBot.Modules.Pokemon;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Classes._DataModels;
|
|
||||||
using NadekoBot.Modules.Pokemon.PokeTypes;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
{
|
{
|
||||||
class PoisonType : IPokeType
|
class PoisonType : PokeType
|
||||||
{
|
{
|
||||||
static readonly string name = "POISON";
|
static readonly string name = "POISON";
|
||||||
public static int numType = 7;
|
public static int numType = 7;
|
||||||
|
|
||||||
public double GetMagnifier(IPokeType target)
|
public double Multiplier(PokeType target)
|
||||||
{
|
{
|
||||||
switch (target.GetName())
|
switch (target.Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
case "GRASS": return 2;
|
case "GRASS": return 2;
|
||||||
@ -26,28 +19,16 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
case "ROCK": return 0.5;
|
case "ROCK": return 0.5;
|
||||||
case "GHOST": return 0.5;
|
case "GHOST": return 0.5;
|
||||||
case "STEEL": return 0;
|
case "STEEL": return 0;
|
||||||
|
case "FAIRY": return 2;
|
||||||
default: return 1;
|
default: return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<string> moves = new List<string>();
|
List<string> moves = new List<string>();
|
||||||
|
|
||||||
|
public string Name => name;
|
||||||
|
|
||||||
|
public string Image => "☠";
|
||||||
|
|
||||||
|
public int Num => numType;
|
||||||
public string GetName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public string GetImage()
|
|
||||||
{
|
|
||||||
return "☠";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetNum()
|
|
||||||
{
|
|
||||||
return numType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,24 @@
|
|||||||
using System.Collections.Generic;
|
using NadekoBot.Modules.Pokemon.PokemonTypes;
|
||||||
using NadekoBot.Classes;
|
using System.Collections.Generic;
|
||||||
using NadekoBot.Classes._DataModels;
|
|
||||||
using NadekoBot.Modules.Pokemon.PokemonTypes;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokeTypes
|
namespace NadekoBot.Modules.Pokemon.PokeTypes
|
||||||
{
|
{
|
||||||
|
public interface PokeType
|
||||||
public interface IPokeType
|
|
||||||
{
|
{
|
||||||
|
string Image { get; }
|
||||||
string GetImage();
|
string Name { get; }
|
||||||
string GetName();
|
int Num { get; }
|
||||||
int GetNum();
|
double Multiplier(PokeType target);
|
||||||
double GetMagnifier(IPokeType target);
|
|
||||||
}
|
}
|
||||||
public class PokemonTypesMain
|
public class PokemonTypesMain
|
||||||
{
|
{
|
||||||
|
|
||||||
public static IPokeType stringToPokeType(string newType)
|
public static PokeType stringToPokeType(string newType)
|
||||||
{
|
{
|
||||||
|
|
||||||
foreach (IPokeType t in TypeList)
|
foreach (PokeType t in TypeList)
|
||||||
{
|
{
|
||||||
if (t.GetName() == newType)
|
if (t.Name == newType)
|
||||||
{
|
{
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
@ -30,26 +26,8 @@ namespace NadekoBot.Modules.Pokemon.PokeTypes
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//public static List<string> getMoves(int numType)
|
|
||||||
//{
|
|
||||||
// var db = DbHandler.Instance.GetAllRows<PokeMoves>();
|
|
||||||
// List<string> moves = new List<string>();
|
|
||||||
// foreach (PokeMoves p in db)
|
|
||||||
// {
|
|
||||||
// if (p.type == numType)
|
|
||||||
// {
|
|
||||||
// if (!moves.Contains(p.move))
|
|
||||||
// {
|
|
||||||
// moves.Add(p.move);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return moves;
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
//These classes can use all methods (except getMoves)
|
//These classes can use all methods (except getMoves)
|
||||||
public static List<IPokeType> TypeList = new List<IPokeType>()
|
public static List<PokeType> TypeList = new List<PokeType>()
|
||||||
{
|
{
|
||||||
new NormalType(),
|
new NormalType(),
|
||||||
new FireType(),
|
new FireType(),
|
||||||
@ -67,14 +45,15 @@ namespace NadekoBot.Modules.Pokemon.PokeTypes
|
|||||||
new GhostType(),
|
new GhostType(),
|
||||||
new DragonType(),
|
new DragonType(),
|
||||||
new DarkType(),
|
new DarkType(),
|
||||||
new SteelType()
|
new SteelType(),
|
||||||
|
new FairyType()
|
||||||
};
|
};
|
||||||
|
|
||||||
public static IPokeType IntToPokeType(int id)
|
public static PokeType IntToPokeType(int id)
|
||||||
{
|
{
|
||||||
foreach (IPokeType t in TypeList)
|
foreach (PokeType t in TypeList)
|
||||||
{
|
{
|
||||||
if (t.GetNum() == id)
|
if (t.Num == id)
|
||||||
{
|
{
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,16 @@
|
|||||||
using System;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NadekoBot.Modules.Pokemon;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Classes._DataModels;
|
|
||||||
using NadekoBot.Modules.Pokemon.PokeTypes;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
{
|
{
|
||||||
class PsychicType : IPokeType
|
class PsychicType : PokeType
|
||||||
{
|
{
|
||||||
static readonly string name = "PSYCHIC";
|
static readonly string name = "PSYCHIC";
|
||||||
public static int numType = 10;
|
public static int numType = 10;
|
||||||
|
|
||||||
public double GetMagnifier(IPokeType target)
|
public double Multiplier(PokeType target)
|
||||||
{
|
{
|
||||||
switch (target.GetName())
|
switch (target.Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
case "FIGHTING": return 2;
|
case "FIGHTING": return 2;
|
||||||
@ -33,21 +26,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string GetName()
|
public string Name => name;
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public string Image => "🔮";
|
||||||
|
|
||||||
|
public int Num => numType;
|
||||||
public string GetImage()
|
|
||||||
{
|
|
||||||
return "💫";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetNum()
|
|
||||||
{
|
|
||||||
return numType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,16 @@
|
|||||||
using System;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NadekoBot.Modules.Pokemon;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Classes._DataModels; using NadekoBot.Modules.Pokemon.PokeTypes;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
{
|
{
|
||||||
class RockType : IPokeType
|
class RockType : PokeType
|
||||||
{
|
{
|
||||||
static readonly string name = "ROCK";
|
static readonly string name = "ROCK";
|
||||||
public static int numType = 12;
|
public static int numType = 12;
|
||||||
|
|
||||||
public double GetMagnifier(IPokeType target)
|
public double Multiplier(PokeType target)
|
||||||
{
|
{
|
||||||
switch (target.GetName())
|
switch (target.Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
case "FIRE": return 2;
|
case "FIRE": return 2;
|
||||||
@ -31,24 +25,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
}
|
}
|
||||||
List<string> moves = new List<string>();
|
List<string> moves = new List<string>();
|
||||||
|
|
||||||
|
public string Name => name;
|
||||||
|
|
||||||
|
public string Image => "💎";
|
||||||
|
|
||||||
|
public int Num => numType;
|
||||||
public string GetName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string GetImage()
|
|
||||||
{
|
|
||||||
return "💎";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetNum()
|
|
||||||
{
|
|
||||||
return numType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,16 @@
|
|||||||
using System;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NadekoBot.Modules.Pokemon;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Classes._DataModels; using NadekoBot.Modules.Pokemon.PokeTypes;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
{
|
{
|
||||||
class SteelType : IPokeType
|
class SteelType : PokeType
|
||||||
{
|
{
|
||||||
static readonly string name = "STEEL";
|
static readonly string name = "STEEL";
|
||||||
public static int numType = -1;
|
public static int numType = 16;
|
||||||
|
|
||||||
public double GetMagnifier(IPokeType target)
|
public double Multiplier(PokeType target)
|
||||||
{
|
{
|
||||||
switch (target.GetName())
|
switch (target.Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
case "FIRE": return 0.5;
|
case "FIRE": return 0.5;
|
||||||
@ -30,23 +24,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
}
|
}
|
||||||
List<string> moves = new List<string>();
|
List<string> moves = new List<string>();
|
||||||
|
|
||||||
|
public string Name => name;
|
||||||
|
|
||||||
|
public string Image => "🔩";
|
||||||
|
|
||||||
|
public int Num => numType;
|
||||||
public string GetName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public string GetImage()
|
|
||||||
{
|
|
||||||
return "🔩";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetNum()
|
|
||||||
{
|
|
||||||
return numType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,16 @@
|
|||||||
using System;
|
using NadekoBot.Modules.Pokemon.PokeTypes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NadekoBot.Modules.Pokemon;
|
|
||||||
using NadekoBot.Classes;
|
|
||||||
using NadekoBot.Classes._DataModels; using NadekoBot.Modules.Pokemon.PokeTypes; using NadekoBot.Modules.Pokemon.PokeTypes;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
||||||
{
|
{
|
||||||
class WaterType : IPokeType
|
class WaterType : PokeType
|
||||||
{
|
{
|
||||||
static readonly string name = "WATER";
|
static readonly string name = "WATER";
|
||||||
public static int numType = 2;
|
public static int numType = 2;
|
||||||
|
|
||||||
public double GetMagnifier(IPokeType target)
|
public double Multiplier(PokeType target)
|
||||||
{
|
{
|
||||||
switch (target.GetName())
|
switch (target.Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
case "FIRE": return 2;
|
case "FIRE": return 2;
|
||||||
@ -30,23 +24,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes
|
|||||||
}
|
}
|
||||||
List<string> moves = new List<string>();
|
List<string> moves = new List<string>();
|
||||||
|
|
||||||
|
public string Name => name;
|
||||||
|
|
||||||
|
public string Image => "💦";
|
||||||
|
|
||||||
|
public int Num => numType;
|
||||||
public string GetName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public string GetImage()
|
|
||||||
{
|
|
||||||
return "💦";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetNum()
|
|
||||||
{
|
|
||||||
return numType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -317,9 +317,62 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
|||||||
.Description("Shows a random quote.")
|
.Description("Shows a random quote.")
|
||||||
.Do(async e =>
|
.Do(async e =>
|
||||||
{
|
{
|
||||||
await
|
var quote = NadekoBot.Config.Quotes[rng.Next(0, NadekoBot.Config.Quotes.Count)].ToString();
|
||||||
e.Channel.SendMessage(
|
await e.Channel.SendMessage(quote);
|
||||||
NadekoBot.Config.Quotes[new Random().Next(0, NadekoBot.Config.Quotes.Count)].ToString());
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand(Prefix + "catfact")
|
||||||
|
.Description("Shows a random catfact from <http://catfacts-api.appspot.com/api/facts>")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
var response = await SearchHelper.GetResponseStringAsync("http://catfacts-api.appspot.com/api/facts");
|
||||||
|
if (response == null)
|
||||||
|
return;
|
||||||
|
await e.Channel.SendMessage($"🐈 `{JObject.Parse(response)["facts"][0].ToString()}`");
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand(Prefix + "yomama")
|
||||||
|
.Alias(Prefix + "ym")
|
||||||
|
.Description("Shows a random joke from <http://api.yomomma.info/>")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
var response = await SearchHelper.GetResponseStringAsync("http://api.yomomma.info/");
|
||||||
|
await e.Channel.SendMessage("`" + JObject.Parse(response)["joke"].ToString() + "` 😆");
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand(Prefix + "randjoke")
|
||||||
|
.Alias(Prefix + "rj")
|
||||||
|
.Description("Shows a random joke from <http://tambal.azurewebsites.net/joke/random>")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
var response = await SearchHelper.GetResponseStringAsync("http://tambal.azurewebsites.net/joke/random");
|
||||||
|
await e.Channel.SendMessage("`" + JObject.Parse(response)["joke"].ToString() + "` 😆");
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand(Prefix + "chucknorris")
|
||||||
|
.Alias(Prefix + "cn")
|
||||||
|
.Description("Shows a random chucknorris joke from <http://tambal.azurewebsites.net/joke/random>")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
var response = await SearchHelper.GetResponseStringAsync("http://api.icndb.com/jokes/random/");
|
||||||
|
await e.Channel.SendMessage("`" + JObject.Parse(response)["value"]["joke"].ToString() + "` 😆");
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand(Prefix + "revav")
|
||||||
|
.Description("Returns a google reverse image search for someone's avatar.")
|
||||||
|
.Parameter("user", ParameterType.Unparsed)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
var usrStr = e.GetArg("user")?.Trim();
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(usrStr))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var usr = e.Server.FindUsers(usrStr).FirstOrDefault();
|
||||||
|
|
||||||
|
if (usr == null || string.IsNullOrWhiteSpace(usr.AvatarUrl))
|
||||||
|
return;
|
||||||
|
await e.Channel.SendMessage($"https://images.google.com/searchbyimage?image_url={usr.AvatarUrl}");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,10 @@ using Discord.Modules;
|
|||||||
using NadekoBot.Classes.JSONModels;
|
using NadekoBot.Classes.JSONModels;
|
||||||
using NadekoBot.Commands;
|
using NadekoBot.Commands;
|
||||||
using NadekoBot.Modules;
|
using NadekoBot.Modules;
|
||||||
|
using NadekoBot.Modules.Administration;
|
||||||
using NadekoBot.Modules.Gambling;
|
using NadekoBot.Modules.Gambling;
|
||||||
using NadekoBot.Modules.Pokemon;
|
using NadekoBot.Modules.Pokemon;
|
||||||
|
using NadekoBot.Modules.Translator;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -14,13 +16,12 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using NadekoBot.Modules.Translator;
|
|
||||||
|
|
||||||
namespace NadekoBot
|
namespace NadekoBot
|
||||||
{
|
{
|
||||||
public class NadekoBot
|
public class NadekoBot
|
||||||
{
|
{
|
||||||
public static DiscordClient Client;
|
public static DiscordClient Client { get; private set; }
|
||||||
public static Credentials Creds { get; set; }
|
public static Credentials Creds { get; set; }
|
||||||
public static Configuration Config { get; set; }
|
public static Configuration Config { get; set; }
|
||||||
public static LocalizedStrings Locale { get; set; } = new LocalizedStrings();
|
public static LocalizedStrings Locale { get; set; } = new LocalizedStrings();
|
||||||
@ -110,7 +111,7 @@ namespace NadekoBot
|
|||||||
Client = new DiscordClient(new DiscordConfigBuilder()
|
Client = new DiscordClient(new DiscordConfigBuilder()
|
||||||
{
|
{
|
||||||
MessageCacheSize = 10,
|
MessageCacheSize = 10,
|
||||||
ConnectionTimeout = 60000,
|
ConnectionTimeout = 120000,
|
||||||
LogLevel = LogSeverity.Warning,
|
LogLevel = LogSeverity.Warning,
|
||||||
LogHandler = (s, e) =>
|
LogHandler = (s, e) =>
|
||||||
Console.WriteLine($"Severity: {e.Severity}" +
|
Console.WriteLine($"Severity: {e.Severity}" +
|
||||||
@ -157,7 +158,7 @@ namespace NadekoBot
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
//install modules
|
//install modules
|
||||||
modules.Add(new Administration(), "Administration", ModuleFilter.None);
|
modules.Add(new AdministrationModule(), "Administration", ModuleFilter.None);
|
||||||
modules.Add(new Help(), "Help", ModuleFilter.None);
|
modules.Add(new Help(), "Help", ModuleFilter.None);
|
||||||
modules.Add(new PermissionModule(), "Permissions", ModuleFilter.None);
|
modules.Add(new PermissionModule(), "Permissions", ModuleFilter.None);
|
||||||
modules.Add(new Conversations(), "Conversations", ModuleFilter.None);
|
modules.Add(new Conversations(), "Conversations", ModuleFilter.None);
|
||||||
@ -167,7 +168,7 @@ namespace NadekoBot
|
|||||||
modules.Add(new Searches(), "Searches", ModuleFilter.None);
|
modules.Add(new Searches(), "Searches", ModuleFilter.None);
|
||||||
modules.Add(new NSFW(), "NSFW", ModuleFilter.None);
|
modules.Add(new NSFW(), "NSFW", ModuleFilter.None);
|
||||||
modules.Add(new ClashOfClans(), "ClashOfClans", ModuleFilter.None);
|
modules.Add(new ClashOfClans(), "ClashOfClans", ModuleFilter.None);
|
||||||
modules.Add(new PokemonGame(), "Pokegame", ModuleFilter.None);
|
modules.Add(new PokemonModule(), "Pokegame", ModuleFilter.None);
|
||||||
modules.Add(new TranslatorModule(), "Translator", ModuleFilter.None);
|
modules.Add(new TranslatorModule(), "Translator", ModuleFilter.None);
|
||||||
if (!string.IsNullOrWhiteSpace(Creds.TrelloAppKey))
|
if (!string.IsNullOrWhiteSpace(Creds.TrelloAppKey))
|
||||||
modules.Add(new Trello(), "Trello", ModuleFilter.None);
|
modules.Add(new Trello(), "Trello", ModuleFilter.None);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>NadekoBot</RootNamespace>
|
<RootNamespace>NadekoBot</RootNamespace>
|
||||||
<AssemblyName>NadekoBot</AssemblyName>
|
<AssemblyName>NadekoBot</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||||
@ -32,6 +32,7 @@
|
|||||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||||
<NuGetPackageImportStamp>
|
<NuGetPackageImportStamp>
|
||||||
</NuGetPackageImportStamp>
|
</NuGetPackageImportStamp>
|
||||||
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
@ -145,27 +146,30 @@
|
|||||||
<Compile Include="Classes\_DataModels\IDataModel.cs" />
|
<Compile Include="Classes\_DataModels\IDataModel.cs" />
|
||||||
<Compile Include="Classes\_DataModels\pokemoves.cs" />
|
<Compile Include="Classes\_DataModels\pokemoves.cs" />
|
||||||
<Compile Include="Classes\_DataModels\PokeTypes.cs" />
|
<Compile Include="Classes\_DataModels\PokeTypes.cs" />
|
||||||
|
<Compile Include="Classes\_DataModels\Reminder.cs" />
|
||||||
<Compile Include="Classes\_DataModels\RequestModel.cs" />
|
<Compile Include="Classes\_DataModels\RequestModel.cs" />
|
||||||
<Compile Include="Classes\_DataModels\StatsModel.cs" />
|
<Compile Include="Classes\_DataModels\StatsModel.cs" />
|
||||||
<Compile Include="Classes\_DataModels\TypingArticleModel.cs" />
|
<Compile Include="Classes\_DataModels\TypingArticleModel.cs" />
|
||||||
<Compile Include="Classes\_DataModels\UserQuoteModel.cs" />
|
<Compile Include="Classes\_DataModels\UserQuoteModel.cs" />
|
||||||
<Compile Include="Commands\BetrayGame.cs" />
|
<Compile Include="Commands\BetrayGame.cs" />
|
||||||
<Compile Include="Commands\CrossServerTextChannel.cs" />
|
<Compile Include="Commands\PlantPick.cs" />
|
||||||
<Compile Include="Commands\SelfAssignedRolesCommand.cs" />
|
<Compile Include="Modules\Administration\Commands\CrossServerTextChannel.cs" />
|
||||||
|
<Compile Include="Modules\Administration\Commands\Remind.cs" />
|
||||||
|
<Compile Include="Modules\Administration\Commands\SelfAssignedRolesCommand.cs" />
|
||||||
<Compile Include="Modules\ClashOfClans.cs" />
|
<Compile Include="Modules\ClashOfClans.cs" />
|
||||||
<Compile Include="Commands\FilterWordsCommand.cs" />
|
<Compile Include="Commands\FilterWordsCommand.cs" />
|
||||||
<Compile Include="Commands\FilterInvitesCommand.cs" />
|
<Compile Include="Commands\FilterInvitesCommand.cs" />
|
||||||
<Compile Include="Commands\LogCommand.cs" />
|
<Compile Include="Modules\Administration\Commands\LogCommand.cs" />
|
||||||
<Compile Include="Commands\LoLCommands.cs" />
|
<Compile Include="Commands\LoLCommands.cs" />
|
||||||
<Compile Include="Commands\MessageRepeater.cs" />
|
<Compile Include="Modules\Administration\Commands\MessageRepeater.cs" />
|
||||||
<Compile Include="Commands\PlayingRotate.cs" />
|
<Compile Include="Modules\Administration\Commands\PlayingRotate.cs" />
|
||||||
<Compile Include="Commands\StreamNotifications.cs" />
|
<Compile Include="Commands\StreamNotifications.cs" />
|
||||||
<Compile Include="Commands\TriviaCommand.cs" />
|
<Compile Include="Commands\TriviaCommand.cs" />
|
||||||
<Compile Include="Classes\Trivia\TriviaGame.cs" />
|
<Compile Include="Classes\Trivia\TriviaGame.cs" />
|
||||||
<Compile Include="Classes\Trivia\TriviaQuestion.cs" />
|
<Compile Include="Classes\Trivia\TriviaQuestion.cs" />
|
||||||
<Compile Include="Classes\Trivia\TriviaQuestionPool.cs" />
|
<Compile Include="Classes\Trivia\TriviaQuestionPool.cs" />
|
||||||
<Compile Include="Commands\RequestsCommand.cs" />
|
<Compile Include="Commands\RequestsCommand.cs" />
|
||||||
<Compile Include="Commands\ServerGreetCommand.cs" />
|
<Compile Include="Modules\Administration\Commands\ServerGreetCommand.cs" />
|
||||||
<Compile Include="Commands\SpeedTyping.cs" />
|
<Compile Include="Commands\SpeedTyping.cs" />
|
||||||
<Compile Include="Modules\Gambling\Helpers\Cards.cs" />
|
<Compile Include="Modules\Gambling\Helpers\Cards.cs" />
|
||||||
<Compile Include="Classes\Extensions.cs" />
|
<Compile Include="Classes\Extensions.cs" />
|
||||||
@ -175,9 +179,9 @@
|
|||||||
<Compile Include="Modules\Gambling\DrawCommand.cs" />
|
<Compile Include="Modules\Gambling\DrawCommand.cs" />
|
||||||
<Compile Include="Modules\Gambling\FlipCoinCommand.cs" />
|
<Compile Include="Modules\Gambling\FlipCoinCommand.cs" />
|
||||||
<Compile Include="Commands\HelpCommand.cs" />
|
<Compile Include="Commands\HelpCommand.cs" />
|
||||||
<Compile Include="Commands\VoiceNotificationCommand.cs" />
|
<Compile Include="Modules\Administration\Commands\VoiceNotificationCommand.cs" />
|
||||||
<Compile Include="Commands\VoicePlusTextCommand.cs" />
|
<Compile Include="Modules\Administration\Commands\VoicePlusTextCommand.cs" />
|
||||||
<Compile Include="Modules\Administration.cs" />
|
<Compile Include="Modules\Administration\AdministrationModule.cs" />
|
||||||
<Compile Include="Modules\Conversations.cs" />
|
<Compile Include="Modules\Conversations.cs" />
|
||||||
<Compile Include="Modules\DiscordModule.cs" />
|
<Compile Include="Modules\DiscordModule.cs" />
|
||||||
<Compile Include="Modules\Gambling\GamblingModule.cs" />
|
<Compile Include="Modules\Gambling\GamblingModule.cs" />
|
||||||
@ -187,9 +191,10 @@
|
|||||||
<Compile Include="Commands\PollCommand.cs" />
|
<Compile Include="Commands\PollCommand.cs" />
|
||||||
<Compile Include="Modules\NSFW.cs" />
|
<Compile Include="Modules\NSFW.cs" />
|
||||||
<Compile Include="Modules\Permissions.cs" />
|
<Compile Include="Modules\Permissions.cs" />
|
||||||
<Compile Include="Commands\RatelimitCommand.cs" />
|
<Compile Include="Modules\Administration\Commands\RatelimitCommand.cs" />
|
||||||
<Compile Include="Modules\Pokemon\DefaultMoves.cs" />
|
<Compile Include="Modules\Pokemon\DefaultMoves.cs" />
|
||||||
<Compile Include="Modules\Pokemon\PokemonModule.cs" />
|
<Compile Include="Modules\Pokemon\PokemonModule.cs" />
|
||||||
|
<Compile Include="Modules\Pokemon\PokemonTypes\FairyType.cs" />
|
||||||
<Compile Include="Modules\Pokemon\PokemonTypes\IPokeTypeExtensions.cs" />
|
<Compile Include="Modules\Pokemon\PokemonTypes\IPokeTypeExtensions.cs" />
|
||||||
<Compile Include="Modules\Pokemon\PokemonTypes\PokeType.cs" />
|
<Compile Include="Modules\Pokemon\PokemonTypes\PokeType.cs" />
|
||||||
<Compile Include="Modules\Pokemon\PokemonTypes\PsychicType.cs" />
|
<Compile Include="Modules\Pokemon\PokemonTypes\PsychicType.cs" />
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
"Gambling": "$",
|
"Gambling": "$",
|
||||||
"Permissions": ";",
|
"Permissions": ";",
|
||||||
"Programming": "%",
|
"Programming": "%",
|
||||||
"Pokemon": "poke"
|
"Pokemon": ">"
|
||||||
},
|
},
|
||||||
"ServerBlacklist": [],
|
"ServerBlacklist": [],
|
||||||
"ChannelBlacklist": [],
|
"ChannelBlacklist": [],
|
||||||
|
BIN
NadekoBot/bin/Debug/data/currency_images/img1.jpg
Normal file
BIN
NadekoBot/bin/Debug/data/currency_images/img1.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 67 KiB |
BIN
NadekoBot/bin/Debug/data/currency_images/img2.jpg
Normal file
BIN
NadekoBot/bin/Debug/data/currency_images/img2.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 225 KiB |
BIN
NadekoBot/bin/Debug/data/currency_images/img3.jpg
Normal file
BIN
NadekoBot/bin/Debug/data/currency_images/img3.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
BIN
NadekoBot/bin/Debug/data/lol/champions/AurelionSol.png
Normal file
BIN
NadekoBot/bin/Debug/data/lol/champions/AurelionSol.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
@ -9,7 +9,7 @@
|
|||||||
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" />
|
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" />
|
||||||
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net452" />
|
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net452" />
|
||||||
<package id="Parse" version="1.6.2" targetFramework="net452" />
|
<package id="Parse" version="1.6.2" targetFramework="net452" />
|
||||||
<package id="RestSharp" version="105.2.3" targetFramework="net452" />
|
<package id="RestSharp" version="105.2.3" targetFramework="net452" requireReinstallation="true" />
|
||||||
<package id="sqlite-net" version="1.0.8" targetFramework="net452" />
|
<package id="sqlite-net" version="1.0.8" targetFramework="net452" />
|
||||||
<package id="taglib" version="2.1.0.0" targetFramework="net452" />
|
<package id="taglib" version="2.1.0.0" targetFramework="net452" />
|
||||||
<package id="VideoLibrary" version="1.3.3" targetFramework="net452" />
|
<package id="VideoLibrary" version="1.3.3" targetFramework="net452" />
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>Tests</RootNamespace>
|
<RootNamespace>Tests</RootNamespace>
|
||||||
<AssemblyName>Tests</AssemblyName>
|
<AssemblyName>Tests</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
######You can donate on paypal: `nadekodiscordbot@gmail.com` or Bitcoin `17MZz1JAqME39akMLrVT4XBPffQJ2n1EPa`
|
######You can donate on paypal: `nadekodiscordbot@gmail.com` or Bitcoin `17MZz1JAqME39akMLrVT4XBPffQJ2n1EPa`
|
||||||
|
|
||||||
#NadekoBot List Of Commands
|
#NadekoBot List Of Commands
|
||||||
Version: `NadekoBot v0.9.5930.23184`
|
Version: `NadekoBot v0.9.5933.23628`
|
||||||
### Administration
|
### Administration
|
||||||
Command and aliases | Description | Usage
|
Command and aliases | Description | Usage
|
||||||
----------------|--------------|-------
|
----------------|--------------|-------
|
||||||
@ -31,6 +31,7 @@ Command and aliases | Description | Usage
|
|||||||
`.lsar` | Lits all self-assignable roles.
|
`.lsar` | Lits all self-assignable roles.
|
||||||
`.iam` | Adds a role to you that you choose. Role must be on a list of self-assignable roles. | .iam Gamer
|
`.iam` | Adds a role to you that you choose. Role must be on a list of self-assignable roles. | .iam Gamer
|
||||||
`.iamn`, `.iamnot` | Removes a role to you that you choose. Role must be on a list of self-assignable roles. | .iamn Gamer
|
`.iamn`, `.iamnot` | Removes a role to you that you choose. Role must be on a list of self-assignable roles. | .iamn Gamer
|
||||||
|
`.remind` |
|
||||||
`.sr`, `.setrole` | Sets a role for a given user. | .sr @User Guest
|
`.sr`, `.setrole` | Sets a role for a given user. | .sr @User Guest
|
||||||
`.rr`, `.removerole` | Removes a role from a given user. | .rr @User Admin
|
`.rr`, `.removerole` | Removes a role from a given user. | .rr @User Admin
|
||||||
`.r`, `.role`, `.cr` | Creates a role with a given name. | .r Awesome Role
|
`.r`, `.role`, `.cr` | Creates a role with a given name. | .r Awesome Role
|
||||||
@ -46,7 +47,7 @@ Command and aliases | Description | Usage
|
|||||||
`.vch`, `.cvch` | Creates a new voice channel with a given name.
|
`.vch`, `.cvch` | Creates a new voice channel with a given name.
|
||||||
`.rch`, `.rtch` | Removes a text channel with a given name.
|
`.rch`, `.rtch` | Removes a text channel with a given name.
|
||||||
`.ch`, `.tch` | Creates a new text channel with a given name.
|
`.ch`, `.tch` | Creates a new text channel with a given name.
|
||||||
`.st`, `.settopic` | Sets a topic on the current channel.
|
`.st`, `.settopic`, `.topic` | Sets a topic on the current channel.
|
||||||
`.uid`, `.userid` | Shows user ID.
|
`.uid`, `.userid` | Shows user ID.
|
||||||
`.cid`, `.channelid` | Shows current channel ID.
|
`.cid`, `.channelid` | Shows current channel ID.
|
||||||
`.sid`, `.serverid` | Shows current server ID.
|
`.sid`, `.serverid` | Shows current server ID.
|
||||||
@ -70,7 +71,6 @@ Command and aliases | Description | Usage
|
|||||||
`.unstuck` | Clears the message queue. **Owner Only!**
|
`.unstuck` | Clears the message queue. **Owner Only!**
|
||||||
`.donators` | List of lovely people who donated to keep this project alive.
|
`.donators` | List of lovely people who donated to keep this project alive.
|
||||||
`.adddon`, `.donadd` | Add a donator to the database.
|
`.adddon`, `.donadd` | Add a donator to the database.
|
||||||
`.topic` | Sets current channel's topic.
|
|
||||||
`.videocall` | Creates a private appear.in video call link for you and other mentioned people. The link is sent to mentioned people via a private message.
|
`.videocall` | Creates a private appear.in video call link for you and other mentioned people. The link is sent to mentioned people via a private message.
|
||||||
|
|
||||||
### Help
|
### Help
|
||||||
@ -138,7 +138,7 @@ Command and aliases | Description | Usage
|
|||||||
`@BotName uptime` | Shows how long Nadeko has been running for.
|
`@BotName uptime` | Shows how long Nadeko has been running for.
|
||||||
`@BotName die` | Works only for the owner. Shuts the bot down.
|
`@BotName die` | Works only for the owner. Shuts the bot down.
|
||||||
`@BotName do you love me` | Replies with positive answer only to the bot owner.
|
`@BotName do you love me` | Replies with positive answer only to the bot owner.
|
||||||
`@BotName how are you` | Replies positive only if bot owner is online.
|
`@BotName how are you`, `@BotName how are you?` | Replies positive only if bot owner is online.
|
||||||
`@BotName insult` | Insults @X person. | @NadekoBot insult @X.
|
`@BotName insult` | Insults @X person. | @NadekoBot insult @X.
|
||||||
`@BotName praise` | Praises @X person. | @NadekoBot praise @X.
|
`@BotName praise` | Praises @X person. | @NadekoBot praise @X.
|
||||||
`@BotName pat` | Pat someone ^_^
|
`@BotName pat` | Pat someone ^_^
|
||||||
@ -169,8 +169,10 @@ Command and aliases | Description | Usage
|
|||||||
`$roll` | Rolls 2 dice from 0-10. If you supply a number [x] it rolls up to 30 normal dice. | $roll [x]
|
`$roll` | Rolls 2 dice from 0-10. If you supply a number [x] it rolls up to 30 normal dice. | $roll [x]
|
||||||
`$nroll` | Rolls in a given range. | `$nroll 5` (rolls 0-5) or `$nroll 5-15`
|
`$nroll` | Rolls in a given range. | `$nroll 5` (rolls 0-5) or `$nroll 5-15`
|
||||||
`$raffle` | Prints a name and ID of a random user from the online list from the (optional) role.
|
`$raffle` | Prints a name and ID of a random user from the online list from the (optional) role.
|
||||||
`$$$` | Check how many NadekoFlowers you have.
|
`$$$` | Check how much NadekoFlowers you have.
|
||||||
`$give` | Give someone a certain amount of flowers
|
`$give` | Give someone a certain amount of NadekoFlowers
|
||||||
|
`$award` | Gives someone a certain amount of flowers. **Owner only!**
|
||||||
|
`$take` | Takes a certain amount of flowers from someone. **Owner only!**
|
||||||
|
|
||||||
### Games
|
### Games
|
||||||
Command and aliases | Description | Usage
|
Command and aliases | Description | Usage
|
||||||
@ -185,15 +187,13 @@ Command and aliases | Description | Usage
|
|||||||
`>pollend` | Stops active poll on this server and prints the results in this channel.
|
`>pollend` | Stops active poll on this server and prints the results in this channel.
|
||||||
`>choose` | Chooses a thing from a list of things | >choose Get up;Sleep;Sleep more
|
`>choose` | Chooses a thing from a list of things | >choose Get up;Sleep;Sleep more
|
||||||
`>8ball` | Ask the 8ball a yes/no question.
|
`>8ball` | Ask the 8ball a yes/no question.
|
||||||
`>attack` | Attack a person. Supported attacks: 'splash', 'strike', 'burn', 'surge'. | >attack strike @User
|
`>rps` | Play a game of rocket paperclip scissors with Nadeko. | >rps scissors
|
||||||
`>poketype` | Gets the users element type. Use this to do more damage with strike!
|
|
||||||
`>rps` | Play a game of rocket paperclip scissors with nadkeo. | >rps scissors
|
|
||||||
`>linux` | Prints a customizable Linux interjection
|
`>linux` | Prints a customizable Linux interjection
|
||||||
|
|
||||||
### Music
|
### Music
|
||||||
Command and aliases | Description | Usage
|
Command and aliases | Description | Usage
|
||||||
----------------|--------------|-------
|
----------------|--------------|-------
|
||||||
`!m n`, `!m next` | Goes to the next song in the queue.
|
`!m n`, `!m next`, `!m skip` | Goes to the next song in the queue.
|
||||||
`!m s`, `!m stop` | Stops the music and clears the playlist. Stays in the channel.
|
`!m s`, `!m stop` | Stops the music and clears the playlist. Stays in the channel.
|
||||||
`!m d`, `!m destroy` | Completely stops the music and unbinds the bot from the channel. (may cause weird behaviour)
|
`!m d`, `!m destroy` | Completely stops the music and unbinds the bot from the channel. (may cause weird behaviour)
|
||||||
`!m p`, `!m pause` | Pauses or Unpauses the song.
|
`!m p`, `!m pause` | Pauses or Unpauses the song.
|
||||||
@ -209,7 +209,7 @@ Command and aliases | Description | Usage
|
|||||||
`!m setgame` | Sets the game of the bot to the number of songs playing. **Owner only**
|
`!m setgame` | Sets the game of the bot to the number of songs playing. **Owner only**
|
||||||
`!m pl` | Queues up to 25 songs from a youtube playlist specified by a link, or keywords.
|
`!m pl` | Queues up to 25 songs from a youtube playlist specified by a link, or keywords.
|
||||||
`!m lopl` | Queues up to 50 songs from a directory. **Owner Only!**
|
`!m lopl` | Queues up to 50 songs from a directory. **Owner Only!**
|
||||||
`!m radio`, `!m ra` | Queues a direct radio stream from a link.
|
`!m radio`, `!m ra` | Queues a radio stream from a link. It can be a direct mp3 radio stream, .m3u, .pls .asx or .xspf
|
||||||
`!m lo` | Queues a local file by specifying a full path. **Owner Only!**
|
`!m lo` | Queues a local file by specifying a full path. **Owner Only!**
|
||||||
`!m mv` | Moves the bot to your voice channel. (works only if music is already playing)
|
`!m mv` | Moves the bot to your voice channel. (works only if music is already playing)
|
||||||
`!m rm` | Remove a song by its # in the queue, or 'all' to remove whole queue.
|
`!m rm` | Remove a song by its # in the queue, or 'all' to remove whole queue.
|
||||||
@ -222,6 +222,7 @@ Command and aliases | Description | Usage
|
|||||||
`~lolban` | Shows top 6 banned champions ordered by ban rate. Ban these champions and you will be Plat 5 in no time.
|
`~lolban` | Shows top 6 banned champions ordered by ban rate. Ban these champions and you will be Plat 5 in no time.
|
||||||
`~hitbox`, `~hb` | Notifies this channel when a certain user starts streaming. | ~hitbox SomeStreamer
|
`~hitbox`, `~hb` | Notifies this channel when a certain user starts streaming. | ~hitbox SomeStreamer
|
||||||
`~twitch`, `~tw` | Notifies this channel when a certain user starts streaming. | ~twitch SomeStreamer
|
`~twitch`, `~tw` | Notifies this channel when a certain user starts streaming. | ~twitch SomeStreamer
|
||||||
|
`~beam`, `~bm` | Notifies this channel when a certain user starts streaming. | ~beam SomeStreamer
|
||||||
`~removestream`, `~rms` | Removes notifications of a certain streamer on this channel. | ~rms SomeGuy
|
`~removestream`, `~rms` | Removes notifications of a certain streamer on this channel. | ~rms SomeGuy
|
||||||
`~liststreams`, `~ls` | Lists all streams you are following on this server. | ~ls
|
`~liststreams`, `~ls` | Lists all streams you are following on this server. | ~ls
|
||||||
`~we` | Shows weather data for a specified city and a country BOTH ARE REQUIRED. Weather api is very random if you make a mistake.
|
`~we` | Shows weather data for a specified city and a country BOTH ARE REQUIRED. Weather api is very random if you make a mistake.
|
||||||
@ -238,12 +239,11 @@ Command and aliases | Description | Usage
|
|||||||
`~ud` | Searches Urban Dictionary for a word. | ~ud Pineapple
|
`~ud` | Searches Urban Dictionary for a word. | ~ud Pineapple
|
||||||
`~#` | Searches Tagdef.com for a hashtag. | ~# ff
|
`~#` | Searches Tagdef.com for a hashtag. | ~# ff
|
||||||
`~quote` | Shows a random quote.
|
`~quote` | Shows a random quote.
|
||||||
|
`~catfact` | Shows a random catfact from <http://catfacts-api.appspot.com/api/facts>
|
||||||
### Translator
|
`~yomama`, `~ym` | Shows a random joke from <http://api.yomomma.info/>
|
||||||
Command and aliases | Description | Usage
|
`~randjoke`, `~rj` | Shows a random joke from <http://tambal.azurewebsites.net/joke/random>
|
||||||
----------------|--------------|-------
|
`~chucknorris`, `~cn` | Shows a random chucknorris joke from <http://tambal.azurewebsites.net/joke/random>
|
||||||
`~trans` | Translates from>to text. From the given language to the destiation language.
|
`~revav` | Returns a google reverse image search for someone's avatar.
|
||||||
`~translangs` | List the valid languages for translation.
|
|
||||||
|
|
||||||
### NSFW
|
### NSFW
|
||||||
Command and aliases | Description | Usage
|
Command and aliases | Description | Usage
|
||||||
@ -267,6 +267,21 @@ Command and aliases | Description | Usage
|
|||||||
`,unclaim`, `,uncall`, `,uc` | Removes your claim from a certain war. Optional second argument denotes a person in whos place to unclaim | ,uc [war_number] [optional_other_name]
|
`,unclaim`, `,uncall`, `,uc` | Removes your claim from a certain war. Optional second argument denotes a person in whos place to unclaim | ,uc [war_number] [optional_other_name]
|
||||||
`,endwar`, `,ew` | Ends the war with a given index. | ,ew [war_number]
|
`,endwar`, `,ew` | Ends the war with a given index. | ,ew [war_number]
|
||||||
|
|
||||||
|
### Pokegame
|
||||||
|
Command and aliases | Description | Usage
|
||||||
|
----------------|--------------|-------
|
||||||
|
`>attack` | Attacks a target with the given move
|
||||||
|
`>ml`, `movelist` | Lists the moves you are able to use
|
||||||
|
`>heal` | Heals someone. Revives those that fainted. Costs a NadekoFlower | >revive @someone
|
||||||
|
`>type` | Get the poketype of the target. | >type @someone
|
||||||
|
`>settype` | Set your poketype. Costs a NadekoFlower. | >settype fire
|
||||||
|
|
||||||
|
### Translator
|
||||||
|
Command and aliases | Description | Usage
|
||||||
|
----------------|--------------|-------
|
||||||
|
`~trans` | Translates from>to text. From the given language to the destiation language.
|
||||||
|
`~translangs` | List the valid languages for translation.
|
||||||
|
|
||||||
### Trello
|
### Trello
|
||||||
Command and aliases | Description | Usage
|
Command and aliases | Description | Usage
|
||||||
----------------|--------------|-------
|
----------------|--------------|-------
|
||||||
|
Loading…
Reference in New Issue
Block a user