Browse Source

Added Version and Invite modules.

Finished PingMe module.
Fixed bugs.
tags/3.0.0
Teknikode 4 years ago
parent
commit
a95e397dd1

+ 33
- 0
Combot.sln.DotSettings View File

@@ -0,0 +1,33 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Description/@EntryValue">Module</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Text/@EntryValue">namespace $namespace$&#xD;
{&#xD;
public class $filename$ : Module&#xD;
{&#xD;
public override void Initialize()&#xD;
{&#xD;
} &#xD;
&#xD;
public override void ParseCommand(CommandMessage command)&#xD;
{&#xD;
}&#xD;
}&#xD;
}</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Reformat/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/ShortenQualifiedReferences/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Categories/=Imported_00201_002F29_002F2015/@EntryIndexedValue">Imported 1/29/2015</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/CustomProperties/=FileName/@EntryIndexedValue">NewModule</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/CustomProperties/=Extension/@EntryIndexedValue">cs</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/CustomProperties/=ValidateFileName/@EntryIndexedValue">False</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Applicability/=File/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Scope/=E8F0594528C33E45BBFEC6CFE851095D/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Scope/=E8F0594528C33E45BBFEC6CFE851095D/Type/@EntryValue">InCSharpProjectFile</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/Expression/@EntryValue">getCurrentNamespace()</s:String>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/InitialRange/@EntryValue">-1</s:Int64>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/Order/@EntryValue">0</s:Int64>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/Expression/@EntryValue">fileDefaultNamespace()</s:String>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/InitialRange/@EntryValue">-1</s:Int64>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/Order/@EntryValue">1</s:Int64></wpf:ResourceDictionary>

+ 109
- 24
Combot/Bot.cs View File

@@ -1,15 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Reflection;
using System.Threading.Tasks;
using System.Threading;
using Combot.IRCServices;
using Combot.Configurations;
using Combot.IRCServices.Messaging;
using Combot.Modules;
using Module = Combot.Modules.Module;

