2016-03-30 18:54:57 +02:00
using Discord.Commands ;
2016-03-11 20:13:48 +01:00
using Discord.Modules ;
using NadekoBot.Classes.ClashOfClans ;
using NadekoBot.Modules ;
2016-03-30 18:54:57 +02:00
using System ;
using System.Collections.Concurrent ;
using System.Collections.Generic ;
using System.Text ;
2016-03-11 20:13:48 +01:00
2016-03-30 18:54:57 +02:00
namespace NadekoBot.Commands
{
2016-03-11 20:13:48 +01:00
internal class ClashOfClans : DiscordModule
{
2016-03-12 10:02:29 +01:00
public override string Prefix { get ; } = NadekoBot . Config . CommandPrefixes . ClashOfClans ;
2016-03-11 20:13:48 +01:00
public static ConcurrentDictionary < ulong , List < ClashWar > > ClashWars { get ; } = new ConcurrentDictionary < ulong , List < ClashWar > > ( ) ;
private readonly object writeLock = new object ( ) ;
2016-03-30 18:54:57 +02:00
public override void Install ( ModuleManager manager )
{
manager . CreateCommands ( "" , cgb = >
{
2016-03-11 20:13:48 +01:00
cgb . CreateCommand ( Prefix + "createwar" )
. Alias ( Prefix + "cw" )
. Description (
$"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 )
2016-03-30 18:54:57 +02:00
. Do ( async e = >
{
2016-03-11 20:13:48 +01:00
if ( ! e . User . ServerPermissions . ManageChannels )
return ;
List < ClashWar > wars ;
2016-03-30 18:54:57 +02:00
if ( ! ClashWars . TryGetValue ( e . Server . Id , out wars ) )
{
2016-03-11 20:13:48 +01:00
wars = new List < ClashWar > ( ) ;
if ( ! ClashWars . TryAdd ( e . Server . Id , wars ) )
return ;
}
var enemyClan = e . GetArg ( "enemy_clan" ) ;
2016-03-30 18:54:57 +02:00
if ( string . IsNullOrWhiteSpace ( enemyClan ) )
{
2016-03-11 20:13:48 +01:00
return ;
}
int size ;
2016-03-30 18:54:57 +02:00
if ( ! int . TryParse ( e . GetArg ( "size" ) , out size ) | | size < 10 | | size > 50 | | size % 5 ! = 0 )
{
2016-03-11 20:13:48 +01:00
await e . Channel . SendMessage ( "💢🔰 Not a Valid war size" ) ;
return ;
}
var cw = new ClashWar ( enemyClan , size , e ) ;
//cw.Start();
wars . Add ( cw ) ;
2016-03-30 18:54:57 +02:00
cw . OnUserTimeExpired + = async ( u ) = >
{
try
{
2016-03-11 20:13:48 +01:00
await
e . Channel . SendMessage (
$"❗🔰**Claim from @{u} for a war against {cw.ShortPrint()} has expired.**" ) ;
2016-03-30 18:54:57 +02:00
}
catch { }
2016-03-11 20:13:48 +01:00
} ;
2016-03-30 18:54:57 +02:00
cw . OnWarEnded + = async ( ) = >
{
try
{
2016-03-11 20:13:48 +01:00
await e . Channel . SendMessage ( $"❗🔰**War against {cw.ShortPrint()} ended.**" ) ;
2016-03-30 18:54:57 +02:00
}
catch { }
2016-03-11 20:13:48 +01:00
} ;
await e . Channel . SendMessage ( $"❗🔰**CREATED CLAN WAR AGAINST {cw.ShortPrint()}**" ) ;
//war with the index X started.
} ) ;
cgb . CreateCommand ( Prefix + "sw" )
. Alias ( Prefix + "startwar" )
. Description ( "Starts a war with a given number." )
. Parameter ( "number" , ParameterType . Required )
2016-03-30 18:54:57 +02:00
. Do ( async e = >
{
2016-03-11 20:13:48 +01:00
var warsInfo = GetInfo ( e ) ;
2016-03-30 18:54:57 +02:00
if ( warsInfo = = null )
{
2016-03-11 20:13:48 +01:00
await e . Channel . SendMessage ( "💢🔰 **That war does not exist.**" ) ;
return ;
}
var war = warsInfo . Item1 [ warsInfo . Item2 ] ;
2016-03-30 18:54:57 +02:00
try
{
2016-03-11 20:13:48 +01:00
var startTask = war . Start ( ) ;
await e . Channel . SendMessage ( $"🔰**STARTED WAR AGAINST {war.ShortPrint()}**" ) ;
await startTask ;
2016-03-30 18:54:57 +02:00
}
catch
{
2016-03-11 20:13:48 +01:00
await e . Channel . SendMessage ( $"🔰**WAR AGAINST {war.ShortPrint()} IS ALREADY STARTED**" ) ;
}
} ) ;
cgb . CreateCommand ( Prefix + "listwar" )
. 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 )
2016-03-30 18:54:57 +02:00
. Do ( async e = >
{
2016-03-11 20:13:48 +01:00
// if number is null, print all wars in a short way
2016-03-30 18:54:57 +02:00
if ( string . IsNullOrWhiteSpace ( e . GetArg ( "number" ) ) )
{
2016-03-11 20:13:48 +01:00
//check if there are any wars
List < ClashWar > wars = null ;
ClashWars . TryGetValue ( e . Server . Id , out wars ) ;
2016-03-30 18:54:57 +02:00
if ( wars = = null | | wars . Count = = 0 )
{
2016-03-11 20:13:48 +01:00
await e . Channel . SendMessage ( "🔰 **No active wars.**" ) ;
return ;
}
var sb = new StringBuilder ( ) ;
sb . AppendLine ( "🔰 **LIST OF ACTIVE WARS**" ) ;
sb . AppendLine ( "**-------------------------**" ) ;
2016-03-30 18:54:57 +02:00
for ( var i = 0 ; i < wars . Count ; i + + )
{
2016-03-11 20:13:48 +01:00
sb . AppendLine ( $"**#{i + 1}.** `Enemy:` **{wars[i].EnemyClan}**" ) ;
sb . AppendLine ( $"\t\t`Size:` **{wars[i].Size} v {wars[i].Size}**" ) ;
sb . AppendLine ( "**-------------------------**" ) ;
}
await e . Channel . SendMessage ( sb . ToString ( ) ) ;
return ;
}
//if number is not null, print the war needed
var warsInfo = GetInfo ( e ) ;
2016-03-30 18:54:57 +02:00
if ( warsInfo = = null )
{
2016-03-11 20:13:48 +01:00
await e . Channel . SendMessage ( "💢🔰 **That war does not exist.**" ) ;
return ;
}
await e . Channel . SendMessage ( warsInfo . Item1 [ warsInfo . Item2 ] . ToString ( ) ) ;
} ) ;
cgb . CreateCommand ( Prefix + "claim" )
. Alias ( Prefix + "call" )
. Alias ( Prefix + "c" )
2016-03-19 03:50:51 +01:00
. Description ( $"Claims a certain base from a certain war. You can supply a name in the third optional argument to claim in someone else's place. \n**Usage**: {Prefix}call [war_number] [base_number] [optional_other_name]" )
2016-03-11 20:13:48 +01:00
. Parameter ( "number" )
. Parameter ( "baseNumber" )
. Parameter ( "other_name" , ParameterType . Unparsed )
2016-03-30 18:54:57 +02:00
. Do ( async e = >
{
2016-03-11 20:13:48 +01:00
var warsInfo = GetInfo ( e ) ;
2016-03-30 18:54:57 +02:00
if ( warsInfo = = null | | warsInfo . Item1 . Count = = 0 )
{
2016-03-11 20:13:48 +01:00
await e . Channel . SendMessage ( "💢🔰 **That war does not exist.**" ) ;
return ;
}
int baseNum ;
2016-03-30 18:54:57 +02:00
if ( ! int . TryParse ( e . GetArg ( "baseNumber" ) , out baseNum ) )
{
2016-03-11 20:13:48 +01:00
await e . Channel . SendMessage ( "💢🔰 **Invalid base number.**" ) ;
return ;
}
var usr =
string . IsNullOrWhiteSpace ( e . GetArg ( "other_name" ) ) ?
e . User . Name :
e . GetArg ( "other_name" ) ;
2016-03-30 18:54:57 +02:00
try
{
2016-03-11 20:13:48 +01:00
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()}" ) ;
2016-03-30 18:54:57 +02:00
}
catch ( Exception ex )
{
2016-03-11 20:13:48 +01:00
await e . Channel . SendMessage ( $"💢🔰 {ex.Message}" ) ;
}
} ) ;
cgb . CreateCommand ( Prefix + "cf" )
. Alias ( Prefix + "claimfinish" )
2016-03-19 03:50:51 +01:00
. 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]" )
2016-03-11 20:13:48 +01:00
. Parameter ( "number" , ParameterType . Required )
. Parameter ( "other_name" , ParameterType . Unparsed )
2016-03-30 18:54:57 +02:00
. Do ( async e = >
{
2016-03-11 20:13:48 +01:00
var warInfo = GetInfo ( e ) ;
2016-03-30 18:54:57 +02:00
if ( warInfo = = null | | warInfo . Item1 . Count = = 0 )
{
2016-03-11 20:13:48 +01:00
await e . Channel . SendMessage ( "💢🔰 **That war does not exist.**" ) ;
return ;
}
var usr =
string . IsNullOrWhiteSpace ( e . GetArg ( "other_name" ) ) ?
e . User . Name :
e . GetArg ( "other_name" ) ;
var war = warInfo . Item1 [ warInfo . Item2 ] ;
2016-03-30 18:54:57 +02:00
try
{
2016-03-11 20:13:48 +01:00
var baseNum = war . FinishClaim ( usr ) ;
await e . Channel . SendMessage ( $"❗🔰{e.User.Mention} **DESTROYED** a base #{baseNum + 1} in a war against {war.ShortPrint()}" ) ;
2016-03-30 18:54:57 +02:00
}
catch ( Exception ex )
{
2016-03-11 20:13:48 +01:00
await e . Channel . SendMessage ( $"💢🔰 {ex.Message}" ) ;
}
} ) ;
cgb . CreateCommand ( Prefix + "unclaim" )
. Alias ( Prefix + "uncall" )
. Alias ( Prefix + "uc" )
2016-03-19 03:50:51 +01:00
. 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]" )
2016-03-11 20:13:48 +01:00
. Parameter ( "number" , ParameterType . Required )
. Parameter ( "other_name" , ParameterType . Unparsed )
2016-03-30 18:54:57 +02:00
. Do ( async e = >
{
2016-03-11 20:13:48 +01:00
var warsInfo = GetInfo ( e ) ;
2016-03-30 18:54:57 +02:00
if ( warsInfo = = null | | warsInfo . Item1 . Count = = 0 )
{
2016-03-11 20:13:48 +01:00
await e . Channel . SendMessage ( "💢🔰 **That war does not exist.**" ) ;
return ;
}
var usr =
string . IsNullOrWhiteSpace ( e . GetArg ( "other_name" ) ) ?
e . User . Name :
e . GetArg ( "other_name" ) ;
2016-03-30 18:54:57 +02:00
try
{
2016-03-11 20:13:48 +01:00
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()}" ) ;
2016-03-30 18:54:57 +02:00
}
catch ( Exception ex )
{
2016-03-11 20:13:48 +01:00
await e . Channel . SendMessage ( $"💢🔰 {ex.Message}" ) ;
}
} ) ;
cgb . CreateCommand ( Prefix + "endwar" )
. Alias ( Prefix + "ew" )
. Description ( $"Ends the war with a given index.\n**Usage**:{Prefix}ew [war_number]" )
. Parameter ( "number" )
2016-03-30 18:54:57 +02:00
. Do ( async e = >
{
2016-03-11 20:13:48 +01:00
var warsInfo = GetInfo ( e ) ;
2016-03-30 18:54:57 +02:00
if ( warsInfo = = null )
{
2016-03-11 20:13:48 +01:00
await e . Channel . SendMessage ( "💢🔰 That war does not exist." ) ;
return ;
}
warsInfo . Item1 [ warsInfo . Item2 ] . End ( ) ;
var size = warsInfo . Item1 [ warsInfo . Item2 ] . Size ;
warsInfo . Item1 . RemoveAt ( warsInfo . Item2 ) ;
} ) ;
} ) ;
}
2016-03-30 18:54:57 +02:00
private static Tuple < List < ClashWar > , int > GetInfo ( CommandEventArgs e )
{
2016-03-11 20:13:48 +01:00
//check if there are any wars
List < ClashWar > wars = null ;
ClashWars . TryGetValue ( e . Server . Id , out wars ) ;
2016-03-30 18:54:57 +02:00
if ( wars = = null | | wars . Count = = 0 )
{
2016-03-11 20:13:48 +01:00
return null ;
}
// get the number of the war
int num ;
if ( string . IsNullOrWhiteSpace ( e . GetArg ( "number" ) ) )
num = 0 ;
2016-03-30 18:54:57 +02:00
else if ( ! int . TryParse ( e . GetArg ( "number" ) , out num ) | | num > wars . Count )
{
2016-03-11 20:13:48 +01:00
return null ;
}
num - = 1 ;
//get the actual war
return new Tuple < List < ClashWar > , int > ( wars , num ) ;
}
}
}