Fixed GetReply and GetError functions. Added some TODO notes.tags/3.0.0
@@ -2,6 +2,7 @@ | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Net; | |||
using System.Text.RegularExpressions; | |||
using System.Threading; | |||
using Combot.IRCServices; | |||
using Combot.Configurations; | |||
@@ -378,13 +379,37 @@ namespace Combot | |||
CommandMessage newCommand = new CommandMessage(); | |||
List<CommandArgument> validArguments = cmd.Arguments.FindAll(arg => arg.MessageTypes.Contains(messageType)); | |||
newCommand.Nick.Copy(sender); | |||
bool nickFound = false; | |||
IRC.Channels.ForEach(channel => channel.Nicks.ForEach(nick => | |||
{ | |||
if (nick.Nickname == newCommand.Nick.Nickname) | |||
{ | |||
nickFound = true; | |||
newCommand.Nick.AddModes(nick.Modes); | |||
newCommand.Nick.AddPrivileges(nick.Privileges); | |||
} | |||
})); | |||
// Nickname has not been found, so need to run a query for nick's modes | |||
if (!nickFound) | |||
{ | |||
string whoStyle = string.Format(@"[^\s]+\s[^\s]+\s[^\s]+\s[^\s]+\s({0})\s(?<Modes>[^\s]+)\s:[\d]\s(.+)", newCommand.Nick.Nickname); | |||
Regex whoRegex = new Regex(whoStyle); | |||
IRC.SendWho(newCommand.Nick.Nickname); | |||
ServerReplyMessage whoReply = IRC.Message.GetServerReply(IRCReplyCode.RPL_WHOREPLY, whoStyle); | |||
if (whoReply.ReplyCode != 0) | |||
{ | |||
Match whoMatch = whoRegex.Match(whoReply.Message); | |||
List<UserModeInfo> modeInfoList = IRC.ParseUserModeString(whoMatch.Groups["Modes"].ToString()); | |||
modeInfoList.ForEach(info => | |||
{ | |||
if (info.Set) | |||
{ | |||
newCommand.Nick.AddMode(info.Mode); | |||
} | |||
}); | |||
} | |||
} | |||
newCommand.TimeStamp = timestamp; | |||
newCommand.Location = location; | |||
newCommand.MessageType = messageType; |
@@ -70,6 +70,7 @@ | |||
<Compile Include="Configurations\ServerConfig.cs" /> | |||
<Compile Include="Modules\CommandArgument.cs" /> | |||
<Compile Include="Modules\CommandMessage.cs" /> | |||
<Compile Include="Modules\ModuleClasses\Owner.cs" /> | |||
<Compile Include="Modules\ModuleClasses\Help.cs" /> | |||
<Compile Include="Modules\ModuleClasses\Invite.cs" /> | |||
<Compile Include="Modules\ModuleClasses\Moderation.cs" /> |
@@ -0,0 +1,209 @@ | |||
using System; | |||
using System.Diagnostics; | |||
using System.Linq; | |||
using System.Reflection; | |||
namespace Combot.Modules.ModuleClasses | |||
{ | |||
public class Owner : Module | |||
{ | |||
public override void Initialize() | |||
{ | |||
Bot.CommandReceivedEvent += HandleCommandEvent; | |||
} | |||
public override void ParseCommand(CommandMessage command) | |||
{ | |||
Command foundCommand = Commands.Find(c => c.Triggers.Contains(command.Command)); | |||
switch (foundCommand.Name) | |||
{ | |||
case "Change Nick": | |||
Bot.IRC.SendNick(command.Arguments["Nickname"]); | |||
break; | |||
case "Identify": | |||
Bot.IRC.SendPrivateMessage("NickServ", string.Format("Identify {0}", Bot.ServerConfig.Password)); | |||
break; | |||
case "Join Channel": | |||
if (!Bot.IRC.Channels.Exists(chan => chan.Name == command.Arguments["Channel"])) | |||
{ | |||
Bot.IRC.SendJoin(command.Arguments["Channel"]); | |||
} | |||
else | |||
{ | |||
string message = string.Format("I am already in \u0002{0}\u000F.", command.Arguments["Channel"]); | |||
switch (command.MessageType) | |||
{ | |||
case MessageType.Channel: | |||
Bot.IRC.SendPrivateMessage(command.Location, message); | |||
break; | |||
case MessageType.Query: | |||
Bot.IRC.SendPrivateMessage(command.Nick.Nickname, message); | |||
break; | |||
case MessageType.Notice: | |||
Bot.IRC.SendNotice(command.Nick.Nickname, message); | |||
break; | |||
} | |||
} | |||
break; | |||
case "Part Channel": | |||
string channel = command.Arguments.ContainsKey("Channel") ? command.Arguments["Channel"] : command.Location; | |||
if (Bot.IRC.Channels.Exists(chan => chan.Name == channel)) | |||
{ | |||
Bot.IRC.SendPart(channel); | |||
} | |||
else | |||
{ | |||
string message = string.Format("I am not in \u0002{0}\u000F.", channel); | |||
switch (command.MessageType) | |||
{ | |||
case MessageType.Channel: | |||
Bot.IRC.SendPrivateMessage(command.Location, message); | |||
break; | |||
case MessageType.Query: | |||
Bot.IRC.SendPrivateMessage(command.Nick.Nickname, message); | |||
break; | |||
case MessageType.Notice: | |||
Bot.IRC.SendNotice(command.Nick.Nickname, message); | |||
break; | |||
} | |||
} | |||
break; | |||
case "Speak": | |||
string location = command.Arguments.ContainsKey("Target") ? command.Arguments["Target"] : command.Location; | |||
Bot.IRC.SendPrivateMessage(location, command.Arguments["Message"]); | |||
break; | |||
case "Action": | |||
string actionLocation = command.Arguments.ContainsKey("Channel") ? command.Arguments["Channel"] : command.Location; | |||
Bot.IRC.SendCTCPMessage(actionLocation, "ACTION", command.Arguments["Message"]); | |||
break; | |||
case "Quit": | |||
string quitType = command.Arguments["Type"].ToString(); | |||
switch (quitType.ToLower()) | |||
{ | |||
case "server": | |||
Bot.Disconnect(); | |||
break; | |||
case "client": | |||
Environment.Exit(0); | |||
break; | |||
} | |||
break; | |||
case "Cycle": | |||
string cycleType = command.Arguments["Type"].ToString(); | |||
switch (cycleType.ToLower()) | |||
{ | |||
case "channel": | |||
string cycleChannel = command.Arguments.ContainsKey("Channel") ? command.Arguments["Channel"] : command.Location; | |||
if (Bot.IRC.Channels.Exists(chan => chan.Name == cycleChannel)) | |||
{ | |||
Bot.IRC.SendPart(cycleChannel); | |||
Bot.IRC.SendJoin(cycleChannel); | |||
} | |||
else | |||
{ | |||
string message = string.Format("I am not in \u0002{0}\u000F.", cycleChannel); | |||
switch (command.MessageType) | |||
{ | |||
case MessageType.Channel: | |||
Bot.IRC.SendPrivateMessage(command.Location, message); | |||
break; | |||
case MessageType.Query: | |||
Bot.IRC.SendPrivateMessage(command.Nick.Nickname, message); | |||
break; | |||
case MessageType.Notice: | |||
Bot.IRC.SendNotice(command.Nick.Nickname, message); | |||
break; | |||
} | |||
} | |||
break; | |||
case "server": | |||
Bot.Disconnect(); | |||
Bot.Connect(); | |||
break; | |||
case "client": | |||
Process.Start(Assembly.GetEntryAssembly().Location); // to start new instance of application | |||
Environment.Exit(0); | |||
break; | |||
} | |||
break; | |||
case "List": | |||
string listType = command.Arguments["Type"].ToString(); | |||
string listLocation = command.Arguments.ContainsKey("Channel") ? command.Arguments["Channel"] : command.Location; | |||
switch (listType.ToLower()) | |||
{ | |||
case "nicks": | |||
if (Bot.IRC.Channels.Exists(chan => chan.Name == listLocation)) | |||
{ | |||
string nickList = string.Join(", ", Bot.IRC.Channels.Find(chan => chan.Name == listLocation).Nicks.Select(nick => nick.Nickname)); | |||
string nickMessage = string.Format("Nicknames in \u0002{0}\u000F: {1}", listLocation, nickList); | |||
switch (command.MessageType) | |||
{ | |||
case MessageType.Channel: | |||
Bot.IRC.SendPrivateMessage(command.Location, nickMessage); | |||
break; | |||
case MessageType.Query: | |||
Bot.IRC.SendPrivateMessage(command.Nick.Nickname, nickMessage); | |||
break; | |||
case MessageType.Notice: | |||
Bot.IRC.SendNotice(command.Nick.Nickname, nickMessage); | |||
break; | |||
} | |||
} | |||
else | |||
{ | |||
string message = string.Format("I do not have nickname information for \u0002{0}\u000F.", listLocation); | |||
switch (command.MessageType) | |||
{ | |||
case MessageType.Channel: | |||
Bot.IRC.SendPrivateMessage(command.Location, message); | |||
break; | |||
case MessageType.Query: | |||
Bot.IRC.SendPrivateMessage(command.Nick.Nickname, message); | |||
break; | |||
case MessageType.Notice: | |||
Bot.IRC.SendNotice(command.Nick.Nickname, message); | |||
break; | |||
} | |||
} | |||
break; | |||
case "channels": | |||
string channelList = string.Join(", ", Bot.IRC.Channels.Select(chan => chan.Name)); | |||
string channelMessage = string.Format("I am in the following channels: \u0002{0}\u000F", channelList); | |||
switch (command.MessageType) | |||
{ | |||
case MessageType.Channel: | |||
Bot.IRC.SendPrivateMessage(command.Location, channelMessage); | |||
break; | |||
case MessageType.Query: | |||
Bot.IRC.SendPrivateMessage(command.Nick.Nickname, channelMessage); | |||
break; | |||
case MessageType.Notice: | |||
Bot.IRC.SendNotice(command.Nick.Nickname, channelMessage); | |||
break; | |||
} | |||
break; | |||
case "servers": | |||
// TODO Add server list | |||
break; | |||
case "modules": | |||
string moduleList = string.Join(", ", Bot.Modules.Select(module => module.Name)); | |||
string moduleMessage = string.Format("I have the following modules loaded: \u0002{0}\u000F", moduleList); | |||
switch (command.MessageType) | |||
{ | |||
case MessageType.Channel: | |||
Bot.IRC.SendPrivateMessage(command.Location, moduleMessage); | |||
break; | |||
case MessageType.Query: | |||
Bot.IRC.SendPrivateMessage(command.Nick.Nickname, moduleMessage); | |||
break; | |||
case MessageType.Notice: | |||
Bot.IRC.SendNotice(command.Nick.Nickname, moduleMessage); | |||
break; | |||
} | |||
break; | |||
} | |||
break; | |||
} | |||
} | |||
} | |||
} |
@@ -190,6 +190,44 @@ namespace Combot.IRCServices | |||
return modeInfos; | |||
} | |||
public List<UserModeInfo> ParseUserModeString(string modeString) | |||
{ | |||
List<UserModeInfo> userModes = new List<UserModeInfo>(); | |||
bool set = true; | |||
char[] modeArr = modeString.ToCharArray(); | |||
for (int i = 1; i <= modeArr.GetUpperBound(0); i++) | |||
{ | |||
UserModeInfo newMode = new UserModeInfo(); | |||
if (modeArr[i].Equals('-')) | |||
{ | |||
set = false; | |||
} | |||
else if (modeArr[i].Equals('+')) | |||
{ | |||
set = true; | |||
} | |||
else if (modeArr[i].Equals('*')) | |||
{ | |||
newMode.Mode = UserMode.o; | |||
newMode.Set = set; | |||
userModes.Add(newMode); | |||
} | |||
else | |||
{ | |||
UserMode foundMode; | |||
bool validMode = Enum.TryParse(modeArr[i].ToString(), false, out foundMode); | |||
if (validMode) | |||
{ | |||
newMode.Mode = foundMode; | |||
newMode.Set = set; | |||
userModes.Add(newMode); | |||
} | |||
} | |||
} | |||
return userModes; | |||
} | |||
private void ReadTCPMessages() | |||
{ | |||
while (_TCP.Connected) | |||
@@ -449,6 +487,10 @@ namespace Combot.IRCServices | |||
Nick newNick = Channels[i].GetNick(e.OldNick.Nickname); | |||
if (newNick != null) | |||
{ | |||
if (e.OldNick.Nickname == Nickname) | |||
{ | |||
Nickname = e.NewNick.Nickname; | |||
} | |||
newNick.Nickname = e.NewNick.Nickname; | |||
} | |||
} |
@@ -8,6 +8,7 @@ using System.Threading; | |||
namespace Combot.IRCServices | |||
{ | |||
// TODO Make long message splits based on words | |||
public partial class IRC | |||
{ | |||
/// <summary> |
@@ -42,6 +42,7 @@ | |||
<Compile Include="AccessControl\Access.cs" /> | |||
<Compile Include="Channel.cs" /> | |||
<Compile Include="IRC.cs" /> | |||
<Compile Include="Messaging\GetError.cs" /> | |||
<Compile Include="Messaging\GetReply.cs" /> | |||
<Compile Include="Messaging\Messages.cs" /> | |||
<Compile Include="Messaging\MessageTypes.cs" /> |
@@ -0,0 +1,13 @@ | |||
using System.Collections.Generic; | |||
using System.Threading; | |||
namespace Combot.IRCServices.Messaging | |||
{ | |||
public class GetError | |||
{ | |||
public ManualResetEventSlim Ready = new ManualResetEventSlim(false); | |||
public string Match = string.Empty; | |||
public IRCErrorCode Error = new IRCErrorCode(); | |||
public ServerErrorMessage Result = new ServerErrorMessage(); | |||
} | |||
} |
@@ -1,18 +1,13 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Collections.Generic; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
namespace Combot.IRCServices.Messaging | |||
{ | |||
public class GetReply | |||
{ | |||
public bool Reattach = true; | |||
public bool Result = false; | |||
public ManualResetEventSlim Ready = new ManualResetEventSlim(false); | |||
public List<IRCReplyCode> Replies = new List<IRCReplyCode>(); | |||
public List<IRCErrorCode> Errors = new List<IRCErrorCode>(); | |||
public string Match = string.Empty; | |||
public IRCReplyCode Reply = new IRCReplyCode(); | |||
public ServerReplyMessage Result = new ServerReplyMessage(); | |||
} | |||
} |
@@ -455,40 +455,58 @@ namespace Combot.IRCServices.Messaging | |||
} | |||
} | |||
public bool GetReply(List<IRCReplyCode> ReplyCodes, List<IRCErrorCode> ErrorCodes) | |||
public ServerReplyMessage GetServerReply(IRCReplyCode replyCode, string match) | |||
{ | |||
GetReply reply = new GetReply(); | |||
reply.Replies = ReplyCodes; | |||
reply.Errors = ErrorCodes; | |||
reply.Reply = replyCode; | |||
reply.Match = match; | |||
ServerReplyEvent += (sender, e) => HandleReply(sender, e, reply); | |||
reply.Ready.Wait(TimeSpan.FromMilliseconds(5000)); | |||
reply.Reattach = false; | |||
ServerReplyEvent -= (obj, e) => HandleReply(obj, e, reply); | |||
return reply.Result; | |||
} | |||
public ServerErrorMessage GetServerError(IRCErrorCode errorCode, string match) | |||
{ | |||
GetError error = new GetError(); | |||
error.Error = errorCode; | |||
error.Match = match; | |||
ServerReplyEvent += (sender, e) => HandleError(sender, e, error); | |||
error.Ready.Wait(TimeSpan.FromMilliseconds(5000)); | |||
ServerReplyEvent -= (sender, e) => HandleError(sender, e, error); | |||
return error.Result; | |||
} | |||
private void HandleReply(object sender, IReply message, GetReply reply) | |||
{ | |||
bool replyFound = false; | |||
Regex replyRegex = new Regex(reply.Match); | |||
if (message.GetType() == typeof(ServerReplyMessage)) | |||
{ | |||
ServerReplyMessage msg = (ServerReplyMessage)message; | |||
replyFound = reply.Replies.Contains(msg.ReplyCode); | |||
replyFound = reply.Reply.Equals(msg.ReplyCode); | |||
if (replyFound && replyRegex.IsMatch(msg.Message)) | |||
{ | |||
reply.Result = msg; | |||
reply.Ready.Set(); | |||
} | |||
} | |||
else | |||
} | |||
private void HandleError(object sender, IReply message, GetError error) | |||
{ | |||
bool errorFound = false; | |||
Regex errorRegex = new Regex(error.Match); | |||
if (message.GetType() == typeof(ServerErrorMessage)) | |||
{ | |||
ServerErrorMessage msg = (ServerErrorMessage)message; | |||
replyFound = reply.Errors.Contains(msg.ErrorCode); | |||
} | |||
if (replyFound) | |||
{ | |||
reply.Result = replyFound; | |||
reply.Ready.Set(); | |||
} | |||
else | |||
{ | |||
if (reply.Reattach) | |||
errorFound = error.Error.Equals(msg.ErrorCode); | |||
if (errorFound && errorRegex.IsMatch(msg.Message)) | |||
{ | |||
ServerReplyEvent += (obj, e) => HandleReply(obj, e, reply); | |||
error.Result = msg; | |||
error.Ready.Set(); | |||
} | |||
} | |||
} |