namespace Combot
{
@@ -19,20 +16,25 @@ namespace Combot
public event Action<BotError> ErrorEvent;
public ServerConfig ServerConfig;
public IRC IRC;
public List<Module> Modules;
public bool Connected = false;
public bool LoggedIn = false;
public static Dictionary<PrivilegeMode, AccessType> AccessTypeMapping = new Dictionary<PrivilegeMode, AccessType>() { { PrivilegeMode.v, AccessType.Voice }, { PrivilegeMode.h, AccessType.HalfOperator }, { PrivilegeMode.o, AccessType.Operator }, { PrivilegeMode.a, AccessType.SuperOperator }, { PrivilegeMode.q, AccessType.Founder } };

private List<Module> _Modules;
private bool GhostSent;

public Bot(ServerConfig serverConfig)
{
IRC = new IRC();
_Modules = new List<Module>();
Modules = new List<Module>();
GhostSent = false;
ServerConfig = serverConfig;
IRC.ConnectEvent += HandleConnectEvent;
IRC.DisconnectEvent += HandleDisconnectEvent;
IRC.Message.ServerReplyEvent += HandleReplyEvent;
IRC.Message.ChannelMessageReceivedEvent += HandleChannelMessageReceivedEvent;
IRC.Message.JoinChannelEvent += HandleJoinEvent;
IRC.Message.KickEvent += HandleKickEvent;

LoadModules();
}
@@ -42,6 +44,7 @@ namespace Combot
/// </summary>
public void Connect()
{
GhostSent = false;
bool serverConnected = false;
int i = 0;
do
@@ -68,7 +71,13 @@ namespace Combot

if (serverConnected)
{
IRC.Login(ServerConfig.Name, new Nick() { Nickname = ServerConfig.Nickname, Host = Dns.GetHostName(), Realname = ServerConfig.Realname, Username = ServerConfig.Username });
IRC.Login(ServerConfig.Name, new Nick()
{
Nickname = ServerConfig.Nickname,
Host = Dns.GetHostName(),
Realname = ServerConfig.Realname,
Username = ServerConfig.Username
});
}
}

@@ -79,18 +88,19 @@ namespace Combot
{
IRC.Disconnect();
Connected = false;
LoggedIn = false;
}

public void LoadModules()
{
foreach (Module module in ServerConfig.Modules)
{
if (module.Enabled && !_Modules.Exists(mod => mod.ClassName == module.ClassName))
if (module.Enabled && !Modules.Exists(mod => mod.ClassName == module.ClassName))
{
Module loadedModule = module.CreateInstance(this);
if (loadedModule.Loaded)
{
_Modules.Add(loadedModule);
Modules.Add(loadedModule);
}
}
}
@@ -106,18 +116,92 @@ namespace Combot
Connected = false;
}

private void HandleReplyEvent(object sender, IReply e)
private void HandleJoinEvent(object sender, JoinChannelInfo info)
{
if (info.Nick.Nickname == IRC.Nickname)
{
if (!ServerConfig.Channels.Exists(chan => chan.Name == info.Channel))
{
ChannelConfig chanConfig = new ChannelConfig();
chanConfig.Name = info.Channel;
ServerConfig.Channels.Add(chanConfig);
ServerConfig.Save();
}
}
}

private void HandleKickEvent(object sender, KickInfo info)
{
if (info.KickedNick.Nickname == IRC.Nickname)
{
ServerConfig.Channels.RemoveAll(chan => chan.Name == info.Channel);
ServerConfig.Save();
}
}

private async void HandleReplyEvent(object sender, IReply e)
{
if (e.GetType() == typeof(ServerReplyMessage))
{
ServerReplyMessage reply = (ServerReplyMessage)e;
// If the reply is Welcome, that means we are fully connected to the server and can now join the auto-join channels.
if (reply.ReplyCode == IRCReplyCode.RPL_WELCOME && Connected)
switch (reply.ReplyCode)
{
foreach (ChannelConfig channel in ServerConfig.Channels)
{
IRC.SendJoin(channel.Name, channel.Key);
}
case IRCReplyCode.RPL_WELCOME:
// If the reply is Welcome, that means we are fully connected to the server.
LoggedIn = true;
if (!GhostSent && IRC.Nickname != ServerConfig.Nickname)
{
IRC.SendPrivateMessage("NickServ", string.Format("GHOST {0} {1}", ServerConfig.Nickname, ServerConfig.Password));
Thread.Sleep(1000);
IRC.SendNick(ServerConfig.Nickname);
GhostSent = true;
}
// Identify to NickServ if need be
IRC.SendPrivateMessage("NickServ", string.Format("IDENTIFY {0}", ServerConfig.Password));

// Join all required channels
// Delay joining channels for configured time
Thread.Sleep(ServerConfig.JoinDelay);
foreach (ChannelConfig channel in ServerConfig.Channels)
{
IRC.SendJoin(channel.Name, channel.Key);
}
break;
}
}
else if (e.GetType() == typeof(ServerErrorMessage))
{
ServerErrorMessage error = (ServerErrorMessage) e;
switch (error.ErrorCode)
{
case IRCErrorCode.ERR_NOTREGISTERED:
if (ServerConfig.Password != string.Empty && ServerConfig.Email != string.Empty)
{
IRC.SendPrivateMessage("NickServ", string.Format("REGISTER {0} {1}", ServerConfig.Password, ServerConfig.Email));
}
break;
case IRCErrorCode.ERR_NICKNAMEINUSE:
if (LoggedIn == false)
{
string nick = string.Empty;
if (IRC.Nickname == ServerConfig.Nickname && ServerConfig.SecondaryNickname != string.Empty)
{
nick = ServerConfig.SecondaryNickname;
}
else
{
Random rand = new Random();
nick = string.Format("{0}_{1}", ServerConfig.Nickname, rand.Next(100000).ToString());
}
IRC.Login(ServerConfig.Name, new Nick()
{
Nickname = nick,
Host = Dns.GetHostName(),
Realname = ServerConfig.Realname,
Username = ServerConfig.Username
});
}
break;
}
}
}
@@ -144,7 +228,7 @@ namespace Combot
List<string> argsOnly = msgArgs.ToList();
argsOnly.RemoveAt(0);

Module module = _Modules.Find(mod => mod.Commands.Exists(c => c.Triggers.Contains(command)) && mod.Loaded);
Module module = Modules.Find(mod => mod.Commands.Exists(c => c.Triggers.Contains(command)) && mod.Loaded);
if (module != null)
{
Command cmd = module.Commands.Find(c => c.Triggers.Contains(command));
@@ -165,17 +249,18 @@ namespace Combot
newCommand.Command = command;
if (argsOnly.Count > 0)
{
string[] argSplit = argsOnly.First()
.Split(new[] {' '}, cmd.Arguments.Count + 1, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < cmd.Arguments.Count; i++)
string[] argSplit = argsOnly.First().Split(new[] {' '}, cmd.Arguments.Count + 1, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < cmd.Arguments.Count && i <= argSplit.GetUpperBound(0); i++)
{
newCommand.Arguments.Add(argSplit[i]);
newCommand.Arguments.Add(cmd.Arguments[i].Name, argSplit[i]);
}
}

if (CommandReceivedEvent != null)
if (cmd.Arguments.FindAll(arg => arg.Required).Count <= newCommand.Arguments.Count)
{
CommandReceivedEvent(newCommand);
if (CommandReceivedEvent != null)
{
CommandReceivedEvent(newCommand);
}
}
}
}

