Merge remote-tracking branch 'refs/remotes/Kwoth/master'
This commit is contained in:
		
							
								
								
									
										7
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -10,7 +10,6 @@ | ||||
| obj/ | ||||
| # User-specific files (MonoDevelop/Xamarin Studio) | ||||
| *.userprefs | ||||
| **/Bin/Debug/** | ||||
| **/Bin/Release/ | ||||
| **/Bin/PRIVATE/ | ||||
| !**/Bin/Debug/opus.dll | ||||
| @@ -19,9 +18,11 @@ obj/ | ||||
| !**/Bin/Debug/Nito.AsyncEx.dll | ||||
| !**/Bin/Debug/WebSocket4Net.dll | ||||
| !**/Bin/Debug/sqlite3.dll | ||||
| !**/Bin/Debug/data/* | ||||
| !**/Bin/Debug/data/ | ||||
| !**/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 | ||||
|  | ||||
| # NuGet Packages | ||||
|   | ||||
| @@ -11,4 +11,4 @@ | ||||
|       </dependentAssembly> | ||||
|     </assemblyBinding> | ||||
|   </runtime> | ||||
| </configuration> | ||||
| </configuration> | ||||
|   | ||||
							
								
								
									
										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 System.Linq; | ||||
| using NadekoBot.Classes._DataModels; | ||||
| using SQLite; | ||||
| using NadekoBot.Classes._DataModels; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Linq.Expressions; | ||||
|  | ||||
| namespace NadekoBot.Classes { | ||||
|     internal class DbHandler { | ||||
| namespace NadekoBot.Classes | ||||
| { | ||||
|     internal class DbHandler | ||||
|     { | ||||
|         public static DbHandler Instance { get; } = new DbHandler(); | ||||
|  | ||||
|         private string FilePath { get; } = "data/nadekobot.sqlite"; | ||||
|  | ||||
|         static DbHandler() { } | ||||
|         public DbHandler() { | ||||
|             using (var conn = new SQLiteConnection(FilePath)) { | ||||
|         public DbHandler() | ||||
|         { | ||||
|             using (var conn = new SQLiteConnection(FilePath)) | ||||
|             { | ||||
|                 conn.CreateTable<Stats>(); | ||||
|                 conn.CreateTable<Command>(); | ||||
|                 conn.CreateTable<Announcement>(); | ||||
| @@ -23,44 +27,83 @@ namespace NadekoBot.Classes { | ||||
|                 conn.CreateTable<CurrencyTransaction>(); | ||||
|                 conn.CreateTable<Donator>(); | ||||
|                 conn.CreateTable<PokeMoves>(); | ||||
|                 conn.CreateTable<userPokeTypes>(); | ||||
|                 conn.CreateTable<UserPokeTypes>(); | ||||
|                 conn.CreateTable<UserQuote>(); | ||||
|                 conn.CreateTable<Reminder>(); | ||||
|                 conn.Execute(Queries.TransactionTriggerQuery); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         internal void InsertData<T>(T o) where T : IDataModel { | ||||
|             using (var conn = new SQLiteConnection(FilePath)) { | ||||
|         internal T FindOne<T>(Expression<Func<T, bool>> p) where T : IDataModel, new() | ||||
|         { | ||||
|             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)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         internal void InsertMany<T>(T objects) where T : IEnumerable<IDataModel> { | ||||
|             using (var conn = new SQLiteConnection(FilePath)) { | ||||
|         internal void InsertMany<T>(T objects) where T : IEnumerable<IDataModel> | ||||
|         { | ||||
|             using (var conn = new SQLiteConnection(FilePath)) | ||||
|             { | ||||
|                 conn.InsertAll(objects); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         internal void UpdateData<T>(T o) where T : IDataModel { | ||||
|             using (var conn = new SQLiteConnection(FilePath)) { | ||||
|         internal void UpdateData<T>(T o) where T : IDataModel | ||||
|         { | ||||
|             using (var conn = new SQLiteConnection(FilePath)) | ||||
|             { | ||||
|                 conn.Update(o, typeof(T)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         internal HashSet<T> GetAllRows<T>() where T : IDataModel, new() { | ||||
|             using (var conn = new SQLiteConnection(FilePath)) { | ||||
|         internal HashSet<T> GetAllRows<T>() where T : IDataModel, new() | ||||
|         { | ||||
|             using (var conn = new SQLiteConnection(FilePath)) | ||||
|             { | ||||
|                 return new HashSet<T>(conn.Table<T>()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         internal CurrencyState GetStateByUserId(long id) { | ||||
|             using (var conn = new SQLiteConnection(FilePath)) { | ||||
|         internal CurrencyState GetStateByUserId(long id) | ||||
|         { | ||||
|             using (var conn = new SQLiteConnection(FilePath)) | ||||
|             { | ||||
|                 return conn.Table<CurrencyState>().Where(x => x.UserId == id).FirstOrDefault(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         internal T Delete<T>(int id) where T : IDataModel, new() { | ||||
|             using (var conn = new SQLiteConnection(FilePath)) { | ||||
|         internal T Delete<T>(int id) where T : IDataModel, new() | ||||
|         { | ||||
|             using (var conn = new SQLiteConnection(FilePath)) | ||||
|             { | ||||
|                 var found = conn.Find<T>(id); | ||||
|                 if (found != null) | ||||
|                     conn.Delete<T>(found.Id); | ||||
| @@ -71,8 +114,10 @@ namespace NadekoBot.Classes { | ||||
|         /// <summary> | ||||
|         /// Updates an existing object or creates a new one | ||||
|         /// </summary> | ||||
|         internal void Save<T>(T o) where T : IDataModel, new() { | ||||
|             using (var conn = new SQLiteConnection(FilePath)) { | ||||
|         internal void Save<T>(T o) where T : IDataModel, new() | ||||
|         { | ||||
|             using (var conn = new SQLiteConnection(FilePath)) | ||||
|             { | ||||
|                 var found = conn.Find<T>(o.Id); | ||||
|                 if (found == null) | ||||
|                     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() { | ||||
|             using (var conn = new SQLiteConnection(FilePath)) { | ||||
|         internal T GetRandom<T>(Expression<Func<T, bool>> p) where T : IDataModel, new() | ||||
|         { | ||||
|             using (var conn = new SQLiteConnection(FilePath)) | ||||
|             { | ||||
|                 var r = new Random(); | ||||
|                 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 = @" | ||||
| CREATE TRIGGER IF NOT EXISTS OnTransactionAdded | ||||
| AFTER INSERT ON CurrencyTransaction | ||||
| BEGIN | ||||
| 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,  | ||||
|             COALESCE((SELECT Value+New.Value FROM CurrencyState Where UserId = NEW.UserId),NEW.Value),   | ||||
|             NEW.DateAdded); | ||||
|   | ||||
| @@ -4,7 +4,7 @@ namespace NadekoBot.Classes | ||||
| { | ||||
|     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) | ||||
|                 return; | ||||
| @@ -17,6 +17,10 @@ namespace NadekoBot.Classes | ||||
|                     Value = amount, | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             if (silent) | ||||
|                 return; | ||||
|  | ||||
|             var flows = ""; | ||||
|             for (var i = 0; i < amount; i++) | ||||
|             { | ||||
| @@ -25,19 +29,23 @@ namespace NadekoBot.Classes | ||||
|             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) | ||||
|                 return; | ||||
|             await Task.Run(() => | ||||
|                 return false; | ||||
|             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, | ||||
|                     Value = -amount, | ||||
|                 }); | ||||
|                 Reason = reason, | ||||
|                 UserId = (long)u.Id, | ||||
|                 Value = -amount, | ||||
|             }); | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -94,7 +94,7 @@ namespace NadekoBot.Classes.JSONModels | ||||
|         public string Gambling { get; set; } = "$"; | ||||
|         public string Permissions { get; set; } = ";"; | ||||
|         public string Programming { get; set; } = "%"; | ||||
|         public string Pokemon { get; set; } = "poke"; | ||||
|         public string Pokemon { get; set; } = ">"; | ||||
|     } | ||||
|  | ||||
|     public static class ConfigHandler | ||||
|   | ||||
| @@ -5,15 +5,18 @@ using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Threading; | ||||
| using System.Threading.Tasks; | ||||
| namespace NadekoBot.Classes.Music { | ||||
| namespace NadekoBot.Classes.Music | ||||
| { | ||||
|  | ||||
|     public enum MusicType { | ||||
|     public enum MusicType | ||||
|     { | ||||
|         Radio, | ||||
|         Normal, | ||||
|         Local | ||||
|     } | ||||
|  | ||||
|     public enum StreamState { | ||||
|     public enum StreamState | ||||
|     { | ||||
|         Resolving, | ||||
|         Queued, | ||||
|         Buffering, //not using it atm | ||||
| @@ -21,7 +24,8 @@ namespace NadekoBot.Classes.Music { | ||||
|         Completed | ||||
|     } | ||||
|  | ||||
|     public class MusicPlayer { | ||||
|     public class MusicPlayer | ||||
|     { | ||||
|         public static int MaximumPlaylistSize => 50; | ||||
|  | ||||
|         private IAudioClient audioClient { get; set; } | ||||
| @@ -44,8 +48,11 @@ namespace NadekoBot.Classes.Music { | ||||
|         public Channel PlaybackVoiceChannel { get; private set; } | ||||
|  | ||||
|         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) | ||||
|                 throw new ArgumentNullException(nameof(startingVoiceChannel)); | ||||
|             if (startingVoiceChannel.Type != ChannelType.Voice) | ||||
| @@ -56,27 +63,42 @@ namespace NadekoBot.Classes.Music { | ||||
|             SongCancelSource = new CancellationTokenSource(); | ||||
|             cancelToken = SongCancelSource.Token; | ||||
|  | ||||
|             Task.Run(async () => { | ||||
|                 while (!Destroyed) { | ||||
|                     try { | ||||
|                         if(audioClient?.State != ConnectionState.Connected) | ||||
|             Task.Run(async () => | ||||
|             { | ||||
|                 while (!Destroyed) | ||||
|                 { | ||||
|                     try | ||||
|                     { | ||||
|                         if (audioClient?.State != ConnectionState.Connected) | ||||
|                             audioClient = await PlaybackVoiceChannel.JoinAudio(); | ||||
|                     } catch { | ||||
|                     } | ||||
|                     catch | ||||
|                     { | ||||
|                         await Task.Delay(1000); | ||||
|                         continue; | ||||
|                     } | ||||
|                     CurrentSong = GetNextSong(); | ||||
|                     var curSong = CurrentSong; | ||||
|                     if (curSong != null) { | ||||
|                         try { | ||||
|                     if (curSong != null) | ||||
|                     { | ||||
|                         try | ||||
|                         { | ||||
|                             OnStarted(this, curSong); | ||||
|                             await curSong.Play(audioClient, cancelToken); | ||||
|                         } catch (OperationCanceledException) { | ||||
|                         } | ||||
|                         catch (OperationCanceledException) | ||||
|                         { | ||||
|                             Console.WriteLine("Song canceled"); | ||||
|                         } catch (Exception ex) { | ||||
|                         } | ||||
|                         catch (Exception ex) | ||||
|                         { | ||||
|                             Console.WriteLine($"Exception in PlaySong: {ex}"); | ||||
|                         } | ||||
|                         OnCompleted(this, curSong); | ||||
|                         if (RepeatSong) | ||||
|                             playlist.Insert(0, curSong); | ||||
|                         else if (RepeatPlaylist) | ||||
|                             playlist.Insert(playlist.Count, curSong); | ||||
|                         SongCancelSource = new CancellationTokenSource(); | ||||
|                         cancelToken = SongCancelSource.Token; | ||||
|                     } | ||||
| @@ -85,17 +107,22 @@ namespace NadekoBot.Classes.Music { | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         public void Next() { | ||||
|             lock (playlistLock) { | ||||
|                 if (!SongCancelSource.IsCancellationRequested) { | ||||
|         public void Next() | ||||
|         { | ||||
|             lock (playlistLock) | ||||
|             { | ||||
|                 if (!SongCancelSource.IsCancellationRequested) | ||||
|                 { | ||||
|                     Paused = false; | ||||
|                     SongCancelSource.Cancel(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void Stop() { | ||||
|             lock (playlistLock) { | ||||
|         public void Stop() | ||||
|         { | ||||
|             lock (playlistLock) | ||||
|             { | ||||
|                 playlist.Clear(); | ||||
|                 CurrentSong = null; | ||||
|                 if (!SongCancelSource.IsCancellationRequested) | ||||
| @@ -105,13 +132,16 @@ namespace NadekoBot.Classes.Music { | ||||
|  | ||||
|         public void TogglePause() => Paused = !Paused; | ||||
|  | ||||
|         public void Shuffle() { | ||||
|             lock (playlistLock) { | ||||
|         public void Shuffle() | ||||
|         { | ||||
|             lock (playlistLock) | ||||
|             { | ||||
|                 playlist.Shuffle(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public int SetVolume(int volume) { | ||||
|         public int SetVolume(int volume) | ||||
|         { | ||||
|             if (volume < 0) | ||||
|                 volume = 0; | ||||
|             if (volume > 150) | ||||
| @@ -121,8 +151,10 @@ namespace NadekoBot.Classes.Music { | ||||
|             return volume; | ||||
|         } | ||||
|  | ||||
|         private Song GetNextSong() { | ||||
|             lock (playlistLock) { | ||||
|         private Song GetNextSong() | ||||
|         { | ||||
|             lock (playlistLock) | ||||
|             { | ||||
|                 if (playlist.Count == 0) | ||||
|                     return null; | ||||
|                 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) | ||||
|                 throw new ArgumentNullException(nameof(s)); | ||||
|             lock (playlistLock) { | ||||
|             lock (playlistLock) | ||||
|             { | ||||
|                 playlist.Add(s); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void RemoveSong(Song s) { | ||||
|         public void RemoveSong(Song s) | ||||
|         { | ||||
|             if (s == null) | ||||
|                 throw new ArgumentNullException(nameof(s)); | ||||
|             lock (playlistLock) { | ||||
|             lock (playlistLock) | ||||
|             { | ||||
|                 playlist.Remove(s); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void RemoveSongAt(int index) { | ||||
|             lock (playlistLock) { | ||||
|         public void RemoveSongAt(int index) | ||||
|         { | ||||
|             lock (playlistLock) | ||||
|             { | ||||
|                 if (index < 0 || index >= playlist.Count) | ||||
|                     throw new ArgumentException("Invalid index"); | ||||
|                 playlist.RemoveAt(index); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         internal Task MoveToVoiceChannel(Channel voiceChannel) { | ||||
|         internal Task MoveToVoiceChannel(Channel voiceChannel) | ||||
|         { | ||||
|             if (audioClient?.State != ConnectionState.Connected) | ||||
|                 throw new InvalidOperationException("Can't move while bot is not connected to voice channel."); | ||||
|             PlaybackVoiceChannel = voiceChannel; | ||||
|             return PlaybackVoiceChannel.JoinAudio(); | ||||
|         } | ||||
|  | ||||
|         internal void ClearQueue() { | ||||
|             lock (playlistLock) { | ||||
|         internal void ClearQueue() | ||||
|         { | ||||
|             lock (playlistLock) | ||||
|             { | ||||
|                 playlist.Clear(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void Destroy() { | ||||
|             lock (playlistLock) { | ||||
|         public void Destroy() | ||||
|         { | ||||
|             lock (playlistLock) | ||||
|             { | ||||
|                 playlist.Clear(); | ||||
|                 Destroyed = true; | ||||
|                 CurrentSong = null; | ||||
| @@ -178,5 +221,9 @@ namespace NadekoBot.Classes.Music { | ||||
|                 audioClient.Disconnect(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         internal bool ToggleRepeatSong() => this.RepeatSong = !this.RepeatSong; | ||||
|  | ||||
|         internal bool ToggleRepeatPlaylist() => this.RepeatPlaylist = !this.RepeatPlaylist; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,16 +1,19 @@ | ||||
| using Discord; | ||||
| using Discord.Commands; | ||||
| using NadekoBot.Extensions; | ||||
| using NadekoBot.Modules; | ||||
| using NadekoBot.Modules.Administration.Commands; | ||||
| using System; | ||||
| using System.Diagnostics; | ||||
| using System.Linq; | ||||
| using NadekoBot.Extensions; | ||||
| using System.Threading.Tasks; | ||||
| using System.Reflection; | ||||
| using System.Threading.Tasks; | ||||
| using System.Timers; | ||||
| using NadekoBot.Modules; | ||||
|  | ||||
| namespace NadekoBot { | ||||
|     public class NadekoStats { | ||||
| namespace NadekoBot | ||||
| { | ||||
|     public class NadekoStats | ||||
|     { | ||||
|         public static NadekoStats Instance { get; } = new NadekoStats(); | ||||
|  | ||||
|         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 VoiceChannelsCount { get; private set; } = 0; | ||||
|  | ||||
|         private readonly Timer commandLogTimer = new Timer() {Interval = 10000}; | ||||
|         private readonly Timer commandLogTimer = new Timer() { Interval = 10000 }; | ||||
|  | ||||
|         static NadekoStats() { } | ||||
|  | ||||
|         private NadekoStats() { | ||||
|         private NadekoStats() | ||||
|         { | ||||
|             var commandService = NadekoBot.Client.GetService<CommandService>(); | ||||
|  | ||||
|             statsStopwatch.Start(); | ||||
| @@ -43,52 +47,66 @@ namespace NadekoBot { | ||||
|             TextChannelsCount = channelsArray.Count(c => c.Type == ChannelType.Text); | ||||
|             VoiceChannelsCount = channelsArray.Count() - TextChannelsCount; | ||||
|  | ||||
|             NadekoBot.Client.JoinedServer += (s, e) => { | ||||
|                 try { | ||||
|             NadekoBot.Client.JoinedServer += (s, e) => | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     ServerCount++; | ||||
|                     TextChannelsCount += e.Server.TextChannels.Count(); | ||||
|                     VoiceChannelsCount += e.Server.VoiceChannels.Count(); | ||||
|                 } catch { } | ||||
|                 } | ||||
|                 catch { } | ||||
|             }; | ||||
|             NadekoBot.Client.LeftServer += (s, e) => { | ||||
|                 try { | ||||
|             NadekoBot.Client.LeftServer += (s, e) => | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     ServerCount--; | ||||
|                     TextChannelsCount -= e.Server.TextChannels.Count(); | ||||
|                     VoiceChannelsCount -= e.Server.VoiceChannels.Count(); | ||||
|                 } catch { } | ||||
|                 } | ||||
|                 catch { } | ||||
|             }; | ||||
|             NadekoBot.Client.ChannelCreated += (s, e) => { | ||||
|                 try { | ||||
|             NadekoBot.Client.ChannelCreated += (s, e) => | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     if (e.Channel.IsPrivate) | ||||
|                         return; | ||||
|                     if (e.Channel.Type == ChannelType.Text) | ||||
|                         TextChannelsCount++; | ||||
|                     else if (e.Channel.Type == ChannelType.Voice) | ||||
|                         VoiceChannelsCount++; | ||||
|                 } catch { } | ||||
|                 } | ||||
|                 catch { } | ||||
|             }; | ||||
|             NadekoBot.Client.ChannelDestroyed += (s, e) => { | ||||
|                 try { | ||||
|             NadekoBot.Client.ChannelDestroyed += (s, e) => | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     if (e.Channel.IsPrivate) | ||||
|                         return; | ||||
|                     if (e.Channel.Type == ChannelType.Text) | ||||
|                         VoiceChannelsCount++; | ||||
|                     else if (e.Channel.Type == ChannelType.Voice) | ||||
|                         VoiceChannelsCount--; | ||||
|                 } catch { } | ||||
|                 } | ||||
|                 catch { } | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         public TimeSpan GetUptime() => | ||||
|             DateTime.Now - Process.GetCurrentProcess().StartTime; | ||||
|  | ||||
|         public string GetUptimeString() { | ||||
|         public string GetUptimeString() | ||||
|         { | ||||
|             var time = (DateTime.Now - Process.GetCurrentProcess().StartTime); | ||||
|             return time.Days + " days, " + time.Hours + " hours, and " + time.Minutes + " minutes."; | ||||
|         } | ||||
|  | ||||
|         public Task LoadStats() => | ||||
|             Task.Run(() => { | ||||
|             Task.Run(() => | ||||
|             { | ||||
|                 var songs = Music.MusicPlayers.Count(mp => mp.Value.CurrentSong != null); | ||||
|                 var sb = new System.Text.StringBuilder(); | ||||
|                 sb.AppendLine("`Author: Kwoth` `Library: Discord.Net`"); | ||||
| @@ -102,7 +120,7 @@ namespace NadekoBot { | ||||
|                 sb.AppendLine($" | VoiceChannels: {VoiceChannelsCount}`"); | ||||
|                 sb.AppendLine($"`Commands Ran this session: {commandsRan}`"); | ||||
|                 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) + | ||||
|                               $"{Music.MusicPlayers.Sum(kvp => kvp.Value.Playlist.Count)} queued.`"); | ||||
|                 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 async Task<string> GetStats() { | ||||
|         public async Task<string> GetStats() | ||||
|         { | ||||
|             if (statsStopwatch.Elapsed.Seconds < 4 && | ||||
|                 !string.IsNullOrWhiteSpace(statsCache)) return statsCache; | ||||
|             await LoadStats(); | ||||
| @@ -119,35 +138,45 @@ namespace NadekoBot { | ||||
|             return statsCache; | ||||
|         } | ||||
|  | ||||
|         private async Task StartCollecting() { | ||||
|             while (true) { | ||||
|         private async Task StartCollecting() | ||||
|         { | ||||
|             while (true) | ||||
|             { | ||||
|                 await Task.Delay(new TimeSpan(0, 30, 0)); | ||||
|                 try { | ||||
|                 try | ||||
|                 { | ||||
|                     var onlineUsers = await Task.Run(() => NadekoBot.Client.Servers.Sum(x => x.Users.Count())); | ||||
|                     var realOnlineUsers = await Task.Run(() => NadekoBot.Client.Servers | ||||
|                                                                         .Sum(x => x.Users.Count(u => u.Status == UserStatus.Online))); | ||||
|                     var connectedServers = NadekoBot.Client.Servers.Count(); | ||||
|  | ||||
|                     Classes.DbHandler.Instance.InsertData(new Classes._DataModels.Stats { | ||||
|                     Classes.DbHandler.Instance.InsertData(new Classes._DataModels.Stats | ||||
|                     { | ||||
|                         OnlineUsers = onlineUsers, | ||||
|                         RealOnlineUsers = realOnlineUsers, | ||||
|                         Uptime = GetUptime(), | ||||
|                         ConnectedServers = connectedServers, | ||||
|                         DateAdded = DateTime.Now | ||||
|                     }); | ||||
|                 } catch { | ||||
|                 } | ||||
|                 catch | ||||
|                 { | ||||
|                     Console.WriteLine("DB Exception in stats collecting."); | ||||
|                     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}"); | ||||
|             await Task.Run(() => { | ||||
|                 try { | ||||
|             await Task.Run(() => | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     commandsRan++; | ||||
|                     Classes.DbHandler.Instance.InsertData(new Classes._DataModels.Command { | ||||
|                     Classes.DbHandler.Instance.InsertData(new Classes._DataModels.Command | ||||
|                     { | ||||
|                         ServerId = (long)e.Server.Id, | ||||
|                         ServerName = e.Server.Name, | ||||
|                         ChannelId = (long)e.Channel.Id, | ||||
| @@ -157,7 +186,9 @@ namespace NadekoBot { | ||||
|                         CommandName = e.Command.Text, | ||||
|                         DateAdded = DateTime.Now | ||||
|                     }); | ||||
|                 } catch { | ||||
|                 } | ||||
|                 catch | ||||
|                 { | ||||
|                     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.Generic; | ||||
| using System.Collections.ObjectModel; | ||||
| using System.ComponentModel; | ||||
| using System.IO; | ||||
| using System.Runtime.CompilerServices; | ||||
| using NadekoBot.Classes.JSONModels; | ||||
| using Newtonsoft.Json; | ||||
|  | ||||
| namespace NadekoBot.Classes { | ||||
|     internal class SpecificConfigurations { | ||||
| namespace NadekoBot.Classes | ||||
| { | ||||
|     internal class SpecificConfigurations | ||||
|     { | ||||
|         public static SpecificConfigurations Default { get; } = new SpecificConfigurations(); | ||||
|         public static bool Instantiated { get; private set; } | ||||
|  | ||||
| @@ -17,14 +18,19 @@ namespace NadekoBot.Classes { | ||||
|  | ||||
|         static SpecificConfigurations() { } | ||||
|  | ||||
|         private SpecificConfigurations() { | ||||
|         private SpecificConfigurations() | ||||
|         { | ||||
|  | ||||
|             if (File.Exists(filePath)) { | ||||
|                 try { | ||||
|             if (File.Exists(filePath)) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     configs = JsonConvert | ||||
|                         .DeserializeObject<ConcurrentDictionary<ulong, ServerSpecificConfig>>( | ||||
|                             File.ReadAllText(filePath)); | ||||
|                 } catch (Exception ex) { | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
|                 { | ||||
|                     Console.WriteLine($"Deserialization failing: {ex}"); | ||||
|                 } | ||||
|             } | ||||
| @@ -42,14 +48,17 @@ namespace NadekoBot.Classes { | ||||
|  | ||||
|         private readonly object saveLock = new object(); | ||||
|  | ||||
|         public void Save() { | ||||
|             lock (saveLock) { | ||||
|         public void Save() | ||||
|         { | ||||
|             lock (saveLock) | ||||
|             { | ||||
|                 File.WriteAllText(filePath, JsonConvert.SerializeObject(configs, Formatting.Indented)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     internal class ServerSpecificConfig : INotifyPropertyChanged { | ||||
|     internal class ServerSpecificConfig : INotifyPropertyChanged | ||||
|     { | ||||
|         [JsonProperty("VoicePlusTextEnabled")] | ||||
|         private bool voicePlusTextEnabled; | ||||
|         [JsonIgnore] | ||||
| @@ -78,7 +87,8 @@ namespace NadekoBot.Classes { | ||||
|             set { | ||||
|                 listOfSelfAssignableRoles = value; | ||||
|                 if (value != null) | ||||
|                     listOfSelfAssignableRoles.CollectionChanged += (s, e) => { | ||||
|                     listOfSelfAssignableRoles.CollectionChanged += (s, e) => | ||||
|                     { | ||||
|                         if (!SpecificConfigurations.Instantiated) return; | ||||
|                         OnPropertyChanged(); | ||||
|                     }; | ||||
| @@ -92,34 +102,39 @@ namespace NadekoBot.Classes { | ||||
|             set { | ||||
|                 observingStreams = value; | ||||
|                 if (value != null) | ||||
|                     observingStreams.CollectionChanged += (s, e) => { | ||||
|                     observingStreams.CollectionChanged += (s, e) => | ||||
|                     { | ||||
|                         if (!SpecificConfigurations.Instantiated) return; | ||||
|                         OnPropertyChanged(); | ||||
|                     }; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public ServerSpecificConfig() { | ||||
|         public ServerSpecificConfig() | ||||
|         { | ||||
|             ListOfSelfAssignableRoles = new ObservableCollection<ulong>(); | ||||
|             ObservingStreams = new ObservableCollection<StreamNotificationConfig>(); | ||||
|         } | ||||
|  | ||||
|         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"); | ||||
|             PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public class StreamNotificationConfig : IEquatable<StreamNotificationConfig> { | ||||
|     public class StreamNotificationConfig : IEquatable<StreamNotificationConfig> | ||||
|     { | ||||
|         public string Username { get; set; } | ||||
|         public StreamType Type { get; set; } | ||||
|         public ulong ServerId { get; set; } | ||||
|         public ulong ChannelId { get; set; } | ||||
|         public bool LastStatus { get; set; } | ||||
|  | ||||
|         public enum StreamType { | ||||
|         public enum StreamType | ||||
|         { | ||||
|             Twitch, | ||||
|             Beam, | ||||
|             Hitbox, | ||||
| @@ -131,7 +146,8 @@ namespace NadekoBot.Classes { | ||||
|             this.Type == other.Type && | ||||
|             this.ServerId == other.ServerId; | ||||
|  | ||||
|         public override int GetHashCode() { | ||||
|         public override int GetHashCode() | ||||
|         { | ||||
|             return (int)((int)ServerId + Username.Length + (int)Type); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -6,7 +6,7 @@ using System.Threading.Tasks; | ||||
|  | ||||
| namespace NadekoBot.Classes._DataModels | ||||
| { | ||||
|     class userPokeTypes : IDataModel | ||||
|     class UserPokeTypes : IDataModel | ||||
|     { | ||||
|         public long UserId { 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 System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Text.RegularExpressions; | ||||
| using System.Threading.Tasks; | ||||
| using Discord; | ||||
| using Discord; | ||||
| using Discord.Commands; | ||||
| using NadekoBot.Classes; | ||||
| using NadekoBot.Classes.Permissions; | ||||
| using NadekoBot.Modules; | ||||
| using System; | ||||
| using System.Linq; | ||||
| using ServerPermissions = NadekoBot.Classes.Permissions.ServerPermissions; | ||||
|  | ||||
| namespace NadekoBot.Commands { | ||||
|     internal class FilterWords : DiscordCommand { | ||||
|         public FilterWords(DiscordModule module) : base(module) { | ||||
|             NadekoBot.Client.MessageReceived += async (sender, args) => { | ||||
| namespace NadekoBot.Commands | ||||
| { | ||||
|     internal class FilterWords : DiscordCommand | ||||
|     { | ||||
|         public FilterWords(DiscordModule module) : base(module) | ||||
|         { | ||||
|             NadekoBot.Client.MessageReceived += async (sender, args) => | ||||
|             { | ||||
|                 if (args.Channel.IsPrivate || args.User.Id == NadekoBot.Client.CurrentUser.Id) return; | ||||
|                 try { | ||||
|                 try | ||||
|                 { | ||||
|                     ServerPermissions serverPerms; | ||||
|                     if (!IsChannelOrServerFiltering(args.Channel, out serverPerms)) return; | ||||
|  | ||||
|                     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(); | ||||
|                         IncidentsHandler.Add(args.Server.Id, $"User [{args.User.Name}/{args.User.Id}] posted " + | ||||
|                                                              $"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 " + | ||||
|                                                            $"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 (serverPerms.Permissions.FilterWords) | ||||
| @@ -44,7 +48,8 @@ namespace NadekoBot.Commands { | ||||
|             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") | ||||
|                 .Alias(Module.Prefix + "channelfilterwords") | ||||
|                 .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") | ||||
|                 .Parameter("bool") | ||||
|                 .Parameter("channel", ParameterType.Optional) | ||||
|                 .Do(async e => { | ||||
|                     try { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     try | ||||
|                     { | ||||
|                         var state = PermissionHelper.ValidateBool(e.GetArg("bool")); | ||||
|                         var chanStr = e.GetArg("channel")?.ToLowerInvariant().Trim(); | ||||
|  | ||||
|                         if (chanStr != "all") { | ||||
|                         if (chanStr != "all") | ||||
|                         { | ||||
|                             var chan = string.IsNullOrWhiteSpace(chanStr) | ||||
|                                 ? e.Channel | ||||
|                                 : PermissionHelper.ValidateChannel(e.Server, chanStr); | ||||
| @@ -67,11 +75,14 @@ namespace NadekoBot.Commands { | ||||
|                         } | ||||
|                         //all channels | ||||
|  | ||||
|                         foreach (var curChannel in e.Server.TextChannels) { | ||||
|                         foreach (var curChannel in e.Server.TextChannels) | ||||
|                         { | ||||
|                             PermissionsHandler.SetChannelWordPermission(curChannel, state); | ||||
|                         } | ||||
|                         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}"); | ||||
|                     } | ||||
|                 }); | ||||
| @@ -81,15 +92,19 @@ namespace NadekoBot.Commands { | ||||
|                .Description("Adds a new word to the list of filtered words" + | ||||
|                             "\n**Usage**: ;aw poop") | ||||
|                .Parameter("word", ParameterType.Unparsed) | ||||
|                .Do(async e => { | ||||
|                    try { | ||||
|                .Do(async e => | ||||
|                { | ||||
|                    try | ||||
|                    { | ||||
|                        var word = e.GetArg("word"); | ||||
|                        if (string.IsNullOrWhiteSpace(word)) | ||||
|                            return; | ||||
|                        PermissionsHandler.AddFilteredWord(e.Server, word.ToLowerInvariant().Trim()); | ||||
|                        await e.Channel.SendMessage($"Successfully added new filtered word."); | ||||
|  | ||||
|                    } catch (Exception ex) { | ||||
|                    } | ||||
|                    catch (Exception ex) | ||||
|                    { | ||||
|                        await e.Channel.SendMessage($"💢 Error: {ex.Message}"); | ||||
|                    } | ||||
|                }); | ||||
| @@ -99,15 +114,19 @@ namespace NadekoBot.Commands { | ||||
|                .Description("Removes the word from the list of filtered words" + | ||||
|                             "\n**Usage**: ;rw poop") | ||||
|                .Parameter("word", ParameterType.Unparsed) | ||||
|                .Do(async e => { | ||||
|                    try { | ||||
|                .Do(async e => | ||||
|                { | ||||
|                    try | ||||
|                    { | ||||
|                        var word = e.GetArg("word"); | ||||
|                        if (string.IsNullOrWhiteSpace(word)) | ||||
|                            return; | ||||
|                        PermissionsHandler.RemoveFilteredWord(e.Server, word.ToLowerInvariant().Trim()); | ||||
|                        await e.Channel.SendMessage($"Successfully removed filtered word."); | ||||
|  | ||||
|                    } catch (Exception ex) { | ||||
|                    } | ||||
|                    catch (Exception ex) | ||||
|                    { | ||||
|                        await e.Channel.SendMessage($"💢 Error: {ex.Message}"); | ||||
|                    } | ||||
|                }); | ||||
| @@ -116,14 +135,18 @@ namespace NadekoBot.Commands { | ||||
|                .Alias(Module.Prefix + "listfilteredwords") | ||||
|                .Description("Shows a list of filtered words" + | ||||
|                             "\n**Usage**: ;lfw") | ||||
|                .Do(async e => { | ||||
|                    try { | ||||
|                .Do(async e => | ||||
|                { | ||||
|                    try | ||||
|                    { | ||||
|                        ServerPermissions serverPerms; | ||||
|                        if (!PermissionsHandler.PermissionsDict.TryGetValue(e.Server.Id, out serverPerms)) | ||||
|                            return; | ||||
|                        await e.Channel.SendMessage($"There are `{serverPerms.Words.Count}` filtered words.\n" + | ||||
|                            string.Join("\n", serverPerms.Words)); | ||||
|                    } catch (Exception ex) { | ||||
|                    } | ||||
|                    catch (Exception ex) | ||||
|                    { | ||||
|                        await e.Channel.SendMessage($"💢 Error: {ex.Message}"); | ||||
|                    } | ||||
|                }); | ||||
| @@ -132,13 +155,17 @@ namespace NadekoBot.Commands { | ||||
|                 .Alias(Module.Prefix + "serverfilterwords") | ||||
|                 .Description("Enables or disables automatic deleting of messages containing forbidden words on the server.\n**Usage**: ;sfi disable") | ||||
|                 .Parameter("bool") | ||||
|                 .Do(async e => { | ||||
|                     try { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     try | ||||
|                     { | ||||
|                         var state = PermissionHelper.ValidateBool(e.GetArg("bool")); | ||||
|                         PermissionsHandler.SetServerWordPermission(e.Server, state); | ||||
|                         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}"); | ||||
|                     } | ||||
|                 }); | ||||
|   | ||||
							
								
								
									
										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 Newtonsoft.Json.Linq; | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| using System.Timers; | ||||
| @@ -18,11 +19,15 @@ namespace NadekoBot.Commands | ||||
|         { | ||||
|             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) | ||||
|         { | ||||
|  | ||||
|             checkTimer.Elapsed += async (s, e) => | ||||
|             { | ||||
|                 cachedStatuses.Clear(); | ||||
|                 try | ||||
|                 { | ||||
|                     var streams = SpecificConfigurations.Default.AllConfigs.SelectMany(c => c.ObservingStreams); | ||||
| @@ -74,23 +79,39 @@ namespace NadekoBot.Commands | ||||
|             bool isLive; | ||||
|             string response; | ||||
|             JObject data; | ||||
|             Tuple<bool, string> result; | ||||
|             switch (stream.Type) | ||||
|             { | ||||
|                 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); | ||||
|                     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: | ||||
|                     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); | ||||
|                     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: | ||||
|                     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); | ||||
|                     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: | ||||
|                     break; | ||||
|             } | ||||
|   | ||||
| @@ -4,19 +4,19 @@ using Discord.Modules; | ||||
| using NadekoBot.Classes; | ||||
| using NadekoBot.Classes._DataModels; | ||||
| using NadekoBot.Classes.Permissions; | ||||
| using NadekoBot.Commands; | ||||
| using NadekoBot.Extensions; | ||||
| using NadekoBot.Modules.Administration.Commands; | ||||
| using Newtonsoft.Json.Linq; | ||||
| using System; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| 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 LogCommand(this)); | ||||
| @@ -26,6 +26,7 @@ namespace NadekoBot.Modules | ||||
|             commands.Add(new VoicePlusTextCommand(this)); | ||||
|             commands.Add(new CrossServerTextChannel(this)); | ||||
|             commands.Add(new SelfAssignedRolesCommand(this)); | ||||
|             commands.Add(new Remind(this)); | ||||
|         } | ||||
| 
 | ||||
|         public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Administration; | ||||
| @@ -227,6 +228,7 @@ namespace NadekoBot.Modules | ||||
|                                 try | ||||
|                                 { | ||||
|                                     await e.Server.Ban(usr); | ||||
| 
 | ||||
|                                     await e.Channel.SendMessage("Banned user " + usr.Name + " Id: " + usr.Id); | ||||
|                                 } | ||||
|                                 catch | ||||
| @@ -456,6 +458,7 @@ namespace NadekoBot.Modules | ||||
|                 cgb.CreateCommand(Prefix + "st").Alias(Prefix + "settopic") | ||||
|                     .Alias(Prefix + "topic") | ||||
|                     .Description("Sets a topic on the current channel.") | ||||
|                     .AddCheck(SimpleCheckers.ManageChannels()) | ||||
|                     .Parameter("topic", ParameterType.Unparsed) | ||||
|                     .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.Generic; | ||||
| using System.Linq; | ||||
| using Discord; | ||||
| using Discord.Commands; | ||||
| using NadekoBot.Classes.Permissions; | ||||
| using NadekoBot.Modules; | ||||
| 
 | ||||
| namespace NadekoBot.Commands { | ||||
|     class CrossServerTextChannel : DiscordCommand { | ||||
|         public CrossServerTextChannel(DiscordModule module) : base(module) { | ||||
|             NadekoBot.Client.MessageReceived += async (s, e) => { | ||||
|                 try { | ||||
| namespace NadekoBot.Modules.Administration.Commands | ||||
| { | ||||
|     class CrossServerTextChannel : DiscordCommand | ||||
|     { | ||||
|         public CrossServerTextChannel(DiscordModule module) : base(module) | ||||
|         { | ||||
|             NadekoBot.Client.MessageReceived += async (s, e) => | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     if (e.User.Id == NadekoBot.Client.CurrentUser.Id) return; | ||||
|                     foreach (var subscriber in Subscribers) { | ||||
|                     foreach (var subscriber in Subscribers) | ||||
|                     { | ||||
|                         var set = subscriber.Value; | ||||
|                         if (!set.Contains(e.Channel)) | ||||
|                             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)); | ||||
|                         } | ||||
|                     } | ||||
|                 } catch { } | ||||
|                 } | ||||
|                 catch { } | ||||
|             }; | ||||
|             NadekoBot.Client.MessageUpdated += async (s, e) => { | ||||
|                 try { | ||||
|             NadekoBot.Client.MessageUpdated += async (s, e) => | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     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; | ||||
|                         if (!set.Contains(e.Channel)) | ||||
|                             continue; | ||||
|                         foreach (var chan in set.Except(new[] { e.Channel })) { | ||||
|                         foreach (var chan in set.Except(new[] { e.Channel })) | ||||
|                         { | ||||
|                             var msg = chan.Messages | ||||
|                                 .FirstOrDefault(m => | ||||
|                                     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>>(); | ||||
| 
 | ||||
|         internal override void Init(CommandGroupBuilder cgb) { | ||||
|         internal override void Init(CommandGroupBuilder cgb) | ||||
|         { | ||||
|             cgb.CreateCommand(Module.Prefix + "scsc") | ||||
|                 .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") | ||||
|                 .AddCheck(SimpleCheckers.OwnerOnly()) | ||||
|                 .Do(async e => { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     var token = new Random().Next(); | ||||
|                     var set = new HashSet<Channel>(); | ||||
|                     if (Subscribers.TryAdd(token, set)) { | ||||
|                     if (Subscribers.TryAdd(token, set)) | ||||
|                     { | ||||
|                         set.Add(e.Channel); | ||||
|                         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.") | ||||
|                 .Parameter("token") | ||||
|                 .AddCheck(SimpleCheckers.ManageServer()) | ||||
|                 .Do(async e => { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     int token; | ||||
|                     if (!int.TryParse(e.GetArg("token"), out token)) | ||||
|                         return; | ||||
| @@ -80,8 +97,10 @@ namespace NadekoBot.Commands { | ||||
|             cgb.CreateCommand(Module.Prefix + "lcsc") | ||||
|                 .Description("Leaves Cross server channel instance from this channel") | ||||
|                 .AddCheck(SimpleCheckers.ManageServer()) | ||||
|                 .Do(async e => { | ||||
|                     foreach (var subscriber in Subscribers) { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     foreach (var subscriber in Subscribers) | ||||
|                     { | ||||
|                         subscriber.Value.Remove(e.Channel); | ||||
|                     } | ||||
|                     await e.Channel.SendMessage(":ok:"); | ||||
| @@ -2,13 +2,13 @@ | ||||
| using Discord.Commands; | ||||
| using NadekoBot.Classes; | ||||
| using NadekoBot.Classes.Permissions; | ||||
| using NadekoBot.Modules; | ||||
| using NadekoBot.Commands; | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| 
 | ||||
| namespace NadekoBot.Commands | ||||
| namespace NadekoBot.Modules.Administration.Commands | ||||
| { | ||||
|     internal class LogCommand : DiscordCommand | ||||
|     { | ||||
| @@ -1,15 +1,18 @@ | ||||
| using System; | ||||
| using System.Timers; | ||||
| using System.Collections.Concurrent; | ||||
| using Discord; | ||||
| using NadekoBot.Classes.Permissions; | ||||
| using Discord; | ||||
| 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 { | ||||
|     class MessageRepeater : DiscordCommand { | ||||
| namespace NadekoBot.Modules.Administration.Commands | ||||
| { | ||||
|     class MessageRepeater : DiscordCommand | ||||
|     { | ||||
|         private readonly ConcurrentDictionary<Server, Repeater> repeaters = new ConcurrentDictionary<Server, Repeater>(); | ||||
|         private class Repeater { | ||||
|         private class Repeater | ||||
|         { | ||||
|             [Newtonsoft.Json.JsonIgnore] | ||||
|             public Timer MessageTimer { get; set; } | ||||
|             [Newtonsoft.Json.JsonIgnore] | ||||
| @@ -20,21 +23,27 @@ namespace NadekoBot.Commands { | ||||
|             public string RepeatingMessage { get; set; } | ||||
|             public int Interval { get; set; } | ||||
| 
 | ||||
|             public Repeater Start() { | ||||
|             public Repeater Start() | ||||
|             { | ||||
|                 MessageTimer = new Timer { Interval = Interval }; | ||||
|                 MessageTimer.Elapsed += async (s, e) => { | ||||
|                 MessageTimer.Elapsed += async (s, e) => | ||||
|                 { | ||||
|                     var ch = RepeatingChannel; | ||||
|                     var msg = RepeatingMessage; | ||||
|                     if (ch != null && !string.IsNullOrWhiteSpace(msg)) { | ||||
|                         try { | ||||
|                     if (ch != null && !string.IsNullOrWhiteSpace(msg)) | ||||
|                     { | ||||
|                         try | ||||
|                         { | ||||
|                             await ch.SendMessage(msg); | ||||
|                         } catch { } | ||||
|                         } | ||||
|                         catch { } | ||||
|                     } | ||||
|                 }; | ||||
|                 return this; | ||||
|             } | ||||
|         } | ||||
|         internal override void Init(CommandGroupBuilder cgb) { | ||||
|         internal override void Init(CommandGroupBuilder cgb) | ||||
|         { | ||||
| 
 | ||||
|             cgb.CreateCommand(Module.Prefix + "repeat") | ||||
|                 .Description("Repeat a message every X minutes. If no parameters are specified, " + | ||||
| @@ -42,12 +51,14 @@ namespace NadekoBot.Commands { | ||||
|                 .Parameter("minutes", ParameterType.Optional) | ||||
|                 .Parameter("msg", ParameterType.Unparsed) | ||||
|                 .AddCheck(SimpleCheckers.ManageMessages()) | ||||
|                 .Do(async e => { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     var minutesStr = e.GetArg("minutes"); | ||||
|                     var msg = e.GetArg("msg"); | ||||
| 
 | ||||
|                     // if both null, disable | ||||
|                     if (string.IsNullOrWhiteSpace(msg) && string.IsNullOrWhiteSpace(minutesStr)) { | ||||
|                     if (string.IsNullOrWhiteSpace(msg) && string.IsNullOrWhiteSpace(minutesStr)) | ||||
|                     { | ||||
|                         await e.Channel.SendMessage("Repeating disabled"); | ||||
|                         Repeater rep; | ||||
|                         if (repeaters.TryGetValue(e.Server, out rep)) | ||||
| @@ -55,14 +66,16 @@ namespace NadekoBot.Commands { | ||||
|                         return; | ||||
|                     } | ||||
|                     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"); | ||||
|                         return; | ||||
|                     } | ||||
| 
 | ||||
|                     var repeater = repeaters.GetOrAdd( | ||||
|                         e.Server, | ||||
|                         s => new Repeater { | ||||
|                         s => new Repeater | ||||
|                         { | ||||
|                             Interval = minutes * 60 * 1000, | ||||
|                             RepeatingChannel = e.Channel, | ||||
|                             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.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using Discord.Commands; | ||||
| using System.Timers; | ||||
| using NadekoBot.Classes.JSONModels; | ||||
| using NadekoBot.Modules; | ||||
| 
 | ||||
| namespace NadekoBot.Commands { | ||||
|     internal class PlayingRotate : DiscordCommand { | ||||
| namespace NadekoBot.Modules.Administration.Commands | ||||
| { | ||||
|     internal class PlayingRotate : DiscordCommand | ||||
|     { | ||||
|         private static readonly Timer timer = new Timer(12000); | ||||
| 
 | ||||
|         public static Dictionary<string, Func<string>> PlayingPlaceholders { get; } = | ||||
| @@ -34,16 +36,21 @@ namespace NadekoBot.Commands { | ||||
| 
 | ||||
|         private readonly object playingPlaceholderLock = new object(); | ||||
| 
 | ||||
|         public PlayingRotate(DiscordModule module) : base(module) { | ||||
|         public PlayingRotate(DiscordModule module) : base(module) | ||||
|         { | ||||
|             var i = -1; | ||||
|             timer.Elapsed += (s, e) => { | ||||
|                 try { | ||||
|             timer.Elapsed += (s, e) => | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     i++; | ||||
|                     var status = ""; | ||||
|                     lock (playingPlaceholderLock) { | ||||
|                     lock (playingPlaceholderLock) | ||||
|                     { | ||||
|                         if (PlayingPlaceholders.Count == 0) | ||||
|                             return; | ||||
|                         if (i >= PlayingPlaceholders.Count) { | ||||
|                         if (i >= PlayingPlaceholders.Count) | ||||
|                         { | ||||
|                             i = -1; | ||||
|                             return; | ||||
|                         } | ||||
| @@ -54,14 +61,17 @@ namespace NadekoBot.Commands { | ||||
|                     if (string.IsNullOrWhiteSpace(status)) | ||||
|                         return; | ||||
|                     Task.Run(() => { NadekoBot.Client.SetGame(status); }); | ||||
|                 } catch { } | ||||
|                 } | ||||
|                 catch { } | ||||
|             }; | ||||
| 
 | ||||
|             timer.Enabled = NadekoBot.Config.IsRotatingStatus; | ||||
|         } | ||||
| 
 | ||||
|         public Func<CommandEventArgs, Task> DoFunc() => async e => { | ||||
|             lock (playingPlaceholderLock) { | ||||
|         public Func<CommandEventArgs, Task> DoFunc() => async e => | ||||
|         { | ||||
|             lock (playingPlaceholderLock) | ||||
|             { | ||||
|                 if (timer.Enabled) | ||||
|                     timer.Stop(); | ||||
|                 else | ||||
| @@ -72,7 +82,8 @@ namespace NadekoBot.Commands { | ||||
|             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") | ||||
|                 .Alias(Module.Prefix + "ropl") | ||||
|                 .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)) | ||||
|                 .Parameter("text", ParameterType.Unparsed) | ||||
|                 .AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly()) | ||||
|                 .Do(async e => { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     var arg = e.GetArg("text"); | ||||
|                     if (string.IsNullOrWhiteSpace(arg)) | ||||
|                         return; | ||||
|                     lock (playingPlaceholderLock) { | ||||
|                     lock (playingPlaceholderLock) | ||||
|                     { | ||||
|                         NadekoBot.Config.RotatingStatuses.Add(arg); | ||||
|                         ConfigHandler.SaveConfig(); | ||||
|                     } | ||||
| @@ -100,12 +113,14 @@ namespace NadekoBot.Commands { | ||||
|                 .Alias(Module.Prefix + "lipl") | ||||
|                 .Description("Lists all playing statuses with their corresponding number.") | ||||
|                 .AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly()) | ||||
|                 .Do(async e => { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     if (NadekoBot.Config.RotatingStatuses.Count == 0) | ||||
|                         await e.Channel.SendMessage("`There are no playing strings. " + | ||||
|                                                     "Add some with .addplaying [text] command.`"); | ||||
|                     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]}"); | ||||
|                     } | ||||
|                     await e.Channel.SendMessage(sb.ToString()); | ||||
| @@ -116,11 +131,13 @@ namespace NadekoBot.Commands { | ||||
|                 .Description("Removes a playing string on a given number.") | ||||
|                 .Parameter("number", ParameterType.Required) | ||||
|                 .AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly()) | ||||
|                 .Do(async e => { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     var arg = e.GetArg("number"); | ||||
|                     int num; | ||||
|                     string str; | ||||
|                     lock (playingPlaceholderLock) { | ||||
|                     lock (playingPlaceholderLock) | ||||
|                     { | ||||
|                         if (!int.TryParse(arg.Trim(), out num) || num <= 0 || num > NadekoBot.Config.RotatingStatuses.Count) | ||||
|                             return; | ||||
|                         str = NadekoBot.Config.RotatingStatuses[num - 1]; | ||||
| @@ -1,28 +1,36 @@ | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| using Discord.Commands; | ||||
| using NadekoBot.Classes.Permissions; | ||||
| using NadekoBot.Modules; | ||||
| using NadekoBot.Commands; | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| 
 | ||||
| namespace NadekoBot.Commands { | ||||
|     internal class RatelimitCommand : DiscordCommand { | ||||
| namespace NadekoBot.Modules.Administration.Commands | ||||
| { | ||||
|     internal class RatelimitCommand : DiscordCommand | ||||
|     { | ||||
| 
 | ||||
|         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); | ||||
| 
 | ||||
|         public RatelimitCommand(DiscordModule module) : base(module) { | ||||
|             NadekoBot.Client.MessageReceived += async (s, e) => { | ||||
|         public RatelimitCommand(DiscordModule module) : base(module) | ||||
|         { | ||||
|             NadekoBot.Client.MessageReceived += async (s, e) => | ||||
|             { | ||||
|                 if (e.Channel.IsPrivate || e.User.Id == NadekoBot.Client.CurrentUser.Id) | ||||
|                     return; | ||||
|                 ConcurrentDictionary<ulong, DateTime> userTimePair; | ||||
|                 if (!RatelimitingChannels.TryGetValue(e.Channel.Id, out userTimePair)) return; | ||||
|                 DateTime lastMessageTime; | ||||
|                 if (userTimePair.TryGetValue(e.User.Id, out lastMessageTime)) { | ||||
|                     if (DateTime.Now - lastMessageTime < ratelimitTime) { | ||||
|                         try { | ||||
|                 if (userTimePair.TryGetValue(e.User.Id, out lastMessageTime)) | ||||
|                 { | ||||
|                     if (DateTime.Now - lastMessageTime < ratelimitTime) | ||||
|                     { | ||||
|                         try | ||||
|                         { | ||||
|                             await e.Message.Delete(); | ||||
|                         } catch { } | ||||
|                         } | ||||
|                         catch { } | ||||
|                         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") | ||||
|                 .Description("Toggles slow mode. When ON, users will be able to send only 1 message every 5 seconds.") | ||||
|                 .Parameter("minutes", ParameterType.Optional) | ||||
|                 .AddCheck(SimpleCheckers.ManageMessages()) | ||||
|                 .Do(async e => { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     //var minutesStr = e.GetArg("minutes"); | ||||
|                     //if (string.IsNullOrWhiteSpace(minutesStr)) { | ||||
|                     //    RatelimitingChannels.Remove(e.Channel.Id); | ||||
|                     //    return; | ||||
|                     //} | ||||
|                     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."); | ||||
|                         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. " + | ||||
|                                                     "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 System.Linq; | ||||
| using System.Text; | ||||
| using Discord.Commands; | ||||
| using Discord.Commands; | ||||
| using NadekoBot.Classes; | ||||
| using NadekoBot.Classes.Permissions; | ||||
| using NadekoBot.Modules; | ||||
| using NadekoBot.Commands; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| 
 | ||||
| namespace NadekoBot.Commands { | ||||
|     internal class SelfAssignedRolesCommand : DiscordCommand { | ||||
| namespace NadekoBot.Modules.Administration.Commands | ||||
| { | ||||
|     internal class SelfAssignedRolesCommand : DiscordCommand | ||||
|     { | ||||
|         public SelfAssignedRolesCommand(DiscordModule module) : base(module) { } | ||||
|         internal override void Init(CommandGroupBuilder cgb) { | ||||
|         internal override void Init(CommandGroupBuilder cgb) | ||||
|         { | ||||
|             cgb.CreateCommand(".asar") | ||||
|                 .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") | ||||
|                 .Parameter("roles", ParameterType.Multiple) | ||||
|                 .AddCheck(SimpleCheckers.CanManageRoles) | ||||
|                 .Do(async e => { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     var config = SpecificConfigurations.Default.Of(e.Server.Id); | ||||
|                     var msg = new StringBuilder(); | ||||
|                     foreach (var arg in e.Args) { | ||||
|                     foreach (var arg in e.Args) | ||||
|                     { | ||||
|                         var role = e.Server.FindRoles(arg.Trim()).FirstOrDefault(); | ||||
|                         if (role == null) | ||||
|                             msg.AppendLine($":anger:Role **{arg}** not found."); | ||||
|                         else { | ||||
|                             if (config.ListOfSelfAssignableRoles.Contains(role.Id)) { | ||||
|                             if (config.ListOfSelfAssignableRoles.Contains(role.Id)) | ||||
|                             { | ||||
|                                 msg.AppendLine($":anger:Role **{role.Name}** is already in the list."); | ||||
|                                 continue; | ||||
|                             } | ||||
| @@ -38,17 +44,20 @@ namespace NadekoBot.Commands { | ||||
|                 .Description("Removes a specified role from the list of self-assignable roles.") | ||||
|                 .Parameter("role", ParameterType.Unparsed) | ||||
|                 .AddCheck(SimpleCheckers.CanManageRoles) | ||||
|                 .Do(async e => { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     var roleName = e.GetArg("role")?.Trim(); | ||||
|                     if (string.IsNullOrWhiteSpace(roleName)) | ||||
|                         return; | ||||
|                     var role = e.Server.FindRoles(roleName).FirstOrDefault(); | ||||
|                     if (role == null) { | ||||
|                     if (role == null) | ||||
|                     { | ||||
|                         await e.Channel.SendMessage(":anger:That role does not exist."); | ||||
|                         return; | ||||
|                     } | ||||
|                     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."); | ||||
|                         return; | ||||
|                     } | ||||
| @@ -59,20 +68,25 @@ namespace NadekoBot.Commands { | ||||
|             cgb.CreateCommand(".lsar") | ||||
|                 .Description("Lits all self-assignable roles.") | ||||
|                 .Parameter("roles", ParameterType.Multiple) | ||||
|                 .Do(async e => { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     var config = SpecificConfigurations.Default.Of(e.Server.Id); | ||||
|                     var msg = new StringBuilder($"There are `{config.ListOfSelfAssignableRoles.Count}` self assignable roles:\n"); | ||||
|                     var toRemove = new HashSet<ulong>(); | ||||
|                     foreach (var roleId in config.ListOfSelfAssignableRoles) { | ||||
|                     foreach (var roleId in config.ListOfSelfAssignableRoles) | ||||
|                     { | ||||
|                         var role = e.Server.GetRole(roleId); | ||||
|                         if (role == null) { | ||||
|                         if (role == null) | ||||
|                         { | ||||
|                             msg.Append($"`{roleId} not found. Cleaned up.`, "); | ||||
|                             toRemove.Add(roleId); | ||||
|                         } else { | ||||
|                         } | ||||
|                         else { | ||||
|                             msg.Append($"**{role.Name}**, "); | ||||
|                         } | ||||
|                     } | ||||
|                     foreach (var id in toRemove) { | ||||
|                     foreach (var id in toRemove) | ||||
|                     { | ||||
|                         config.ListOfSelfAssignableRoles.Remove(id); | ||||
|                     } | ||||
|                     await e.Channel.SendMessage(msg.ToString()); | ||||
| @@ -83,21 +97,25 @@ namespace NadekoBot.Commands { | ||||
|                              "Role must be on a list of self-assignable roles." + | ||||
|                              "\n**Usage**: .iam Gamer") | ||||
|                 .Parameter("role", ParameterType.Unparsed) | ||||
|                 .Do(async e => { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     var roleName = e.GetArg("role")?.Trim(); | ||||
|                     if (string.IsNullOrWhiteSpace(roleName)) | ||||
|                         return; | ||||
|                     var role = e.Server.FindRoles(roleName).FirstOrDefault(); | ||||
|                     if (role == null) { | ||||
|                     if (role == null) | ||||
|                     { | ||||
|                         await e.Channel.SendMessage(":anger:That role does not exist."); | ||||
|                         return; | ||||
|                     } | ||||
|                     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."); | ||||
|                         return; | ||||
|                     } | ||||
|                     if (e.User.HasRole(role)) { | ||||
|                     if (e.User.HasRole(role)) | ||||
|                     { | ||||
|                         await e.Channel.SendMessage($":anger:You already have {role.Name} role."); | ||||
|                         return; | ||||
|                     } | ||||
| @@ -111,21 +129,25 @@ namespace NadekoBot.Commands { | ||||
|                              "Role must be on a list of self-assignable roles." + | ||||
|                              "\n**Usage**: .iamn Gamer") | ||||
|                 .Parameter("role", ParameterType.Unparsed) | ||||
|                 .Do(async e => { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     var roleName = e.GetArg("role")?.Trim(); | ||||
|                     if (string.IsNullOrWhiteSpace(roleName)) | ||||
|                         return; | ||||
|                     var role = e.Server.FindRoles(roleName).FirstOrDefault(); | ||||
|                     if (role == null) { | ||||
|                     if (role == null) | ||||
|                     { | ||||
|                         await e.Channel.SendMessage(":anger:That role does not exist."); | ||||
|                         return; | ||||
|                     } | ||||
|                     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."); | ||||
|                         return; | ||||
|                     } | ||||
|                     if (!e.User.HasRole(role)) { | ||||
|                     if (!e.User.HasRole(role)) | ||||
|                     { | ||||
|                         await e.Channel.SendMessage($":anger:You don't have {role.Name} role."); | ||||
|                         return; | ||||
|                     } | ||||
| @@ -1,12 +1,9 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| using Discord; | ||||
| using Discord.Commands; | ||||
| using System.Collections.Concurrent; | ||||
| using NadekoBot.Commands; | ||||
| using NadekoBot.Extensions; | ||||
| using Discord; | ||||
| using NadekoBot.Modules; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Linq; | ||||
| 
 | ||||
| /* Voltana's legacy | ||||
| public class AsyncLazy<T> : Lazy<Task<T>>  | ||||
| @@ -21,14 +18,17 @@ public class AsyncLazy<T> : Lazy<Task<T>> | ||||
| } | ||||
| */ | ||||
| 
 | ||||
| namespace NadekoBot.Commands { | ||||
|     internal class ServerGreetCommand : DiscordCommand { | ||||
| namespace NadekoBot.Modules.Administration.Commands | ||||
| { | ||||
|     internal class ServerGreetCommand : DiscordCommand | ||||
|     { | ||||
| 
 | ||||
|         public static ConcurrentDictionary<ulong, AnnounceControls> AnnouncementsDictionary; | ||||
| 
 | ||||
|         public static long Greeted = 0; | ||||
| 
 | ||||
|         public ServerGreetCommand(DiscordModule module) : base(module) { | ||||
|         public ServerGreetCommand(DiscordModule module) : base(module) | ||||
|         { | ||||
|             AnnouncementsDictionary = new ConcurrentDictionary<ulong, AnnounceControls>(); | ||||
| 
 | ||||
|             NadekoBot.Client.UserJoined += UserJoined; | ||||
| @@ -41,8 +41,10 @@ namespace NadekoBot.Commands { | ||||
|                 AnnouncementsDictionary.TryAdd((ulong)obj.ServerId, new AnnounceControls(obj)); | ||||
|         } | ||||
| 
 | ||||
|         private async void UserLeft(object sender, UserEventArgs e) { | ||||
|             try { | ||||
|         private async void UserLeft(object sender, UserEventArgs e) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 if (!AnnouncementsDictionary.ContainsKey(e.Server.Id) || | ||||
|                     !AnnouncementsDictionary[e.Server.Id].Bye) return; | ||||
| 
 | ||||
| @@ -52,9 +54,11 @@ namespace NadekoBot.Commands { | ||||
|                 if (string.IsNullOrEmpty(msg)) | ||||
|                     return; | ||||
| 
 | ||||
|                 if (controls.ByePM) { | ||||
|                 if (controls.ByePM) | ||||
|                 { | ||||
|                     Greeted++; | ||||
|                     try { | ||||
|                     try | ||||
|                     { | ||||
|                         await e.User.SendMessage($"`Farewell Message From {e.Server?.Name}`\n" + msg); | ||||
|                     } | ||||
|                     catch { } | ||||
| @@ -68,8 +72,10 @@ namespace NadekoBot.Commands { | ||||
|             catch { } | ||||
|         } | ||||
| 
 | ||||
|         private async void UserJoined(object sender, Discord.UserEventArgs e) { | ||||
|             try { | ||||
|         private async void UserJoined(object sender, Discord.UserEventArgs e) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 if (!AnnouncementsDictionary.ContainsKey(e.Server.Id) || | ||||
|                     !AnnouncementsDictionary[e.Server.Id].Greet) return; | ||||
| 
 | ||||
| @@ -79,7 +85,8 @@ namespace NadekoBot.Commands { | ||||
|                 var msg = controls.GreetText.Replace("%user%", e.User.Mention).Trim(); | ||||
|                 if (string.IsNullOrEmpty(msg)) | ||||
|                     return; | ||||
|                 if (controls.GreetPM) { | ||||
|                 if (controls.GreetPM) | ||||
|                 { | ||||
|                     Greeted++; | ||||
|                     await e.User.SendMessage($"`Welcome Message From {e.Server.Name}`\n" + msg); | ||||
|                 } | ||||
| @@ -92,7 +99,8 @@ namespace NadekoBot.Commands { | ||||
|             catch { } | ||||
|         } | ||||
| 
 | ||||
|         public class AnnounceControls { | ||||
|         public class AnnounceControls | ||||
|         { | ||||
|             private Classes._DataModels.Announcement _model { get; } | ||||
| 
 | ||||
|             public bool Greet { | ||||
| @@ -139,28 +147,36 @@ namespace NadekoBot.Commands { | ||||
|                 set { _model.ServerId = (long)value; } | ||||
|             } | ||||
| 
 | ||||
|             public AnnounceControls(Classes._DataModels.Announcement model) { | ||||
|             public AnnounceControls(Classes._DataModels.Announcement model) | ||||
|             { | ||||
|                 this._model = model; | ||||
|             } | ||||
| 
 | ||||
|             public AnnounceControls(ulong serverId) { | ||||
|             public AnnounceControls(ulong serverId) | ||||
|             { | ||||
|                 this._model = new Classes._DataModels.Announcement(); | ||||
|                 ServerId = serverId; | ||||
|             } | ||||
| 
 | ||||
|             internal bool ToggleBye(ulong id) { | ||||
|                 if (Bye) { | ||||
|             internal bool ToggleBye(ulong id) | ||||
|             { | ||||
|                 if (Bye) | ||||
|                 { | ||||
|                     return Bye = false; | ||||
|                 } else { | ||||
|                 } | ||||
|                 else { | ||||
|                     ByeChannel = id; | ||||
|                     return Bye = true; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             internal bool ToggleGreet(ulong id) { | ||||
|                 if (Greet) { | ||||
|             internal bool ToggleGreet(ulong id) | ||||
|             { | ||||
|                 if (Greet) | ||||
|                 { | ||||
|                     return Greet = false; | ||||
|                 } else { | ||||
|                 } | ||||
|                 else { | ||||
|                     GreetChannel = id; | ||||
|                     return Greet = true; | ||||
|                 } | ||||
| @@ -168,16 +184,19 @@ namespace NadekoBot.Commands { | ||||
|             internal bool ToggleGreetPM() => GreetPM = !GreetPM; | ||||
|             internal bool ToggleByePM() => ByePM = !ByePM; | ||||
| 
 | ||||
|             private void Save() { | ||||
|             private void Save() | ||||
|             { | ||||
|                 Classes.DbHandler.Instance.Save(_model); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         internal override void Init(CommandGroupBuilder cgb) { | ||||
|         internal override void Init(CommandGroupBuilder cgb) | ||||
|         { | ||||
| 
 | ||||
|             cgb.CreateCommand(Module.Prefix + "greet") | ||||
|                 .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 (!AnnouncementsDictionary.ContainsKey(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") | ||||
|                 .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) | ||||
|                 .Do(async e => { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     if (!e.User.ServerPermissions.ManageServer) return; | ||||
|                     if (e.GetArg("msg") == null) return; | ||||
|                     if (!AnnouncementsDictionary.ContainsKey(e.Server.Id)) | ||||
| @@ -207,7 +227,8 @@ namespace NadekoBot.Commands { | ||||
| 
 | ||||
|             cgb.CreateCommand(Module.Prefix + "bye") | ||||
|                 .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 (!AnnouncementsDictionary.ContainsKey(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") | ||||
|                 .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) | ||||
|                 .Do(async e => { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     if (!e.User.ServerPermissions.ManageServer) return; | ||||
|                     if (e.GetArg("msg") == null) return; | ||||
|                     if (!AnnouncementsDictionary.ContainsKey(e.Server.Id)) | ||||
| @@ -237,7 +259,8 @@ namespace NadekoBot.Commands { | ||||
| 
 | ||||
|             cgb.CreateCommand(Module.Prefix + "byepm") | ||||
|                 .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 (!AnnouncementsDictionary.ContainsKey(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") | ||||
|                 .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 (!AnnouncementsDictionary.ContainsKey(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.Threading.Tasks; | ||||
| using Discord.Commands; | ||||
| using System.Collections.Concurrent; | ||||
| using Discord; | ||||
| using NadekoBot.Modules; | ||||
| 
 | ||||
| namespace NadekoBot.Commands { | ||||
|     internal class VoiceNotificationCommand : DiscordCommand { | ||||
| namespace NadekoBot.Modules.Administration.Commands | ||||
| { | ||||
|     internal class VoiceNotificationCommand : DiscordCommand | ||||
|     { | ||||
| 
 | ||||
|         //voicechannel/text 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"); | ||||
|             if (string.IsNullOrWhiteSpace("voice_name")) | ||||
|                 return; | ||||
|             var voiceChannel = e.Server.FindChannels(arg, ChannelType.Voice).FirstOrDefault(); | ||||
|             if (voiceChannel == null) | ||||
|                 return; | ||||
|             if (subscribers.ContainsKey(voiceChannel)) { | ||||
|             if (subscribers.ContainsKey(voiceChannel)) | ||||
|             { | ||||
|                 await e.Channel.SendMessage("`Voice channel notifications disabled.`"); | ||||
|                 return; | ||||
|             } | ||||
|             if (subscribers.TryAdd(voiceChannel, e.Channel)) { | ||||
|             if (subscribers.TryAdd(voiceChannel, e.Channel)) | ||||
|             { | ||||
|                 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") | ||||
|                   .Description("Enables notifications on who joined/left the voice channel.\n**Usage**:.voicenotif Karaoke club") | ||||
|                   .Parameter("voice_name", ParameterType.Unparsed) | ||||
| @@ -1,20 +1,24 @@ | ||||
| using System; | ||||
| using System.Linq; | ||||
| using System.Runtime.CompilerServices; | ||||
| using Discord; | ||||
| using Discord; | ||||
| using Discord.Commands; | ||||
| using NadekoBot.Classes; | ||||
| using NadekoBot.Classes.Permissions; | ||||
| using NadekoBot.Modules; | ||||
| using NadekoBot.Commands; | ||||
| using System; | ||||
| using System.Linq; | ||||
| using ChPermOverride = Discord.ChannelPermissionOverrides; | ||||
| 
 | ||||
| namespace NadekoBot.Commands { | ||||
|     internal class VoicePlusTextCommand : DiscordCommand { | ||||
| namespace NadekoBot.Modules.Administration.Commands | ||||
| { | ||||
|     internal class VoicePlusTextCommand : DiscordCommand | ||||
|     { | ||||
| 
 | ||||
|         public VoicePlusTextCommand(DiscordModule module) : base(module) { | ||||
|         public VoicePlusTextCommand(DiscordModule module) : base(module) | ||||
|         { | ||||
|             // changing servers may cause bugs | ||||
|             NadekoBot.Client.UserUpdated += async (sender, e) => { | ||||
|                 try { | ||||
|             NadekoBot.Client.UserUpdated += async (sender, e) => | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     if (e.Server == null) | ||||
|                         return; | ||||
|                     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; | ||||
|                     if (serverPerms == null) | ||||
|                         return; | ||||
|                     if (!serverPerms.Value.ManageChannels || !serverPerms.Value.ManageRoles) { | ||||
|                     if (!serverPerms.Value.ManageChannels || !serverPerms.Value.ManageRoles) | ||||
|                     { | ||||
| 
 | ||||
|                         try { | ||||
|                         try | ||||
|                         { | ||||
|                             await e.Server.Owner.SendMessage( | ||||
|                                 "I don't have manage server and/or Manage Channels permission," + | ||||
|                                 $" so I cannot run voice+text on **{e.Server.Name}** server."); | ||||
|                         } catch { } // meh | ||||
|                         } | ||||
|                         catch { } // meh | ||||
|                         config.VoicePlusTextEnabled = false; | ||||
|                         return; | ||||
|                     } | ||||
| 
 | ||||
| 
 | ||||
|                     var beforeVch = e.Before.VoiceChannel; | ||||
|                     if (beforeVch != null) { | ||||
|                     if (beforeVch != null) | ||||
|                     { | ||||
|                         var textChannel = | ||||
|                             e.Server.FindChannels(GetChannelName(beforeVch.Name), ChannelType.Text).FirstOrDefault(); | ||||
|                         if (textChannel != null) | ||||
| @@ -46,12 +54,14 @@ namespace NadekoBot.Commands { | ||||
|                                                    sendMessages: PermValue.Deny)); | ||||
|                     } | ||||
|                     var afterVch = e.After.VoiceChannel; | ||||
|                     if (afterVch != null) { | ||||
|                     if (afterVch != null) | ||||
|                     { | ||||
|                         var textChannel = e.Server.FindChannels( | ||||
|                                                     GetChannelName(afterVch.Name), | ||||
|                                                     ChannelType.Text) | ||||
|                                                     .FirstOrDefault(); | ||||
|                         if (textChannel == null) { | ||||
|                         if (textChannel == null) | ||||
|                         { | ||||
|                             textChannel = (await e.Server.CreateChannel(GetChannelName(afterVch.Name), ChannelType.Text)); | ||||
|                             await textChannel.AddPermissionsRule(e.Server.EveryoneRole, | ||||
|                                 new ChPermOverride(readMessages: PermValue.Deny, | ||||
| @@ -61,7 +71,9 @@ namespace NadekoBot.Commands { | ||||
|                             new ChPermOverride(readMessages: PermValue.Allow, | ||||
|                                                sendMessages: PermValue.Allow)); | ||||
|                     } | ||||
|                 } catch (Exception ex) { | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
|                 { | ||||
|                     Console.WriteLine(ex); | ||||
|                 } | ||||
|             }; | ||||
| @@ -70,22 +82,30 @@ namespace NadekoBot.Commands { | ||||
|         private string GetChannelName(string voiceName) => | ||||
|             voiceName.Replace(" ", "-").Trim() + "-voice"; | ||||
| 
 | ||||
|         internal override void Init(CommandGroupBuilder cgb) { | ||||
|         internal override void Init(CommandGroupBuilder cgb) | ||||
|         { | ||||
|             cgb.CreateCommand(Module.Prefix + "v+t") | ||||
|                 .Alias(Module.Prefix + "voice+text") | ||||
|                 .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.") | ||||
|                 .AddCheck(SimpleCheckers.ManageChannels()) | ||||
|                 .AddCheck(SimpleCheckers.CanManageRoles) | ||||
|                 .Do(async e => { | ||||
|                     try { | ||||
|                 .Do(async e => | ||||
|                 { | ||||
|                     try | ||||
|                     { | ||||
|                         var config = SpecificConfigurations.Default.Of(e.Server.Id); | ||||
|                         if (config.VoicePlusTextEnabled == true) { | ||||
|                         if (config.VoicePlusTextEnabled == true) | ||||
|                         { | ||||
|                             config.VoicePlusTextEnabled = false; | ||||
|                             foreach (var textChannel in e.Server.TextChannels.Where(c => c.Name.EndsWith("-voice"))) { | ||||
|                                 try { | ||||
|                             foreach (var textChannel in e.Server.TextChannels.Where(c => c.Name.EndsWith("-voice"))) | ||||
|                             { | ||||
|                                 try | ||||
|                                 { | ||||
|                                     await textChannel.Delete(); | ||||
|                                 } catch { | ||||
|                                 } | ||||
|                                 catch | ||||
|                                 { | ||||
|                                     await | ||||
|                                         e.Channel.SendMessage( | ||||
|                                             ":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. " + | ||||
|                                                     "**Make sure the bot has manage roles and manage channels permissions**"); | ||||
| 
 | ||||
|                     } catch (Exception ex) { | ||||
|                     } | ||||
|                     catch (Exception ex) | ||||
|                     { | ||||
|                         await e.Channel.SendMessage(ex.ToString()); | ||||
|                     } | ||||
|                 }); | ||||
| @@ -1,16 +1,14 @@ | ||||
| using System; | ||||
| 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.Commands; | ||||
| using Discord.Modules; | ||||
| using NadekoBot.Classes.ClashOfClans; | ||||
| 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 | ||||
|     { | ||||
|         public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.ClashOfClans; | ||||
| @@ -19,8 +17,10 @@ namespace NadekoBot.Commands { | ||||
|  | ||||
|         private readonly object writeLock = new object(); | ||||
|  | ||||
|         public override void Install(ModuleManager manager) { | ||||
|             manager.CreateCommands("", cgb => { | ||||
|         public override void Install(ModuleManager manager) | ||||
|         { | ||||
|             manager.CreateCommands("", cgb => | ||||
|             { | ||||
|  | ||||
|                 cgb.CreateCommand(Prefix + "createwar") | ||||
|                     .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") | ||||
|                     .Parameter("size") | ||||
|                     .Parameter("enemy_clan", ParameterType.Unparsed) | ||||
|                     .Do(async e => { | ||||
|                     .Do(async e => | ||||
|                     { | ||||
|                         if (!e.User.ServerPermissions.ManageChannels) | ||||
|                             return; | ||||
|                         List<ClashWar> wars; | ||||
|                         if (!ClashWars.TryGetValue(e.Server.Id, out wars)) { | ||||
|                         if (!ClashWars.TryGetValue(e.Server.Id, out wars)) | ||||
|                         { | ||||
|                             wars = new List<ClashWar>(); | ||||
|                             if (!ClashWars.TryAdd(e.Server.Id, wars)) | ||||
|                                 return; | ||||
|                         } | ||||
|                         var enemyClan = e.GetArg("enemy_clan"); | ||||
|                         if (string.IsNullOrWhiteSpace(enemyClan)) { | ||||
|                         if (string.IsNullOrWhiteSpace(enemyClan)) | ||||
|                         { | ||||
|                             return; | ||||
|                         } | ||||
|                         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"); | ||||
|                             return; | ||||
|                         } | ||||
|                         var cw = new ClashWar(enemyClan, size, e); | ||||
|                         //cw.Start(); | ||||
|                         wars.Add(cw); | ||||
|                         cw.OnUserTimeExpired += async (u) => { | ||||
|                             try { | ||||
|                         cw.OnUserTimeExpired += async (u) => | ||||
|                         { | ||||
|                             try | ||||
|                             { | ||||
|                                 await | ||||
|                                     e.Channel.SendMessage( | ||||
|                                         $"❗🔰**Claim from @{u} for a war against {cw.ShortPrint()} has expired.**"); | ||||
|                             } catch { } | ||||
|                             } | ||||
|                             catch { } | ||||
|                         }; | ||||
|                         cw.OnWarEnded += async () => { | ||||
|                             try { | ||||
|                         cw.OnWarEnded += async () => | ||||
|                         { | ||||
|                             try | ||||
|                             { | ||||
|                                 await e.Channel.SendMessage($"❗🔰**War against {cw.ShortPrint()} ended.**"); | ||||
|                             } catch { } | ||||
|                             } | ||||
|                             catch { } | ||||
|                         }; | ||||
|                         await e.Channel.SendMessage($"❗🔰**CREATED CLAN WAR AGAINST {cw.ShortPrint()}**"); | ||||
|                         //war with the index X started. | ||||
| @@ -69,18 +79,23 @@ namespace NadekoBot.Commands { | ||||
|                     .Alias(Prefix + "startwar") | ||||
|                     .Description("Starts a war with a given number.") | ||||
|                     .Parameter("number", ParameterType.Required) | ||||
|                     .Do(async e => { | ||||
|                     .Do(async e => | ||||
|                     { | ||||
|                         var warsInfo = GetInfo(e); | ||||
|                         if (warsInfo == null) { | ||||
|                         if (warsInfo == null) | ||||
|                         { | ||||
|                             await e.Channel.SendMessage("💢🔰 **That war does not exist.**"); | ||||
|                             return; | ||||
|                         } | ||||
|                         var war = warsInfo.Item1[warsInfo.Item2]; | ||||
|                         try { | ||||
|                         try | ||||
|                         { | ||||
|                             var startTask = war.Start(); | ||||
|                             await e.Channel.SendMessage($"🔰**STARTED WAR AGAINST {war.ShortPrint()}**"); | ||||
|                             await startTask; | ||||
|                         } catch { | ||||
|                         } | ||||
|                         catch | ||||
|                         { | ||||
|                             await e.Channel.SendMessage($"🔰**WAR AGAINST {war.ShortPrint()} IS ALREADY STARTED**"); | ||||
|                         } | ||||
|                     }); | ||||
| @@ -89,13 +104,16 @@ namespace NadekoBot.Commands { | ||||
|                     .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") | ||||
|                     .Parameter("number", ParameterType.Optional) | ||||
|                     .Do(async e => { | ||||
|                     .Do(async e => | ||||
|                     { | ||||
|                         // 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 | ||||
|                             List<ClashWar> wars = null; | ||||
|                             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.**"); | ||||
|                                 return; | ||||
|                             } | ||||
| @@ -103,7 +121,8 @@ namespace NadekoBot.Commands { | ||||
|                             var sb = new StringBuilder(); | ||||
|                             sb.AppendLine("🔰 **LIST OF ACTIVE WARS**"); | ||||
|                             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($"\t\t`Size:` **{wars[i].Size} v {wars[i].Size}**"); | ||||
|                                 sb.AppendLine("**-------------------------**"); | ||||
| @@ -113,7 +132,8 @@ namespace NadekoBot.Commands { | ||||
|                         } | ||||
|                         //if number is not null, print the war needed | ||||
|                         var warsInfo = GetInfo(e); | ||||
|                         if (warsInfo == null) { | ||||
|                         if (warsInfo == null) | ||||
|                         { | ||||
|                             await e.Channel.SendMessage("💢🔰 **That war does not exist.**"); | ||||
|                             return; | ||||
|                         } | ||||
| @@ -127,14 +147,17 @@ namespace NadekoBot.Commands { | ||||
|                     .Parameter("number") | ||||
|                     .Parameter("baseNumber") | ||||
|                     .Parameter("other_name", ParameterType.Unparsed) | ||||
|                     .Do(async e => { | ||||
|                     .Do(async 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.**"); | ||||
|                             return; | ||||
|                         } | ||||
|                         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.**"); | ||||
|                             return; | ||||
|                         } | ||||
| @@ -142,11 +165,14 @@ namespace NadekoBot.Commands { | ||||
|                             string.IsNullOrWhiteSpace(e.GetArg("other_name")) ? | ||||
|                             e.User.Name : | ||||
|                             e.GetArg("other_name"); | ||||
|                         try { | ||||
|                         try | ||||
|                         { | ||||
|                             var war = warsInfo.Item1[warsInfo.Item2]; | ||||
|                             war.Call(usr, baseNum - 1); | ||||
|                             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}"); | ||||
|                         } | ||||
|                     }); | ||||
| @@ -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]") | ||||
|                     .Parameter("number", ParameterType.Required) | ||||
|                     .Parameter("other_name", ParameterType.Unparsed) | ||||
|                     .Do(async e => { | ||||
|                     .Do(async 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.**"); | ||||
|                             return; | ||||
|                         } | ||||
| @@ -168,10 +196,13 @@ namespace NadekoBot.Commands { | ||||
|                             e.GetArg("other_name"); | ||||
|  | ||||
|                         var war = warInfo.Item1[warInfo.Item2]; | ||||
|                         try { | ||||
|                         try | ||||
|                         { | ||||
|                             var baseNum = war.FinishClaim(usr); | ||||
|                             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}"); | ||||
|                         } | ||||
|                     }); | ||||
| @@ -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]") | ||||
|                     .Parameter("number", ParameterType.Required) | ||||
|                     .Parameter("other_name", ParameterType.Unparsed) | ||||
|                     .Do(async e => { | ||||
|                     .Do(async 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.**"); | ||||
|                             return; | ||||
|                         } | ||||
| @@ -192,11 +225,14 @@ namespace NadekoBot.Commands { | ||||
|                             string.IsNullOrWhiteSpace(e.GetArg("other_name")) ? | ||||
|                             e.User.Name : | ||||
|                             e.GetArg("other_name"); | ||||
|                         try { | ||||
|                         try | ||||
|                         { | ||||
|                             var war = warsInfo.Item1[warsInfo.Item2]; | ||||
|                             var baseNumber = war.Uncall(usr); | ||||
|                             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}"); | ||||
|                         } | ||||
|                     }); | ||||
| @@ -205,9 +241,11 @@ namespace NadekoBot.Commands { | ||||
|                     .Alias(Prefix + "ew") | ||||
|                     .Description($"Ends the war with a given index.\n**Usage**:{Prefix}ew [war_number]") | ||||
|                     .Parameter("number") | ||||
|                     .Do(async e => { | ||||
|                     .Do(async e => | ||||
|                     { | ||||
|                         var warsInfo = GetInfo(e); | ||||
|                         if (warsInfo == null) { | ||||
|                         if (warsInfo == null) | ||||
|                         { | ||||
|                             await e.Channel.SendMessage("💢🔰 That war does not exist."); | ||||
|                             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 | ||||
|             List<ClashWar> wars = null; | ||||
|             ClashWars.TryGetValue(e.Server.Id, out wars); | ||||
|             if (wars == null || wars.Count == 0) { | ||||
|             if (wars == null || wars.Count == 0) | ||||
|             { | ||||
|                 return null; | ||||
|             } | ||||
|             // get the number of the war | ||||
|             int num; | ||||
|             if (string.IsNullOrWhiteSpace(e.GetArg("number"))) | ||||
|                 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; | ||||
|             } | ||||
|             num -= 1; | ||||
|   | ||||
| @@ -159,6 +159,7 @@ namespace NadekoBot.Modules | ||||
|                     }); | ||||
|  | ||||
|                 cgb.CreateCommand("how are you") | ||||
|                     .Alias("how are you?") | ||||
|                     .Description("Replies positive only if bot owner is online.") | ||||
|                     .Do(async e => | ||||
|                     { | ||||
|   | ||||
| @@ -19,7 +19,7 @@ namespace NadekoBot.Modules.Gambling | ||||
|         internal override void Init(CommandGroupBuilder cgb) | ||||
|         { | ||||
|             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) | ||||
|                 .Do(Roll0to10Func()); | ||||
|             cgb.CreateCommand(Module.Prefix + "nroll") | ||||
| @@ -28,7 +28,13 @@ namespace NadekoBot.Modules.Gambling | ||||
|                 .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() | ||||
|         { | ||||
| @@ -37,30 +43,24 @@ namespace NadekoBot.Modules.Gambling | ||||
|             { | ||||
|                 if (e.Args[0] == "") | ||||
|                 { | ||||
|                     var num1 = r.Next(0, 10); | ||||
|                     var num2 = r.Next(0, 10); | ||||
|                     var gen = r.Next(0, 101); | ||||
|  | ||||
|                     Image[] images; | ||||
|                     var num1 = gen / 10; | ||||
|                     var num2 = gen % 10; | ||||
|  | ||||
|                     if (num1 == 0 && num2 == 0 && r.Next(0, 2) == 1) | ||||
|                     { | ||||
|                         images = new Image[3] { GetDice(1), GetDice(0), GetDice(0) }; | ||||
|                     } | ||||
|                     else { | ||||
|                         images = new Image[2] { GetDice(num1), GetDice(num2) }; | ||||
|                     } | ||||
|                     var imageStream = new Image[2] { GetDice(num1), GetDice(num2) }.Merge().ToStream(ImageFormat.Png); | ||||
|  | ||||
|                     var bitmap = images.Merge(); | ||||
|                     await e.Channel.SendFile("dice.png", bitmap.ToStream(ImageFormat.Png)); | ||||
|                     await e.Channel.SendFile("dice.png", imageStream); | ||||
|                 } | ||||
|                 else { | ||||
|                 else | ||||
|                 { | ||||
|                     try | ||||
|                     { | ||||
|                         var num = int.Parse(e.Args[0]); | ||||
|                         if (num < 1) num = 1; | ||||
|                         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; | ||||
|                         } | ||||
|                         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."); | ||||
|                         rolled = new Random().Next(arr[0], arr[1] + 1); | ||||
|                     } | ||||
|                     else { | ||||
|                     else | ||||
|                     { | ||||
|                         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.") | ||||
|                     .Parameter("role", ParameterType.Optional) | ||||
|                     .Do(RaffleFunc()); | ||||
|  | ||||
|                 cgb.CreateCommand(Prefix + "$$") | ||||
|                     .Description(string.Format("Check how much {0}s you have.", NadekoBot.Config.CurrencyName)) | ||||
|                     .Do(NadekoFlowerCheckFunc()); | ||||
|  | ||||
|                 cgb.CreateCommand(Prefix + "give") | ||||
|                     .Description(string.Format("Give someone a certain amount of {0}s", NadekoBot.Config.CurrencyName)) | ||||
|                     .Parameter("amount", ParameterType.Required) | ||||
| @@ -61,12 +63,56 @@ namespace NadekoBot.Modules.Gambling | ||||
|                             return; | ||||
|                         } | ||||
|  | ||||
|                         await FlowersHandler.RemoveFlowersAsync(e.User, "Gift", (int)amount); | ||||
|                         FlowersHandler.RemoveFlowers(e.User, "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}!"); | ||||
|  | ||||
|                     }); | ||||
|  | ||||
|                 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 System.Linq; | ||||
| using Discord.Commands; | ||||
| using Discord.Modules; | ||||
| using NadekoBot.Commands; | ||||
| using Newtonsoft.Json.Linq; | ||||
| using System.IO; | ||||
| using Discord.Commands; | ||||
| using NadekoBot.Extensions; | ||||
| using System; | ||||
| using System.Linq; | ||||
|  | ||||
| namespace NadekoBot.Modules { | ||||
|     internal class Games : DiscordModule { | ||||
| namespace NadekoBot.Modules | ||||
| { | ||||
|     internal class Games : DiscordModule | ||||
|     { | ||||
|         private readonly Random rng = new Random(); | ||||
|  | ||||
|         public Games() { | ||||
|         public Games() | ||||
|         { | ||||
|             commands.Add(new Trivia(this)); | ||||
|             commands.Add(new SpeedTyping(this)); | ||||
|             commands.Add(new PollCommand(this)); | ||||
|             commands.Add(new PlantPick(this)); | ||||
|             //commands.Add(new BetrayGame(this)); | ||||
| 			 | ||||
|  | ||||
|         } | ||||
|  | ||||
|         public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Games; | ||||
|  | ||||
|         public override void Install(ModuleManager manager) { | ||||
|             manager.CreateCommands("", cgb => { | ||||
|         public override void Install(ModuleManager manager) | ||||
|         { | ||||
|             manager.CreateCommands("", cgb => | ||||
|             { | ||||
|  | ||||
|                 cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance); | ||||
|  | ||||
| @@ -30,8 +34,9 @@ namespace NadekoBot.Modules { | ||||
|  | ||||
|                 cgb.CreateCommand(Prefix + "choose") | ||||
|                   .Description("Chooses a thing from a list of things\n**Usage**: >choose Get up;Sleep;Sleep more") | ||||
|                   .Parameter("list", Discord.Commands.ParameterType.Unparsed) | ||||
|                   .Do(async e => { | ||||
|                   .Parameter("list", ParameterType.Unparsed) | ||||
|                   .Do(async e => | ||||
|                   { | ||||
|                       var arg = e.GetArg("list"); | ||||
|                       if (string.IsNullOrWhiteSpace(arg)) | ||||
|                           return; | ||||
| @@ -43,24 +48,29 @@ namespace NadekoBot.Modules { | ||||
|  | ||||
|                 cgb.CreateCommand(Prefix + "8ball") | ||||
|                     .Description("Ask the 8ball a yes/no question.") | ||||
|                     .Parameter("question", Discord.Commands.ParameterType.Unparsed) | ||||
|                     .Do(async e => { | ||||
|                     .Parameter("question", ParameterType.Unparsed) | ||||
|                     .Do(async e => | ||||
|                     { | ||||
|                         var question = e.GetArg("question"); | ||||
|                         if (string.IsNullOrWhiteSpace(question)) | ||||
|                             return; | ||||
|                         try { | ||||
|                         try | ||||
|                         { | ||||
|                             await e.Channel.SendMessage( | ||||
|                                 $":question: **Question**: `{question}` \n🎱 **8Ball Answers**: `{NadekoBot.Config._8BallResponses[rng.Next(0, NadekoBot.Config._8BallResponses.Length)]}`"); | ||||
|                         } catch { } | ||||
|                         } | ||||
|                         catch { } | ||||
|                     }); | ||||
|  | ||||
|                 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) | ||||
|                     .Do(async e => { | ||||
|                     .Do(async e => | ||||
|                     { | ||||
|                         var input = e.GetArg("input").Trim(); | ||||
|                         int pick; | ||||
|                         switch (input) { | ||||
|                         switch (input) | ||||
|                         { | ||||
|                             case "r": | ||||
|                             case "rock": | ||||
|                             case "rocket": | ||||
| @@ -96,7 +106,8 @@ namespace NadekoBot.Modules { | ||||
|                     .Description("Prints a customizable Linux interjection") | ||||
|                     .Parameter("gnu", ParameterType.Required) | ||||
|                     .Parameter("linux", ParameterType.Required) | ||||
|                     .Do(async e => { | ||||
|                     .Do(async e => | ||||
|                     { | ||||
|                         var guhnoo = e.Args[0]; | ||||
|                         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) | ||||
|                 return "rocket"; | ||||
|             else if (i == 1) | ||||
|   | ||||
| @@ -70,6 +70,7 @@ namespace NadekoBot.Modules | ||||
|  | ||||
|                 cgb.CreateCommand("n") | ||||
|                     .Alias("next") | ||||
|                     .Alias("skip") | ||||
|                     .Description("Goes to the next song in the queue.") | ||||
|                     .Do(e => | ||||
|                     { | ||||
| @@ -138,7 +139,15 @@ namespace NadekoBot.Modules | ||||
|                             await e.Channel.SendMessage("🎵 No active music player."); | ||||
|                             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) | ||||
|                             toSend += "**Song queue is full!**\n"; | ||||
|                         else | ||||
| @@ -156,9 +165,10 @@ namespace NadekoBot.Modules | ||||
|                         if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer)) | ||||
|                             return; | ||||
|                         var currentSong = musicPlayer.CurrentSong; | ||||
|                         if (currentSong != null) | ||||
|                             await e.Channel.SendMessage($"🎵`Now Playing` {currentSong.PrettyName} " + | ||||
|                                                         $"{currentSong.PrettyCurrentTime()}"); | ||||
|                         if (currentSong == null) | ||||
|                             return; | ||||
|                         await e.Channel.SendMessage($"🎵`Now Playing` {currentSong.PrettyName} " + | ||||
|                                                     $"{currentSong.PrettyCurrentTime()}"); | ||||
|                     }); | ||||
|  | ||||
|                 cgb.CreateCommand("vol") | ||||
| @@ -303,7 +313,7 @@ namespace NadekoBot.Modules | ||||
|                     }); | ||||
|  | ||||
|                 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) | ||||
|                     .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") | ||||
|                 //    .Description("Does something magical. **BOT OWNER ONLY**") | ||||
|                 //    .AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly()) | ||||
|   | ||||
| @@ -79,7 +79,11 @@ namespace NadekoBot.Modules.Pokemon | ||||
|                         {"bullet punch",16}, | ||||
|                         {"metal burst",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.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using System.Collections.Generic; | ||||
|  | ||||
| namespace NadekoBot.Modules.Pokemon | ||||
| { | ||||
|     class PokeStats | ||||
|     { | ||||
|         //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 | ||||
|         public int MovesMade { get; set; } = 0; | ||||
|         //Last people attacked | ||||
|   | ||||
| @@ -1,378 +1,318 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using Discord.Commands; | ||||
| using Discord.Modules; | ||||
| using Discord.Commands; | ||||
| using NadekoBot.Commands; | ||||
| using NadekoBot.Classes; | ||||
| using NadekoBot.Extensions; | ||||
| using NadekoBot.Classes._DataModels; | ||||
| using NadekoBot.Classes.Permissions; | ||||
| using System.Collections.Concurrent; | ||||
| using NadekoBot.Extensions; | ||||
| using NadekoBot.Modules.Pokemon.PokeTypes; | ||||
| using NadekoBot.Modules.Pokemon.PokeTypes.Extensions; | ||||
|  | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
|  | ||||
| namespace NadekoBot.Modules.Pokemon | ||||
| { | ||||
|      | ||||
|     class PokemonGame : DiscordModule | ||||
|     class PokemonModule : DiscordModule | ||||
|     { | ||||
|         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>(); | ||||
|  | ||||
|  | ||||
|         public PokemonGame() | ||||
|         public PokemonModule() | ||||
|         { | ||||
|             //Something? | ||||
|         } | ||||
|         public override void Install(ModuleManager manager) | ||||
|         { | ||||
|             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 => | ||||
|             DbHandler.Instance.DeleteAll<PokeMoves>(); | ||||
|             DbHandler.Instance.InsertMany( | ||||
|                 DefaultMoves.DefaultMovesList.Select(move => new PokeMoves | ||||
|                 { | ||||
|                     var move = e.GetArg("move"); | ||||
|                     var target = e.Server.FindUsers(e.GetArg("target")).FirstOrDefault(); | ||||
|                     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 🌸"); | ||||
|                 }); | ||||
|             }); | ||||
|                     move = move.Key, | ||||
|                     type = move.Value | ||||
|                 })); | ||||
|         } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|         private int getDamage(IPokeType usertype, IPokeType targetType) | ||||
|         private int GetDamage(PokeType usertype, PokeType targetType) | ||||
|         { | ||||
|             Random rng = new Random(); | ||||
|             var rng = new Random(); | ||||
|             int damage = rng.Next(40, 60); | ||||
|             double multiplier = 1; | ||||
|             multiplier = usertype.GetMagnifier(targetType); | ||||
|             var multiplier = usertype.Multiplier(targetType); | ||||
|             damage = (int)(damage * multiplier); | ||||
|             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); | ||||
|             if (setTypes.ContainsKey((long)id)) | ||||
|             { | ||||
|                 return PokemonTypesMain.IntToPokeType(setTypes[(long)id]); | ||||
|             } | ||||
|  | ||||
|             int remainder = (int)id % 16; | ||||
|             int remainder = Math.Abs((int)(id % 18)); | ||||
|  | ||||
|             return PokemonTypesMain.IntToPokeType(remainder); | ||||
|  | ||||
|  | ||||
|         } | ||||
|  | ||||
|         private PokeStats defaultStats() | ||||
|         public override void Install(ModuleManager manager) | ||||
|         { | ||||
|             PokeStats s = new PokeStats(); | ||||
|             s.HP = BaseHealth; | ||||
|             return s; | ||||
|             manager.CreateCommands("", cgb => | ||||
|             { | ||||
|                 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.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 | ||||
| { | ||||
|     class BugType : IPokeType | ||||
|     class BugType : PokeType | ||||
|     { | ||||
|         static readonly string name = "BUG"; | ||||
|         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; | ||||
| @@ -24,8 +18,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes | ||||
|                 case "FIGHTING": return 0.5; | ||||
|                 case "POISON": return 0.5; | ||||
|                 case "FLYING": return 0.5; | ||||
|                 case "GHOST": return 0.5; | ||||
|                 case "PSYCHIC": return 2; | ||||
|                 case "ROCK": return 0.5; | ||||
|                 case "FAIRY": return 0.5; | ||||
|                 case "DARK": return 2; | ||||
|                 case "STEEL": return 0.5; | ||||
|                 default: return 1; | ||||
| @@ -33,24 +29,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes | ||||
|         } | ||||
|         List<string> moves = new List<string>(); | ||||
|  | ||||
|          | ||||
|         public string Name => name; | ||||
|  | ||||
|         public string Image => "🐛"; | ||||
|  | ||||
|         public string GetName() | ||||
|         { | ||||
|             return name; | ||||
|         } | ||||
|  | ||||
|          | ||||
|  | ||||
|         public string GetImage() | ||||
|         { | ||||
|             return "🐛"; | ||||
|         } | ||||
|  | ||||
|         public int GetNum() | ||||
|         { | ||||
|             return numType; | ||||
|         } | ||||
|         public int Num => numType; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,52 +1,32 @@ | ||||
| using System; | ||||
| using NadekoBot.Modules.Pokemon.PokeTypes; | ||||
| 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 | ||||
| { | ||||
|     class DarkType : IPokeType | ||||
|     class DarkType : PokeType | ||||
|     { | ||||
|         static readonly string name = "DARK"; | ||||
|         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 "PSYCHIC": return 2; | ||||
|                 case "GHOST": return 2; | ||||
|                 case "DARK": return 0.5; | ||||
|                 case "STEEL": return 0.5; | ||||
|                 case "FAIRY": return 0.5; | ||||
|                 default: return 1; | ||||
|             } | ||||
|         } | ||||
|         List<string> moves = new List<string>(); | ||||
|  | ||||
|          | ||||
|         public string Name => name; | ||||
|  | ||||
|         public string Image => "🕶"; | ||||
|  | ||||
|         public string GetName() | ||||
|         { | ||||
|             return name; | ||||
|         } | ||||
|  | ||||
|          | ||||
|  | ||||
|         public string GetImage() | ||||
|         { | ||||
|             return "🕶"; | ||||
|         } | ||||
|  | ||||
|         public int GetNum() | ||||
|         { | ||||
|             return numType; | ||||
|         } | ||||
|         public int Num => numType; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,49 +1,35 @@ | ||||
| using System; | ||||
| using NadekoBot.Modules.Pokemon.PokeTypes; | ||||
| 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 | ||||
| { | ||||
|     class DragonType : IPokeType | ||||
|     class DragonType : PokeType | ||||
|     { | ||||
|         static readonly string name = "DRAGON"; | ||||
|         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 "STEEL": return 0.5; | ||||
|                 case "FAIRY": return 0; | ||||
|                 default: return 1; | ||||
|             } | ||||
|         } | ||||
|         List<string> moves = new List<string>(); | ||||
|  | ||||
|          | ||||
|  | ||||
|  | ||||
|         public string GetName() | ||||
|         { | ||||
|             return name; | ||||
|         } | ||||
|  | ||||
|          | ||||
|         public string Name => name; | ||||
|  | ||||
|         public string GetImage() | ||||
|         { | ||||
|             return "🐉"; | ||||
|         } | ||||
|  | ||||
|         public int GetNum() | ||||
|         { | ||||
|             return numType; | ||||
|         } | ||||
|  | ||||
|         public string Image => "🐉"; | ||||
|  | ||||
|         public int Num => numType; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,22 +1,16 @@ | ||||
| using System; | ||||
| using NadekoBot.Modules.Pokemon.PokeTypes; | ||||
| 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 | ||||
| { | ||||
|     class ElectricType : IPokeType | ||||
|     class ElectricType : PokeType | ||||
|     { | ||||
|         static readonly string name = "ELECTRIC"; | ||||
|         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; | ||||
| @@ -30,23 +24,14 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes | ||||
|         } | ||||
|         List<string> moves = new List<string>(); | ||||
|  | ||||
|          | ||||
|  | ||||
|  | ||||
|         public string GetName() | ||||
|         { | ||||
|             return name; | ||||
|         } | ||||
|  | ||||
|          | ||||
|         public string GetImage() | ||||
|         { | ||||
|             return "⚡️"; | ||||
|         } | ||||
|         public string Name => name; | ||||
|  | ||||
|         public int GetNum() | ||||
|         { | ||||
|             return numType; | ||||
|         } | ||||
|  | ||||
|         public string Image => "⚡️"; | ||||
|  | ||||
|         public int Num => 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.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 | ||||
| { | ||||
|     class FightingType : IPokeType | ||||
|     class FightingType : PokeType | ||||
|     { | ||||
|         static readonly string name = "FIGHTING"; | ||||
|         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; | ||||
| @@ -29,28 +23,20 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes | ||||
|                 case "GHOST": return 0; | ||||
|                 case "DARK": return 2; | ||||
|                 case "STEEL": return 2; | ||||
|                 case "FAIRY": return 0.5; | ||||
|                 default: return 1; | ||||
|             } | ||||
|         } | ||||
|         List<string> moves = new List<string>(); | ||||
|  | ||||
|          | ||||
|  | ||||
|  | ||||
|         public string GetName() | ||||
|         { | ||||
|             return name; | ||||
|         } | ||||
|  | ||||
|          | ||||
|         public string GetImage() | ||||
|         { | ||||
|             return "✊"; | ||||
|         } | ||||
|         public string Name => name; | ||||
|  | ||||
|         public int GetNum() | ||||
|         { | ||||
|             return numType; | ||||
|         } | ||||
|  | ||||
|         public string Image => "✊"; | ||||
|  | ||||
|         public int Num => numType; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,24 +1,18 @@ | ||||
| using System; | ||||
| using NadekoBot.Modules.Pokemon.PokeTypes; | ||||
| 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 | ||||
| { | ||||
|     class FireType : IPokeType | ||||
|     class FireType : PokeType | ||||
|     { | ||||
|         static readonly string name = "FIRE"; | ||||
|         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; | ||||
| @@ -33,25 +27,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes | ||||
|             } | ||||
|         } | ||||
|         List<string> moves = new List<string>(); | ||||
|         public string Name => name; | ||||
|  | ||||
|          | ||||
|         public string Image => "🔥"; | ||||
|  | ||||
|  | ||||
|         public string GetName() | ||||
|         { | ||||
|             return name; | ||||
|         } | ||||
|  | ||||
|          | ||||
|  | ||||
|         public string GetImage() | ||||
|         { | ||||
|             return "🔥"; | ||||
|         } | ||||
|  | ||||
|         public int GetNum() | ||||
|         { | ||||
|             return numType; | ||||
|         } | ||||
|         public int Num => numType; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,22 +1,16 @@ | ||||
| using System; | ||||
| using NadekoBot.Modules.Pokemon.PokeTypes; | ||||
| 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 | ||||
| { | ||||
|     class FlyingType : IPokeType | ||||
|     class FlyingType : PokeType | ||||
|     { | ||||
|         static readonly string name = "FLYING"; | ||||
|         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; | ||||
| @@ -30,24 +24,15 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes | ||||
|         } | ||||
|         List<string> moves = new List<string>(); | ||||
|  | ||||
|          | ||||
|  | ||||
|  | ||||
|         public string GetName() | ||||
|         { | ||||
|             return name; | ||||
|         } | ||||
|  | ||||
|          | ||||
|         public string Name => name; | ||||
|  | ||||
|         public string GetImage() | ||||
|         { | ||||
|             return "☁"; | ||||
|         } | ||||
|  | ||||
|         public int GetNum() | ||||
|         { | ||||
|             return numType; | ||||
|         } | ||||
|  | ||||
|         public string Image => "☁"; | ||||
|  | ||||
|         public int Num => numType; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,22 +1,16 @@ | ||||
| using System; | ||||
| using NadekoBot.Modules.Pokemon.PokeTypes; | ||||
| 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 | ||||
| { | ||||
|     class GhostType : IPokeType | ||||
|     class GhostType : PokeType | ||||
|     { | ||||
|         static readonly string name = "GHOST"; | ||||
|         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; | ||||
| @@ -29,24 +23,15 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes | ||||
|         } | ||||
|         List<string> moves = new List<string>(); | ||||
|  | ||||
|          | ||||
|  | ||||
|  | ||||
|         public string GetName() | ||||
|         { | ||||
|             return name; | ||||
|         } | ||||
|  | ||||
|          | ||||
|         public string Name => name; | ||||
|  | ||||
|         public string GetImage() | ||||
|         { | ||||
|             return "👻"; | ||||
|         } | ||||
|  | ||||
|         public int GetNum() | ||||
|         { | ||||
|             return numType; | ||||
|         } | ||||
|  | ||||
|         public string Image => "👻"; | ||||
|  | ||||
|         public int Num => numType; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,22 +1,16 @@ | ||||
| using System; | ||||
| using NadekoBot.Modules.Pokemon.PokeTypes; | ||||
| 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 | ||||
| { | ||||
|     class GrassType : IPokeType | ||||
|     class GrassType : PokeType | ||||
|     { | ||||
|         static readonly string name = "GRASS"; | ||||
|         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; | ||||
| @@ -32,23 +26,14 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes | ||||
|         } | ||||
|         List<string> moves = new List<string>(); | ||||
|  | ||||
|          | ||||
|  | ||||
|  | ||||
|         public string GetName() | ||||
|         { | ||||
|             return name; | ||||
|         } | ||||
|  | ||||
|          | ||||
|         public string GetImage() | ||||
|         { | ||||
|             return "🌿"; | ||||
|         } | ||||
|         public string Name => name; | ||||
|  | ||||
|         public int GetNum() | ||||
|         { | ||||
|             return numType; | ||||
|         } | ||||
|  | ||||
|         public string Image => "🌿"; | ||||
|  | ||||
|         public int Num => numType; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,22 +1,16 @@ | ||||
| using System; | ||||
| using NadekoBot.Modules.Pokemon.PokeTypes; | ||||
| 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 | ||||
| { | ||||
|     class GroundType : IPokeType | ||||
|     class GroundType : PokeType | ||||
|     { | ||||
|         static readonly string name = "GROUND"; | ||||
|         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; | ||||
| @@ -32,24 +26,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes | ||||
|         } | ||||
|         List<string> moves = new List<string>(); | ||||
|  | ||||
|          | ||||
|         public string Name => name; | ||||
|  | ||||
|         public string Image => "🗻"; | ||||
|  | ||||
|         public string GetName() | ||||
|         { | ||||
|             return name; | ||||
|         } | ||||
|  | ||||
|          | ||||
|  | ||||
|         public string GetImage() | ||||
|         { | ||||
|             return "🗻"; | ||||
|         } | ||||
|  | ||||
|         public int GetNum() | ||||
|         { | ||||
|             return numType; | ||||
|         } | ||||
|         public int Num => numType; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -5,23 +5,23 @@ using System.Collections.Generic; | ||||
| namespace NadekoBot.Modules.Pokemon.PokeTypes.Extensions | ||||
| { | ||||
|     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>(); | ||||
|                 List<string> moves = new List<string>(); | ||||
|                 foreach (PokeMoves p in db) | ||||
|                 if (p.type == poketype.Num) | ||||
|                 { | ||||
|                     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.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 | ||||
| { | ||||
|     class IceType : IPokeType | ||||
|     class IceType : PokeType | ||||
|     { | ||||
|         static readonly string name = "ICE"; | ||||
|         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; | ||||
| @@ -32,23 +26,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes | ||||
|         } | ||||
|         List<string> moves = new List<string>(); | ||||
|  | ||||
|          | ||||
|         public string Name => name; | ||||
|  | ||||
|         public string Image => "❄"; | ||||
|  | ||||
|         public string GetName() | ||||
|         { | ||||
|             return name; | ||||
|         } | ||||
|  | ||||
|      | ||||
|         public string GetImage() | ||||
|         { | ||||
|             return "❄"; | ||||
|         } | ||||
|  | ||||
|         public int GetNum() | ||||
|         { | ||||
|             return numType; | ||||
|         } | ||||
|         public int Num => numType; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,26 +1,18 @@ | ||||
| using System; | ||||
| using NadekoBot.Modules.Pokemon.PokeTypes; | ||||
| 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 | ||||
| { | ||||
|     class NormalType : IPokeType | ||||
|     class NormalType : PokeType | ||||
|     { | ||||
|         static readonly string name = "NORMAL"; | ||||
|         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 "GHOST": return 0; | ||||
|                 case "STEEL": return 0.5; | ||||
| @@ -29,24 +21,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes | ||||
|         } | ||||
|         List<string> moves = new List<string>(); | ||||
|  | ||||
|          | ||||
|         public string Name => name; | ||||
|  | ||||
|         public string Image => "⭕️"; | ||||
|  | ||||
|         public string GetName() | ||||
|         { | ||||
|             return name; | ||||
|         } | ||||
|  | ||||
|          | ||||
|  | ||||
|         public string GetImage() | ||||
|         { | ||||
|             return "⭕️"; | ||||
|         } | ||||
|  | ||||
|         public int GetNum() | ||||
|         { | ||||
|             return type_num; | ||||
|         } | ||||
|         public int Num => type_num; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,23 +1,16 @@ | ||||
| using System; | ||||
| using NadekoBot.Modules.Pokemon.PokeTypes; | ||||
| 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 | ||||
| { | ||||
|     class PoisonType : IPokeType | ||||
|     class PoisonType : PokeType | ||||
|     { | ||||
|         static readonly string name = "POISON"; | ||||
|         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; | ||||
| @@ -26,28 +19,16 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes | ||||
|                 case "ROCK": return 0.5; | ||||
|                 case "GHOST": return 0.5; | ||||
|                 case "STEEL": return 0; | ||||
|                 case "FAIRY": return 2; | ||||
|                 default: return 1; | ||||
|             } | ||||
|         } | ||||
|         List<string> moves = new List<string>(); | ||||
|  | ||||
|          | ||||
|         public string Name => name; | ||||
|  | ||||
|         public string Image => "☠"; | ||||
|  | ||||
|         public string GetName() | ||||
|         { | ||||
|             return name; | ||||
|         } | ||||
|  | ||||
|          | ||||
|         public string GetImage() | ||||
|         { | ||||
|             return "☠"; | ||||
|         } | ||||
|  | ||||
|         public int GetNum() | ||||
|         { | ||||
|             return numType; | ||||
|         } | ||||
|         public int Num => numType; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,28 +1,24 @@ | ||||
| using System.Collections.Generic; | ||||
| using NadekoBot.Classes; | ||||
| using NadekoBot.Classes._DataModels; | ||||
| using NadekoBot.Modules.Pokemon.PokemonTypes; | ||||
| using NadekoBot.Modules.Pokemon.PokemonTypes; | ||||
| using System.Collections.Generic; | ||||
|  | ||||
| namespace NadekoBot.Modules.Pokemon.PokeTypes | ||||
| { | ||||
|  | ||||
|     public interface IPokeType | ||||
|     public interface PokeType | ||||
|     { | ||||
|  | ||||
|         string GetImage(); | ||||
|         string GetName(); | ||||
|         int GetNum(); | ||||
|         double GetMagnifier(IPokeType target); | ||||
|         string Image { get; } | ||||
|         string Name { get; } | ||||
|         int Num { get; } | ||||
|         double Multiplier(PokeType target); | ||||
|     } | ||||
|     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; | ||||
|                 } | ||||
| @@ -30,26 +26,8 @@ namespace NadekoBot.Modules.Pokemon.PokeTypes | ||||
|             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) | ||||
|         public static List<IPokeType> TypeList = new List<IPokeType>() | ||||
|         public static List<PokeType> TypeList = new List<PokeType>() | ||||
|         { | ||||
|             new NormalType(), | ||||
|             new FireType(), | ||||
| @@ -67,14 +45,15 @@ namespace NadekoBot.Modules.Pokemon.PokeTypes | ||||
|             new GhostType(), | ||||
|             new DragonType(), | ||||
|             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; | ||||
|                 } | ||||
|   | ||||
| @@ -1,23 +1,16 @@ | ||||
| using System; | ||||
| using NadekoBot.Modules.Pokemon.PokeTypes; | ||||
| 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 | ||||
| { | ||||
|     class PsychicType : IPokeType | ||||
|     class PsychicType : PokeType | ||||
|     { | ||||
|         static readonly string name = "PSYCHIC"; | ||||
|         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; | ||||
| @@ -30,24 +23,13 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes | ||||
|         } | ||||
|         List<string> moves = new List<string>(); | ||||
|  | ||||
|          | ||||
|  | ||||
|  | ||||
|         public string GetName() | ||||
|         { | ||||
|             return name; | ||||
|         } | ||||
|  | ||||
|          | ||||
|         public string Name => name; | ||||
|  | ||||
|         public string GetImage() | ||||
|         { | ||||
|             return "💫"; | ||||
|         } | ||||
|         public string Image => "🔮"; | ||||
|  | ||||
|         public int GetNum() | ||||
|         { | ||||
|             return numType; | ||||
|         } | ||||
|         public int Num => numType; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,22 +1,16 @@ | ||||
| using System; | ||||
| using NadekoBot.Modules.Pokemon.PokeTypes; | ||||
| 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 | ||||
| { | ||||
|     class RockType : IPokeType | ||||
|     class RockType : PokeType | ||||
|     { | ||||
|         static readonly string name = "ROCK"; | ||||
|         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; | ||||
| @@ -31,24 +25,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes | ||||
|         } | ||||
|         List<string> moves = new List<string>(); | ||||
|  | ||||
|          | ||||
|         public string Name => name; | ||||
|  | ||||
|         public string Image => "💎"; | ||||
|  | ||||
|         public string GetName() | ||||
|         { | ||||
|             return name; | ||||
|         } | ||||
|  | ||||
|          | ||||
|  | ||||
|         public string GetImage() | ||||
|         { | ||||
|             return "💎"; | ||||
|         } | ||||
|  | ||||
|         public int GetNum() | ||||
|         { | ||||
|             return numType; | ||||
|         } | ||||
|         public int Num => numType; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,22 +1,16 @@ | ||||
| using System; | ||||
| using NadekoBot.Modules.Pokemon.PokeTypes; | ||||
| 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 | ||||
| { | ||||
|     class SteelType : IPokeType | ||||
|     class SteelType : PokeType | ||||
|     { | ||||
|         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; | ||||
| @@ -30,23 +24,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes | ||||
|         } | ||||
|         List<string> moves = new List<string>(); | ||||
|  | ||||
|          | ||||
|         public string Name => name; | ||||
|  | ||||
|         public string Image => "🔩"; | ||||
|  | ||||
|         public string GetName() | ||||
|         { | ||||
|             return name; | ||||
|         } | ||||
|  | ||||
|          | ||||
|         public string GetImage() | ||||
|         { | ||||
|             return "🔩"; | ||||
|         } | ||||
|  | ||||
|         public int GetNum() | ||||
|         { | ||||
|             return numType; | ||||
|         } | ||||
|         public int Num => numType; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,22 +1,16 @@ | ||||
| using System; | ||||
| using NadekoBot.Modules.Pokemon.PokeTypes; | ||||
| 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 | ||||
| { | ||||
|     class WaterType : IPokeType | ||||
|     class WaterType : PokeType | ||||
|     { | ||||
|         static readonly string name = "WATER"; | ||||
|         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; | ||||
| @@ -30,23 +24,10 @@ namespace NadekoBot.Modules.Pokemon.PokemonTypes | ||||
|         } | ||||
|         List<string> moves = new List<string>(); | ||||
|  | ||||
|          | ||||
|         public string Name => name; | ||||
|  | ||||
|         public string Image => "💦"; | ||||
|  | ||||
|         public string GetName() | ||||
|         { | ||||
|             return name; | ||||
|         } | ||||
|  | ||||
|          | ||||
|         public string GetImage() | ||||
|         { | ||||
|             return "💦"; | ||||
|         } | ||||
|  | ||||
|         public int GetNum() | ||||
|         { | ||||
|             return numType; | ||||
|         } | ||||
|         public int Num => numType; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -317,9 +317,62 @@ $@"🌍 **Weather for** 【{obj["target"]}】 | ||||
|                     .Description("Shows a random quote.") | ||||
|                     .Do(async e => | ||||
|                     { | ||||
|                         await | ||||
|                             e.Channel.SendMessage( | ||||
|                                 NadekoBot.Config.Quotes[new Random().Next(0, NadekoBot.Config.Quotes.Count)].ToString()); | ||||
|                         var quote = NadekoBot.Config.Quotes[rng.Next(0, NadekoBot.Config.Quotes.Count)].ToString(); | ||||
|                         await e.Channel.SendMessage(quote); | ||||
|                     }); | ||||
|  | ||||
|                 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.Commands; | ||||
| using NadekoBot.Modules; | ||||
| using NadekoBot.Modules.Administration; | ||||
| using NadekoBot.Modules.Gambling; | ||||
| using NadekoBot.Modules.Pokemon; | ||||
| using NadekoBot.Modules.Translator; | ||||
| using Newtonsoft.Json; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| @@ -14,13 +16,12 @@ using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using NadekoBot.Modules.Translator; | ||||
|  | ||||
| namespace NadekoBot | ||||
| { | ||||
|     public class NadekoBot | ||||
|     { | ||||
|         public static DiscordClient Client; | ||||
|         public static DiscordClient Client { get; private set; } | ||||
|         public static Credentials Creds { get; set; } | ||||
|         public static Configuration Config { get; set; } | ||||
|         public static LocalizedStrings Locale { get; set; } = new LocalizedStrings(); | ||||
| @@ -110,7 +111,7 @@ namespace NadekoBot | ||||
|             Client = new DiscordClient(new DiscordConfigBuilder() | ||||
|             { | ||||
|                 MessageCacheSize = 10, | ||||
|                 ConnectionTimeout = 60000, | ||||
|                 ConnectionTimeout = 120000, | ||||
|                 LogLevel = LogSeverity.Warning, | ||||
|                 LogHandler = (s, e) => | ||||
|                     Console.WriteLine($"Severity: {e.Severity}" + | ||||
| @@ -157,7 +158,7 @@ namespace NadekoBot | ||||
|             })); | ||||
|  | ||||
|             //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 PermissionModule(), "Permissions", 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 NSFW(), "NSFW", 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); | ||||
|             if (!string.IsNullOrWhiteSpace(Creds.TrelloAppKey)) | ||||
|                 modules.Add(new Trello(), "Trello", ModuleFilter.None); | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
|     <AppDesignerFolder>Properties</AppDesignerFolder> | ||||
|     <RootNamespace>NadekoBot</RootNamespace> | ||||
|     <AssemblyName>NadekoBot</AssemblyName> | ||||
|     <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion> | ||||
|     <TargetFrameworkVersion>v4.6</TargetFrameworkVersion> | ||||
|     <FileAlignment>512</FileAlignment> | ||||
|     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> | ||||
|     <IsWebBootstrapper>false</IsWebBootstrapper> | ||||
| @@ -32,6 +32,7 @@ | ||||
|     <BootstrapperEnabled>true</BootstrapperEnabled> | ||||
|     <NuGetPackageImportStamp> | ||||
|     </NuGetPackageImportStamp> | ||||
|     <TargetFrameworkProfile /> | ||||
|   </PropertyGroup> | ||||
|   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||||
|     <PlatformTarget>AnyCPU</PlatformTarget> | ||||
| @@ -145,27 +146,30 @@ | ||||
|     <Compile Include="Classes\_DataModels\IDataModel.cs" /> | ||||
|     <Compile Include="Classes\_DataModels\pokemoves.cs" /> | ||||
|     <Compile Include="Classes\_DataModels\PokeTypes.cs" /> | ||||
|     <Compile Include="Classes\_DataModels\Reminder.cs" /> | ||||
|     <Compile Include="Classes\_DataModels\RequestModel.cs" /> | ||||
|     <Compile Include="Classes\_DataModels\StatsModel.cs" /> | ||||
|     <Compile Include="Classes\_DataModels\TypingArticleModel.cs" /> | ||||
|     <Compile Include="Classes\_DataModels\UserQuoteModel.cs" /> | ||||
|     <Compile Include="Commands\BetrayGame.cs" /> | ||||
|     <Compile Include="Commands\CrossServerTextChannel.cs" /> | ||||
|     <Compile Include="Commands\SelfAssignedRolesCommand.cs" /> | ||||
|     <Compile Include="Commands\PlantPick.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="Commands\FilterWordsCommand.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\MessageRepeater.cs" /> | ||||
|     <Compile Include="Commands\PlayingRotate.cs" /> | ||||
|     <Compile Include="Modules\Administration\Commands\MessageRepeater.cs" /> | ||||
|     <Compile Include="Modules\Administration\Commands\PlayingRotate.cs" /> | ||||
|     <Compile Include="Commands\StreamNotifications.cs" /> | ||||
|     <Compile Include="Commands\TriviaCommand.cs" /> | ||||
|     <Compile Include="Classes\Trivia\TriviaGame.cs" /> | ||||
|     <Compile Include="Classes\Trivia\TriviaQuestion.cs" /> | ||||
|     <Compile Include="Classes\Trivia\TriviaQuestionPool.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="Modules\Gambling\Helpers\Cards.cs" /> | ||||
|     <Compile Include="Classes\Extensions.cs" /> | ||||
| @@ -175,9 +179,9 @@ | ||||
|     <Compile Include="Modules\Gambling\DrawCommand.cs" /> | ||||
|     <Compile Include="Modules\Gambling\FlipCoinCommand.cs" /> | ||||
|     <Compile Include="Commands\HelpCommand.cs" /> | ||||
|     <Compile Include="Commands\VoiceNotificationCommand.cs" /> | ||||
|     <Compile Include="Commands\VoicePlusTextCommand.cs" /> | ||||
|     <Compile Include="Modules\Administration.cs" /> | ||||
|     <Compile Include="Modules\Administration\Commands\VoiceNotificationCommand.cs" /> | ||||
|     <Compile Include="Modules\Administration\Commands\VoicePlusTextCommand.cs" /> | ||||
|     <Compile Include="Modules\Administration\AdministrationModule.cs" /> | ||||
|     <Compile Include="Modules\Conversations.cs" /> | ||||
|     <Compile Include="Modules\DiscordModule.cs" /> | ||||
|     <Compile Include="Modules\Gambling\GamblingModule.cs" /> | ||||
| @@ -187,9 +191,10 @@ | ||||
|     <Compile Include="Commands\PollCommand.cs" /> | ||||
|     <Compile Include="Modules\NSFW.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\PokemonModule.cs" /> | ||||
|     <Compile Include="Modules\Pokemon\PokemonTypes\FairyType.cs" /> | ||||
|     <Compile Include="Modules\Pokemon\PokemonTypes\IPokeTypeExtensions.cs" /> | ||||
|     <Compile Include="Modules\Pokemon\PokemonTypes\PokeType.cs" /> | ||||
|     <Compile Include="Modules\Pokemon\PokemonTypes\PsychicType.cs" /> | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|     "Gambling": "$", | ||||
|     "Permissions": ";", | ||||
|     "Programming": "%", | ||||
|     "Pokemon": "poke" | ||||
|     "Pokemon": ">" | ||||
|   }, | ||||
|   "ServerBlacklist": [], | ||||
|   "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="Newtonsoft.Json" version="8.0.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="taglib" version="2.1.0.0" targetFramework="net452" /> | ||||
|   <package id="VideoLibrary" version="1.3.3" targetFramework="net452" /> | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|     <AppDesignerFolder>Properties</AppDesignerFolder> | ||||
|     <RootNamespace>Tests</RootNamespace> | ||||
|     <AssemblyName>Tests</AssemblyName> | ||||
|     <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion> | ||||
|     <TargetFrameworkVersion>v4.6</TargetFrameworkVersion> | ||||
|     <FileAlignment>512</FileAlignment> | ||||
|     <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | ||||
|     <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| ######You can donate on paypal: `nadekodiscordbot@gmail.com` or Bitcoin `17MZz1JAqME39akMLrVT4XBPffQJ2n1EPa` | ||||
|  | ||||
| #NadekoBot List Of Commands   | ||||
| Version: `NadekoBot v0.9.5930.23184` | ||||
| Version: `NadekoBot v0.9.5933.23628` | ||||
| ### Administration   | ||||
| Command and aliases | Description | Usage | ||||
| ----------------|--------------|------- | ||||
| @@ -31,6 +31,7 @@ Command and aliases | Description | Usage | ||||
| `.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 | ||||
| `.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 | ||||
| `.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 | ||||
| @@ -46,7 +47,7 @@ Command and aliases | Description | Usage | ||||
| `.vch`, `.cvch`  |  Creates a new voice 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. | ||||
| `.st`, `.settopic`  |  Sets a topic on the current channel. | ||||
| `.st`, `.settopic`, `.topic`  |  Sets a topic on the current channel. | ||||
| `.uid`, `.userid`  |  Shows user ID. | ||||
| `.cid`, `.channelid`  |  Shows current channel ID. | ||||
| `.sid`, `.serverid`  |  Shows current server ID. | ||||
| @@ -70,7 +71,6 @@ Command and aliases | Description | Usage | ||||
| `.unstuck`  |  Clears the message queue. **Owner Only!** | ||||
| `.donators`  |  List of lovely people who donated to keep this project alive. | ||||
| `.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. | ||||
|  | ||||
| ### Help   | ||||
| @@ -138,7 +138,7 @@ Command and aliases | Description | Usage | ||||
| `@BotName uptime`  |  Shows how long Nadeko has been running for. | ||||
| `@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 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 praise`  |  Praises @X person. |  @NadekoBot praise @X. | ||||
| `@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] | ||||
| `$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. | ||||
| `$$$`  |  Check how many NadekoFlowers you have. | ||||
| `$give`  |  Give someone a certain amount of flowers | ||||
| `$$$`  |  Check how much NadekoFlowers you have. | ||||
| `$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   | ||||
| 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. | ||||
| `>choose`  |  Chooses a thing from a list of things |  >choose Get up;Sleep;Sleep more | ||||
| `>8ball`  |  Ask the 8ball a yes/no question. | ||||
| `>attack`  |  Attack a person. Supported attacks: 'splash', 'strike', 'burn', 'surge'. |  >attack strike @User | ||||
| `>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 | ||||
| `>rps`  |  Play a game of rocket paperclip scissors with Nadeko. |  >rps scissors | ||||
| `>linux`  |  Prints a customizable Linux interjection | ||||
|  | ||||
| ### Music   | ||||
| 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 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. | ||||
| @@ -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 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 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 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. | ||||
| @@ -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. | ||||
| `~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 | ||||
| `~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 | ||||
| `~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. | ||||
| @@ -238,12 +239,11 @@ Command and aliases | Description | Usage | ||||
| `~ud`  |  Searches Urban Dictionary for a word. | ~ud Pineapple | ||||
| `~#`  |  Searches Tagdef.com for a hashtag. | ~# ff | ||||
| `~quote`  |  Shows a random quote. | ||||
|  | ||||
| ### 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. | ||||
| `~catfact`  |  Shows a random catfact from <http://catfacts-api.appspot.com/api/facts> | ||||
| `~yomama`, `~ym`  |  Shows a random joke from <http://api.yomomma.info/> | ||||
| `~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> | ||||
| `~revav`  |  Returns a google reverse image search for someone's avatar. | ||||
|  | ||||
| ### NSFW   | ||||
| 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] | ||||
| `,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   | ||||
| Command and aliases | Description | Usage | ||||
| ----------------|--------------|------- | ||||
|   | ||||
		Reference in New Issue
	
	Block a user