+ 2
- 0
Combot/Combot.csproj View File

@@ -69,7 +69,9 @@
<Compile Include="Help.cs" />
<Compile Include="Modules\CommandArgument.cs" />
<Compile Include="Modules\CommandMessage.cs" />
<Compile Include="Modules\ModuleClasses\Invite.cs" />
<Compile Include="Modules\ModuleClasses\PingMe.cs" />
<Compile Include="Modules\ModuleClasses\Version.cs" />
<Compile Include="Modules\Option.cs" />
<Compile Include="Types.cs" />
<Compile Include="Methods.cs" />

+ 10
- 2
Combot/Configurations/ServerConfig.cs View File

@@ -12,17 +12,21 @@ namespace Combot.Configurations
{
public event Action ModifyEvent;
public string Name { get; set; }
public bool AutoConnect { get; set; }
public string CommandPrefix { get; set; }
public string Nickname { get; set; }
public string SecondaryNickname { get; set; }
public string Realname { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Email { get; set; }
public List<string> Owners { get; set; }
public List<string> ChannelBlacklist { get; set; }
public List<string> NickBlacklist { get; set; }
public List<HostConfig> Hosts { get; set; }
public List<ChannelConfig> Channels { get; set; }
public List<Module> Modules { get; set; }
public bool AutoConnect { get; set; }
public string CommandPrefix { get; set; }
public int JoinDelay { get; set; }

public ServerConfig()
{
@@ -34,6 +38,7 @@ namespace Combot.Configurations
Name = string.Empty;
AutoConnect = false;
CommandPrefix = string.Empty;
JoinDelay = 0;
Owners = new List<string>();
ChannelBlacklist = new List<string>();
NickBlacklist = new List<string>();
@@ -41,8 +46,11 @@ namespace Combot.Configurations
Modules = new List<Module>();
Hosts = new List<HostConfig>();
Nickname = string.Empty;
SecondaryNickname = string.Empty;
Realname = string.Empty;
Username = string.Empty;
Password = string.Empty;
Email = string.Empty;
}

public void Save()

+ 3
- 0
Combot/Modules/Command.cs View File

@@ -6,6 +6,7 @@ namespace Combot.Modules
{
public string Name { get; set; }
public string Description { get; set; }
public bool Enabled { get; set; }
public List<string> ChannelBlacklist { get; set; }
public List<string> NickBlacklist { get; set; }
public List<string> Triggers { get; set; }
@@ -28,6 +29,7 @@ namespace Combot.Modules
{
Name = string.Empty;
Description = string.Empty;
Enabled = true;
Triggers = new List<string>();
ChannelBlacklist = new List<string>();
NickBlacklist = new List<string>();
@@ -41,6 +43,7 @@ namespace Combot.Modules
{
Name = command.Name;
Description = command.Description;
Enabled = command.Enabled;
Triggers = new List<string>();
foreach (string trigger in command.Triggers)
{

+ 0
- 7
Combot/Modules/CommandArgument.cs View File

@@ -6,7 +6,6 @@ namespace Combot.Modules
{
public string Name { get; set; }
public string Description { get; set; }
public List<string> Triggers { get; set; }
public bool Required { get; set; }

public CommandArgument()
@@ -18,7 +17,6 @@ namespace Combot.Modules
{
Name = string.Empty;
Description = string.Empty;
Triggers = new List<string>();
Required = false;
}

@@ -26,11 +24,6 @@ namespace Combot.Modules
{
Name = argument.Name;
Description = argument.Description;
Triggers = new List<string>();
foreach (string trigger in argument.Triggers)
{
Triggers.Add(trigger);
}
Required = argument.Required;
}
}

+ 2
- 2
Combot/Modules/CommandMessage.cs View File

@@ -11,7 +11,7 @@ namespace Combot.Modules
public Nick Nick { get; set; }
public DateTime TimeStamp { get; set; }
public string Command { get; set; }
public List<string> Arguments { get; set; }
public Dictionary<string, dynamic> Arguments { get; set; }

public CommandMessage()
{
@@ -20,7 +20,7 @@ namespace Combot.Modules
Nick = new Nick();
TimeStamp = DateTime.Now;
Command = string.Empty;
Arguments = new List<string>();
Arguments = new Dictionary<string, dynamic>();
}
}


+ 16
- 0
Combot/Modules/Module.cs View File

@@ -38,6 +38,7 @@ namespace Combot.Modules
&& !ChannelBlacklist.Contains(command.Location)
&& !NickBlacklist.Contains(command.Nick.Nickname)
&& Commands.Exists(c => c.Triggers.Contains(command.Command)
&& c.Enabled
&& !c.ChannelBlacklist.Contains(command.Location)
&& !c.NickBlacklist.Contains(command.Nick.Nickname)
)
@@ -132,5 +133,20 @@ namespace Combot.Modules

return newModule;
}

public dynamic GetOptionValue(string name)
{
dynamic foundValue = null;
Option foundOption = Options.Find(opt => opt.Name == name);
if (foundOption != null)
{
foundValue = foundOption.Value;
if (foundValue == null)
{
foundValue = string.Empty;
}
}
return foundValue;
}
}
}

+ 30
- 0
Combot/Modules/ModuleClasses/Invite.cs View File

@@ -0,0 +1,30 @@
using Combot.IRCServices.Messaging;

namespace Combot.Modules.ModuleClasses
{
public class Invite : Module
{
public override void Initialize()
{
Bot.IRC.Message.InviteChannelEvent += HandleInvite;
}

private void HandleInvite(object sender, InviteChannelInfo inviteInfo)
{
if (!Bot.ServerConfig.ChannelBlacklist.Contains(inviteInfo.Channel))
{
Bot.IRC.SendJoin(inviteInfo.Channel);
string helpMessage = string.Empty;
if (Bot.Modules.Exists(module => module.Commands.Exists(cmd => cmd.Triggers.Contains("help") && cmd.Enabled)))
{
helpMessage = string.Format(" For more information on what I can do, just type: {0}help", Bot.ServerConfig.CommandPrefix);
}
Bot.IRC.SendPrivateMessage(inviteInfo.Channel, string.Format("{0} has invited me to this channel. If you would like me to leave, just kick me.{1}", inviteInfo.Requester.Nickname, helpMessage));
}
else
{
Bot.IRC.SendNotice(inviteInfo.Requester.Nickname, "I am unable to join that channel.");
}
}
}
}

+ 1
- 1
Combot/Modules/ModuleClasses/PingMe.cs View File

@@ -37,7 +37,7 @@ namespace Combot.Modules.ModuleClasses
}
pingList.Add(tmpItem);
listLock.ExitWriteLock();
Bot.IRC.SendCTCP(command.Nick.Nickname, "PING", epoch.ToString());
Bot.IRC.SendCTCPMessage(command.Nick.Nickname, "PING", epoch.ToString());
}
}


+ 92
- 0
Combot/Modules/ModuleClasses/Version.cs View File

@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using Combot.IRCServices.Messaging;

namespace Combot.Modules.ModuleClasses
{
public class Version : Module
{
private List<VersionItem> versionList;
private ReaderWriterLockSlim listLock;

public override void Initialize()
{
listLock = new ReaderWriterLockSlim();
versionList = new List<VersionItem>();
Bot.IRC.Message.CTCPMessageRecievedEvent += HandleVersionQuery;
Bot.IRC.Message.CTCPNoticeRecievedEvent += HandleVersionResponse;
Bot.CommandReceivedEvent += HandleCommandEvent;
}

public override void ParseCommand(CommandMessage command)
{
if (Commands.Find(cmd => cmd.Name == "Version Check").Triggers.Contains(command.Command))
{
VersionItem tmpItem = new VersionItem();
tmpItem.Location = command.Location;
tmpItem.LocationType = command.LocationType;
tmpItem.Nick = command.Arguments["Nickname"];
listLock.EnterWriteLock();
if (versionList.Exists(item => item.Nick == command.Arguments["Nickname"]))
{
versionList.RemoveAll(item => item.Nick == command.Arguments["Nickname"]);
}
versionList.Add(tmpItem);
listLock.ExitWriteLock();
Bot.IRC.SendCTCPMessage(command.Arguments["Nickname"], "VERSION");
}
}

public void HandleVersionQuery(object sender, CTCPMessage message)
{
if (message.Command.ToLower() == "version")
{
Bot.IRC.SendCTCPNotice(message.Sender.Nickname, "VERSION", string.Format("Combot v{0} on {1}", Assembly.GetExecutingAssembly().GetName().Version, GetOptionValue("Machine Reply")));
}
}

public void HandleVersionResponse(object sender, CTCPMessage message)
{
if (message.Command == "VERSION")
{
listLock.EnterReadLock();
VersionItem versionItem = versionList.Find(item => item.Nick == message.Sender.Nickname);
listLock.ExitReadLock();
if (versionItem != null)
{
switch (versionItem.LocationType)
{
case LocationType.Channel:
Bot.IRC.SendPrivateMessage(versionItem.Location, string.Format("[{0}] Using version: {1}", versionItem.Nick, message.Arguments));
break;
case LocationType.Query:
Bot.IRC.SendPrivateMessage(versionItem.Nick, string.Format("[{0}] Using version: {1}", versionItem.Nick, message.Arguments));
break;
case LocationType.Notice:
Bot.IRC.SendNotice(versionItem.Nick, string.Format("[{0}] Using version: {1}", versionItem.Nick, message.Arguments));
break;
}
listLock.EnterWriteLock();
versionList.RemoveAll(item => item.Nick == versionItem.Nick);
listLock.ExitWriteLock();
}
}
}
}

public class VersionItem
{
public string Nick { get; set; }
public string Location { get; set; }
public LocationType LocationType { get; set; }

public VersionItem()
{
Nick = string.Empty;
Location = string.Empty;
LocationType = LocationType.Channel;
}
}
}

+ 31
- 2
IRCServices/IRCSend.cs View File

@@ -57,7 +57,7 @@ namespace Combot.IRCServices
/// <param name="recipient"></param>
/// <param name="command"></param>
/// <param name="message"></param>
public void SendCTCP(string recipient, string command, string message = "")
public void SendCTCPMessage(string recipient, string command, string message = "")
{
if (message != string.Empty)
{
@@ -66,7 +66,7 @@ namespace Combot.IRCServices
SendTCPMessage(string.Format("PRIVMSG {0} :\u0001{1}{2}\u0001", recipient, command, message));
}

public void SendCTCP(List<string> recipients, string command, string message)
public void SendCTCPMessage(List<string> recipients, string command, string message)
{
string recipient_list = string.Empty;
foreach (string recipient in recipients)
@@ -80,6 +80,35 @@ namespace Combot.IRCServices
SendTCPMessage(string.Format("PRIVMSG {0} :\u0001{1}{2}\u0001", recipient_list.TrimEnd(','), command, message));
}

/// <summary>
/// Sends a CTCP command and optional message to a nick or channel
/// </summary>
/// <param name="recipient"></param>
/// <param name="command"></param>
/// <param name="message"></param>
public void SendCTCPNotice(string recipient, string command, string message = "")
{
if (message != string.Empty)
{
message = " " + message;
}
SendTCPMessage(string.Format("NOTICE {0} :\u0001{1}{2}\u0001", recipient, command, message));
}

public void SendCTCPNotice(List<string> recipients, string command, string message)
{
string recipient_list = string.Empty;
foreach (string recipient in recipients)
{
recipient_list += recipient + ",";
}
if (message != string.Empty)
{
message = " " + message;
}
SendTCPMessage(string.Format("NOTICE {0} :\u0001{1}{2}\u0001", recipient_list.TrimEnd(','), command, message));
}

/// <summary>
/// Sends the connection password
/// </summary>

+ 134
- 62
IRCServices/Messaging/Messages.cs View File

@@ -42,7 +42,7 @@ namespace Combot.IRCServices.Messaging
/// Parses the raw messages coming from the server and triggers an event based on the type of message.
/// </summary>
/// <param name="tcpMessage">The raw string read from the TCP stream.</param>
internal void ParseTCPMessage(string tcpMessage)
internal async void ParseTCPMessage(string tcpMessage)
{
DateTime messageTime = DateTime.Now;
Regex messageRegex = new Regex(@"^:(?<Sender>[^\s]+)\s(?<Type>[^\s]+)\s(?<Recipient>[^\s]+)\s?:?(?<Args>.*)", RegexOptions.None);
@@ -80,17 +80,35 @@ namespace Combot.IRCServices.Messaging
// The message was a reply to a command sent
if (Enum.IsDefined(typeof(IRCReplyCode), replyCode))
{
if (ServerReplyEvent != null)
await Task.Run(() =>
{
ServerReplyEvent(this, new ServerReplyMessage() { TimeStamp = messageTime, ReplyCode = (IRCReplyCode)replyCode, Message = args });
}
if (ServerReplyEvent != null)
{
ServerReplyEvent(this,
new ServerReplyMessage()
{
TimeStamp = messageTime,
ReplyCode = (IRCReplyCode) replyCode,
Message = args
});
}
});
}
else if (Enum.IsDefined(typeof(IRCErrorCode), replyCode))
{
if (ServerReplyEvent != null)
await Task.Run(() =>
{
ServerReplyEvent(this, new ServerErrorMessage() { TimeStamp = messageTime, ErrorCode = (IRCErrorCode)replyCode, Message = args });
}
if (ServerReplyEvent != null)
{
ServerReplyEvent(this,
new ServerErrorMessage()
{
TimeStamp = messageTime,
ErrorCode = (IRCErrorCode) replyCode,
Message = args
});
}
});
}
}
else
@@ -112,10 +130,13 @@ namespace Combot.IRCServices.Messaging
ctcpMessage.Command = ctcpMatch.Groups["Command"].Value;
ctcpMessage.Arguments = ctcpMatch.Groups["Args"].Value;

if (CTCPMessageRecievedEvent != null)
await Task.Run(() =>
{
CTCPMessageRecievedEvent(this, ctcpMessage);
}
if (CTCPMessageRecievedEvent != null)
{
CTCPMessageRecievedEvent(this, ctcpMessage);
}
});
}
else
{
@@ -131,10 +152,13 @@ namespace Combot.IRCServices.Messaging
};
msg.Message = args;

if (ChannelMessageReceivedEvent != null)
await Task.Run(() =>
{
ChannelMessageReceivedEvent(this, msg);
}
if (ChannelMessageReceivedEvent != null)
{
ChannelMessageReceivedEvent(this, msg);
}
});
}
else
{
@@ -147,10 +171,13 @@ namespace Combot.IRCServices.Messaging
};
msg.Message = args;

if (PrivateMessageReceivedEvent != null)
await Task.Run(() =>
{
PrivateMessageReceivedEvent(this, msg);
}
if (PrivateMessageReceivedEvent != null)
{
PrivateMessageReceivedEvent(this, msg);
}
});
}
}
break;
@@ -169,10 +196,13 @@ namespace Combot.IRCServices.Messaging
ctcpMessage.Command = ctcpMatch.Groups["Command"].Value;
ctcpMessage.Arguments = ctcpMatch.Groups["Args"].Value;

if (CTCPNoticeRecievedEvent != null)
await Task.Run(() =>
{
CTCPNoticeRecievedEvent(this, ctcpMessage);
}
if (CTCPNoticeRecievedEvent != null)
{
CTCPNoticeRecievedEvent(this, ctcpMessage);
}
});
}
if (recipient.StartsWith("&") || recipient.StartsWith("#"))
{
@@ -181,10 +211,13 @@ namespace Combot.IRCServices.Messaging
msg.Sender = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost };
msg.Message = args;

if (ChannelNoticeReceivedEvent != null)
await Task.Run(() =>
{
ChannelNoticeReceivedEvent(this, msg);
}
if (ChannelNoticeReceivedEvent != null)
{
ChannelNoticeReceivedEvent(this, msg);
}
});
}
else
{
@@ -192,10 +225,13 @@ namespace Combot.IRCServices.Messaging
msg.Sender = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost };
msg.Message = args;

if (PrivateNoticeReceivedEvent != null)
await Task.Run(() =>
{
PrivateNoticeReceivedEvent(this, msg);
}
if (PrivateNoticeReceivedEvent != null)
{
PrivateNoticeReceivedEvent(this, msg);
}
});
}
break;
// The message was a mode change message for a channel or nick
@@ -256,10 +292,13 @@ namespace Combot.IRCServices.Messaging
}
}

if (ChannelModeChangeEvent != null)
await Task.Run(() =>
{
ChannelModeChangeEvent(this, modeMsg);
}
if (ChannelModeChangeEvent != null)
{
ChannelModeChangeEvent(this, modeMsg);
}
});
}
else
{
@@ -289,10 +328,13 @@ namespace Combot.IRCServices.Messaging
}
}

if (UserModeChangeEvent != null)
await Task.Run(() =>
{
UserModeChangeEvent(this, modeMsg);
}
if (UserModeChangeEvent != null)
{
UserModeChangeEvent(this, modeMsg);
}
});
}
break;
// The message was a topic change for a channel
@@ -302,10 +344,13 @@ namespace Combot.IRCServices.Messaging
topicMsg.Nick = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost };
topicMsg.Topic = args;

if (TopicChangeEvent != null)
await Task.Run(() =>
{
TopicChangeEvent(this, topicMsg);
}
if (TopicChangeEvent != null)
{
TopicChangeEvent(this, topicMsg);
}
});
break;
// The message was a nick change
case "NICK":
@@ -313,10 +358,13 @@ namespace Combot.IRCServices.Messaging
nickMsg.OldNick = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost };
nickMsg.NewNick = new Nick() { Nickname = recipient.Remove(0, 1) };

if (NickChangeEvent != null)
await Task.Run(() =>
{
NickChangeEvent(this, nickMsg);
}
if (NickChangeEvent != null)
{
NickChangeEvent(this, nickMsg);
}
});
break;
// The message was an invite to a channel
case "INVITE":
@@ -325,10 +373,13 @@ namespace Combot.IRCServices.Messaging
inviteMsg.Recipient = new Nick() { Nickname = recipient };
inviteMsg.Channel = args;

if (InviteChannelEvent != null)
await Task.Run(() =>
{
InviteChannelEvent(this, inviteMsg);
}
if (InviteChannelEvent != null)
{
InviteChannelEvent(this, inviteMsg);
}
});
break;
// The message was a nick joining a channel
case "JOIN":
@@ -336,10 +387,13 @@ namespace Combot.IRCServices.Messaging
joinMsg.Channel = recipient.TrimStart(':');
joinMsg.Nick = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost };

if (JoinChannelEvent != null)
await Task.Run(() =>
{
JoinChannelEvent(this, joinMsg);
}
if (JoinChannelEvent != null)
{
JoinChannelEvent(this, joinMsg);
}
});
break;
// The message was a nick parting a channel
case "PART":
@@ -347,10 +401,13 @@ namespace Combot.IRCServices.Messaging
partMsg.Channel = recipient;
partMsg.Nick = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost };

if (PartChannelEvent != null)
await Task.Run(() =>
{
PartChannelEvent(this, partMsg);
}
if (PartChannelEvent != null)
{
PartChannelEvent(this, partMsg);
}
});
break;
// The message was a nick being kicked from a channel
case "KICK":
@@ -365,10 +422,13 @@ namespace Combot.IRCServices.Messaging
reasonArgs.RemoveAt(0);
kickMsg.Reason = string.Join(" ", reasonArgs.ToArray()).Remove(0, 1);

if (KickEvent != null)
await Task.Run(() =>
{
KickEvent(this, kickMsg);
}
if (KickEvent != null)
{
KickEvent(this, kickMsg);
}
});
break;
// The message was a nick quiting the irc network
case "QUIT":
@@ -376,10 +436,13 @@ namespace Combot.IRCServices.Messaging
quitMsg.Nick = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost };
quitMsg.Message = recipient.Remove(0, 1);

if (QuitEvent != null)
await Task.Run(() =>
{
QuitEvent(this, quitMsg);
}
if (QuitEvent != null)
{
QuitEvent(this, quitMsg);
}
});
break;
default:
break;
@@ -392,10 +455,13 @@ namespace Combot.IRCServices.Messaging
PingInfo ping = new PingInfo();
ping.Message = match.Groups["Message"].Value;

if (PingEvent != null)
await Task.Run(() =>
{
PingEvent(this, ping);
}
if (PingEvent != null)
{
PingEvent(this, ping);
}
});
}
else if (pongRegex.IsMatch(message)) // The message was a PONG
{
@@ -403,10 +469,13 @@ namespace Combot.IRCServices.Messaging
PongInfo pong = new PongInfo();
pong.Message = match.Groups["Message"].Value;

if (PongEvent != null)
await Task.Run(() =>
{
PongEvent(this, pong);
}
if (PongEvent != null)
{
PongEvent(this, pong);
}
});
}
else if (errorRegex.IsMatch(message)) // The message was a server error
{
@@ -420,14 +489,17 @@ namespace Combot.IRCServices.Messaging
}
}

if (RawMessageEvent != null)
await Task.Run(() =>
{
RawMessageEvent(this, message);
}
if (RawMessageEvent != null)
{
RawMessageEvent(this, message);
}
});
}
}

internal bool GetReply(List<IRCReplyCode> ReplyCodes, List<IRCErrorCode> ErrorCodes)
public bool GetReply(List<IRCReplyCode> ReplyCodes, List<IRCErrorCode> ErrorCodes)
{
GetReply reply = new GetReply();
reply.Replies = ReplyCodes;

+ 60
- 6
Interface/ViewModels/MainViewModel.cs View File

@@ -43,18 +43,20 @@ namespace Interface.ViewModels
{
Name = "#testing",
Key = string.Empty
},
}/*,
new ChannelConfig()
{
Name = "#/g/technology",
Name = "#rice",
Key = string.Empty
}
}*/
};
serverConfig.Name = "Rizon";
serverConfig.Nickname = "Combot_V3";
serverConfig.Realname = "Combot_Realname";
serverConfig.Username = "Combot_Username";
serverConfig.Password = "24121exe";
serverConfig.CommandPrefix = ".";
serverConfig.JoinDelay = 1000;
serverConfig.Hosts = new List<HostConfig> { new HostConfig() { Host = "irc.rizon.net", Port = 6667 } };
serverConfig.Modules = new List<Module>
{
@@ -69,7 +71,7 @@ namespace Interface.ViewModels
{
Name = "Ping Me",
Description = "Checks the time it takes for a PING to be returned from a nick.",
AllowedAccess = new List<AccessType>()
AllowedAccess = new List<AccessType>
{
AccessType.User,
AccessType.Voice,
@@ -79,27 +81,74 @@ namespace Interface.ViewModels
AccessType.Founder,
AccessType.Owner
},
Triggers = new List<string>()
Triggers = new List<string>
{
"pingme"
}
}
}
},
new Module
{
Name = "Invite",
ClassName = "Invite",
Enabled = true
},
new Module
{
Name = "Version",
ClassName = "Version",
Enabled = true,
Commands = new List<Command>
{
new Command
{
Name = "Version Check",
Description = "Sends a version CTCP request and displays the response.",
AllowedAccess = new List<AccessType>
{
AccessType.User,
AccessType.Voice,
AccessType.HalfOperator,
AccessType.Operator,
AccessType.SuperOperator,
AccessType.Founder,
AccessType.Owner
},
Triggers = new List<string>
{
"version",
"ver"
},
Arguments = new List<CommandArgument>
{
new CommandArgument
{
Name = "Nickname",
Description = "The nickname you want to query for version information.",
Required = true
}
}
}
}
}
};
Config.Servers.Add(serverConfig);
Config.SaveServers();
Config.LoadServers();

foreach (ServerConfig server in Config.Servers)
{
Bot Combot = new Bot(server);

/*
Combot.IRC.Message.ErrorMessageEvent += ErrorMessageHandler;
Combot.IRC.Message.ServerReplyEvent += ServerReplyHandler;
Combot.IRC.Message.ChannelMessageReceivedEvent += ChannelMessageReceivedHandler;
Combot.IRC.Message.ChannelNoticeReceivedEvent += ChannelNoticeReceivedHandler;
Combot.IRC.Message.PrivateMessageReceivedEvent += PrivateMessageReceivedHandler;
Combot.IRC.Message.PrivateNoticeReceivedEvent += PrivateNoticeReceivedHandler;
*/
Combot.IRC.Message.RawMessageEvent += RawMessageHandler;

Combot.IRC.ConnectEvent += ConnectHandler;
Combot.IRC.DisconnectEvent += DisconnectHandler;
@@ -111,6 +160,11 @@ namespace Interface.ViewModels
ToggleConnection = new DelegateCommand(ExecuteToggleConnection, CanToggleConnection);
}

private void RawMessageHandler(object sender, string message)
{
CurrentBuffer += message + Environment.NewLine;
}

private void TCPErrorHandler(Combot.IRCServices.TCP.TCPError error)
{
CurrentBuffer += string.Format("[{0}] {1}", error.Code.ToString(), error.Message) + Environment.NewLine;

+ 32
- 0
ModuleTemplate.DotSettings View File

@@ -0,0 +1,32 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Description/@EntryValue">Module</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Text/@EntryValue">namespace $namespace$&#xD;
{&#xD;
public class $filename$ : Module&#xD;
{&#xD;
public override void Initialize()&#xD;
{&#xD;
} &#xD;
&#xD;
public override void ParseCommand(CommandMessage command)&#xD;
{&#xD;
}&#xD;
}&#xD;
}</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Reformat/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/ShortenQualifiedReferences/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/CustomProperties/=FileName/@EntryIndexedValue">NewModule</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/CustomProperties/=Extension/@EntryIndexedValue">cs</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/CustomProperties/=ValidateFileName/@EntryIndexedValue">False</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Applicability/=File/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Scope/=E8F0594528C33E45BBFEC6CFE851095D/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Scope/=E8F0594528C33E45BBFEC6CFE851095D/Type/@EntryValue">InCSharpProjectFile</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/Expression/@EntryValue">getCurrentNamespace()</s:String>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/InitialRange/@EntryValue">-1</s:Int64>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/Order/@EntryValue">0</s:Int64>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/Expression/@EntryValue">fileDefaultNamespace()</s:String>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/InitialRange/@EntryValue">-1</s:Int64>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/Order/@EntryValue">1</s:Int64></wpf:ResourceDictionary>

Loading…
Cancel
Save