Browse Source

Added comments.

Added Topic initialization on join.
tags/3.0.0
Teknikode 4 years ago
parent
commit
7625034ebd
7 changed files with 194 additions and 43 deletions
  1. 10
    7
      Combot/Bot.cs
  2. 36
    4
      Combot/Combot.csproj
  3. 76
    6
      IRCServices/IRC.cs
  4. 24
    10
      IRCServices/Messaging/Messages.cs
  5. 14
    14
      IRCServices/Nick.cs
  6. 2
    2
      IRCServices/Types.cs
  7. 32
    0
      Interface/Interface.csproj

+ 10
- 7
Combot/Bot.cs View File

@@ -26,7 +26,10 @@ namespace Combot
IRC.Message.ServerReplyEvent += HandleReplyEvent;
}

public bool Connect()
/// <summary>
/// Trys to connect to one of the IPs of the given hostname. If the connection was successful, it will login the nick.
/// </summary>
public void Connect()
{
bool serverConnected = false;
int i = 0;
@@ -56,16 +59,15 @@ namespace Combot
{
IRC.Login(ServerConfig.Name, new Nick() { Nickname = ServerConfig.Nickname, Host = Dns.GetHostName(), Realname = ServerConfig.Realname, Username = ServerConfig.Username });
}

return Connected;
}

public bool Disconnect()
/// <summary>
/// Disconnects from the current server.
/// </summary>
public void Disconnect()
{
IRC.Disconnect();
Connected = false;

return Connected;
}

private void HandleConnectEvent()
@@ -83,7 +85,8 @@ namespace Combot
if (e.GetType() == typeof(ServerReplyMessage))
{
ServerReplyMessage reply = (ServerReplyMessage)e;
if (reply.ReplyCode == IRCReplyCode.RPL_ENDOFMOTD && Connected)
// 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)
{
foreach (ChannelConfig channel in ServerConfig.Channels)
{

+ 36
- 4
Combot/Combot.csproj View File

@@ -11,6 +11,21 @@
<AssemblyName>Combot</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -55,6 +70,12 @@
<Compile Include="Properties.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Service References\" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IRCServices\IRCServices.csproj">
<Project>{65fcbf1c-8c9e-4688-becc-185d9030899f}</Project>
@@ -62,10 +83,21 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Service References\" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<BootstrapperPackage Include=".NETFramework,Version=v4.5.1">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.5.1 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

+ 76
- 6
IRCServices/IRC.cs View File

@@ -18,7 +18,7 @@ namespace Combot.IRCServices
public event Action DisconnectEvent;
public event Action<TCPError> TCPErrorEvent;
public string Nickname { get; set; }
public Dictionary<string, PrivaledgeMode> PrivaledgeMapping = new Dictionary<string, PrivaledgeMode>() { { "+", PrivaledgeMode.v }, { "%", PrivaledgeMode.h }, { "@", PrivaledgeMode.o }, { "&", PrivaledgeMode.a }, { "~", PrivaledgeMode.q } };
public Dictionary<string, PrivilegeMode> PrivilegeMapping = new Dictionary<string, PrivilegeMode>() { { "+", PrivilegeMode.v }, { "%", PrivilegeMode.h }, { "@", PrivilegeMode.o }, { "&", PrivilegeMode.a }, { "~", PrivilegeMode.q } };

private TCPInterface _TCP;
private Thread TCPReader;
@@ -47,6 +47,14 @@ namespace Combot.IRCServices
Message.QuitEvent += HandleQuit;
}

/// <summary>
/// Starts a TCP connection to the specified host.
/// </summary>
/// <param name="IP">The IP address of the host.</param>
/// <param name="port">The port for the tcp connection.</param>
/// <param name="readTimeout">The timeout for read operations in milliseconds.</param>
/// <param name="allowedFailedCount">Number of times a read can fail before disconnecting.</param>
/// <returns></returns>
public bool Connect(IPAddress IP, int port, int readTimeout = 5000, int allowedFailedCount = 0)
{
bool result = false;
@@ -69,6 +77,10 @@ namespace Combot.IRCServices
return result;
}

/// <summary>
/// Disconencts from the active TCP connection.
/// </summary>
/// <returns></returns>
public bool Disconnect()
{
bool result = false;
@@ -90,6 +102,11 @@ namespace Combot.IRCServices
return result;
}

/// <summary>
/// Logs in the specified nick using their Username and Realname.
/// </summary>
/// <param name="serverName">The server's name.</param>
/// <param name="nick">The nick information for the login.</param>
public void Login(string serverName, Nick nick)
{
Nickname = nick.Nickname;
@@ -149,6 +166,11 @@ namespace Combot.IRCServices
Disconnect();
}

/// <summary>
/// Responds with PONG on a PING with the specified arguments.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void HandlePing(object sender, PingInfo e)
{
IRCSendPong(e.Message);
@@ -161,6 +183,7 @@ namespace Combot.IRCServices
ServerReplyMessage msg = (ServerReplyMessage)e;
switch (msg.ReplyCode)
{
// If we get a WHO response, we parse and add the nicks to the specified channel if they are not there already.
case IRCReplyCode.RPL_WHOREPLY:
ChannelRWLock.EnterWriteLock();
string[] msgSplit = msg.Message.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
@@ -189,13 +212,13 @@ namespace Combot.IRCServices
nick.Realname = realname;
nick.Username = username;
nick.Modes = new List<UserMode>();
nick.Privaledges = new List<PrivaledgeMode>();
nick.Privileges = new List<PrivilegeMode>();
char[] modeArr = modeString.ToCharArray();
for (int i = 1; i <= modeArr.GetUpperBound(0); i++)
{
if (PrivaledgeMapping.ContainsKey(modeArr[i].ToString()))
if (PrivilegeMapping.ContainsKey(modeArr[i].ToString()))
{
nick.Privaledges.Add(PrivaledgeMapping[modeArr[i].ToString()]);
nick.Privileges.Add(PrivilegeMapping[modeArr[i].ToString()]);
}
else if (modeArr[i].ToString() == "*")
{
@@ -215,6 +238,18 @@ namespace Combot.IRCServices
}
ChannelRWLock.ExitWriteLock();
break;
// On a topic reply, update the channel's topic
case IRCReplyCode.RPL_TOPIC:
ChannelRWLock.EnterWriteLock();
string[] topicSplit = msg.Message.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
string topicChan = topicSplit[0];
Channel topicChannel = Channels.Find(chan => chan.Name == topicChan);
if (topicChannel != null)
{
topicChannel.Topic = topicSplit[1].Remove(0, 1);
}
ChannelRWLock.ExitWriteLock();
break;
default:
break;
}
@@ -225,6 +260,11 @@ namespace Combot.IRCServices
}
}

/// <summary>
/// Update a channel's mode.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void HandleChannelModeChange(object sender, ChannelModeChangeInfo e)
{
ChannelRWLock.EnterWriteLock();
@@ -243,11 +283,11 @@ namespace Combot.IRCServices
Nick changedNick = channel.GetNick(mode.Parameter);
if (mode.Set)
{
changedNick.AddPrivaledge((PrivaledgeMode)Enum.Parse(typeof(PrivaledgeMode), mode.Mode.ToString()));
changedNick.AddPrivilege((PrivilegeMode)Enum.Parse(typeof(PrivilegeMode), mode.Mode.ToString()));
}
else
{
changedNick.RemovePrivaledge((PrivaledgeMode)Enum.Parse(typeof(PrivaledgeMode), mode.Mode.ToString()));
changedNick.RemovePrivilege((PrivilegeMode)Enum.Parse(typeof(PrivilegeMode), mode.Mode.ToString()));
}
break;
case ChannelMode.b:
@@ -288,6 +328,11 @@ namespace Combot.IRCServices
ChannelRWLock.ExitWriteLock();
}

/// <summary>
/// Update a nick's mode.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void HandleUserModeChange(object sender, UserModeChangeInfo e)
{
ChannelRWLock.EnterWriteLock();
@@ -312,6 +357,11 @@ namespace Combot.IRCServices
ChannelRWLock.ExitWriteLock();
}

/// <summary>
/// Update a nick to use their new nickname.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void HandleNickChange(object sender, NickChangeInfo e)
{
ChannelRWLock.EnterWriteLock();
@@ -326,6 +376,11 @@ namespace Combot.IRCServices
ChannelRWLock.ExitWriteLock();
}

/// <summary>
/// Add a nick to a channel on join.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void HandleJoin(object sender, JoinChannelInfo e)
{
ChannelRWLock.EnterWriteLock();
@@ -349,6 +404,11 @@ namespace Combot.IRCServices
ChannelRWLock.ExitWriteLock();
}

/// <summary>
/// Remove a nick from a channel on part.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void HandlePart(object sender, PartChannelInfo e)
{
ChannelRWLock.EnterWriteLock();
@@ -360,6 +420,11 @@ namespace Combot.IRCServices
ChannelRWLock.ExitWriteLock();
}

/// <summary>
/// Remove a nick from a channel on kick.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void HandleKick(object sender, KickInfo e)
{
ChannelRWLock.EnterWriteLock();
@@ -371,6 +436,11 @@ namespace Combot.IRCServices
ChannelRWLock.ExitWriteLock();
}

/// <summary>
/// Remove a nick from all channels on quit.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void HandleQuit(object sender, QuitInfo e)
{
ChannelRWLock.EnterWriteLock();

+ 24
- 10
IRCServices/Messaging/Messages.cs View File

@@ -36,10 +36,14 @@ namespace Combot.IRCServices.Messaging
_IRC = irc;
}

/// <summary>
/// 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)
{
DateTime messageTime = DateTime.Now;
Regex messageRegex = new Regex(@"^:(?<Sender>[^\s]+)\s(?<Type>[^\s]+)\s(?<Recipient>[^\s]+)\s?(?<Args>.*)", RegexOptions.None);
Regex messageRegex = new Regex(@"^:(?<Sender>[^\s]+)\s(?<Type>[^\s]+)\s(?<Recipient>[^\s]+)\s?:?(?<Args>.*)", RegexOptions.None);
Regex senderRegex = new Regex(@"^(?<Nick>[^\s]+)!(?<Realname>[^\s]+)@(?<Host>[^\s]+)", RegexOptions.None);
Regex pingRegex = new Regex(@"^PING :(?<Message>.+)", RegexOptions.None);
Regex pongRegex = new Regex(@"^PONG :(?<Message>.+)", RegexOptions.None);
@@ -90,13 +94,14 @@ namespace Combot.IRCServices.Messaging
{
switch (type)
{
// The message was a private message to a channel or nick
case "PRIVMSG":
if (recipient.StartsWith("&") || recipient.StartsWith("#"))
{
ChannelMessage msg = new ChannelMessage();
msg.Channel = recipient;
msg.Sender = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost };
msg.Message = args.Remove(0, 1);
msg.Message = args;

if (ChannelMessageReceivedEvent != null)
{
@@ -107,7 +112,7 @@ namespace Combot.IRCServices.Messaging
{
PrivateMessage msg = new PrivateMessage();
msg.Sender = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost };
msg.Message = args.Remove(0, 1);
msg.Message = args;

if (PrivateMessageReceivedEvent != null)
{
@@ -115,13 +120,14 @@ namespace Combot.IRCServices.Messaging
}
}
break;
// The message was a notice to a channel or nick
case "NOTICE":
if (recipient.StartsWith("&") || recipient.StartsWith("#"))
{
ChannelNotice msg = new ChannelNotice();
msg.Channel = recipient;
msg.Sender = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost };
msg.Message = args.Remove(0, 1);
msg.Message = args;

if (ChannelNoticeReceivedEvent != null)
{
@@ -132,7 +138,7 @@ namespace Combot.IRCServices.Messaging
{
PrivateNotice msg = new PrivateNotice();
msg.Sender = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost };
msg.Message = args.Remove(0, 1);
msg.Message = args;

if (PrivateNoticeReceivedEvent != null)
{
@@ -140,6 +146,7 @@ namespace Combot.IRCServices.Messaging
}
}
break;
// The message was a mode change message for a channel or nick
case "MODE":
if (recipient.StartsWith("&") || recipient.StartsWith("#"))
{
@@ -236,17 +243,19 @@ namespace Combot.IRCServices.Messaging
}
}
break;
// The message was a topic change for a channel
case "TOPIC":
TopicChangeInfo topicMsg = new TopicChangeInfo();
topicMsg.Channel = recipient;
topicMsg.Nick = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost };
topicMsg.Topic = args.Remove(0, 1);
topicMsg.Topic = args;

if (TopicChangeEvent != null)
{
TopicChangeEvent(this, topicMsg);
}
break;
// The message was a nick change
case "NICK":
NickChangeInfo nickMsg = new NickChangeInfo();
nickMsg.OldNick = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost };
@@ -257,17 +266,19 @@ namespace Combot.IRCServices.Messaging
NickChangeEvent(this, nickMsg);
}
break;
// The message was an invite to a channel
case "INVITE":
InviteChannelInfo inviteMsg = new InviteChannelInfo();
inviteMsg.Requester = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost };
inviteMsg.Recipient = new Nick() { Nickname = recipient };
inviteMsg.Channel = args.Remove(0, 1);
inviteMsg.Channel = args;

if (InviteChannelEvent != null)
{
InviteChannelEvent(this, inviteMsg);
}
break;
// The message was a nick joining a channel
case "JOIN":
JoinChannelInfo joinMsg = new JoinChannelInfo();
joinMsg.Channel = recipient.TrimStart(':');
@@ -278,6 +289,7 @@ namespace Combot.IRCServices.Messaging
JoinChannelEvent(this, joinMsg);
}
break;
// The message was a nick parting a channel
case "PART":
PartChannelInfo partMsg = new PartChannelInfo();
partMsg.Channel = recipient;
@@ -288,6 +300,7 @@ namespace Combot.IRCServices.Messaging
PartChannelEvent(this, partMsg);
}
break;
// The message was a nick being kicked from a channel
case "KICK":
KickInfo kickMsg = new KickInfo();
kickMsg.Channel = recipient;
@@ -305,6 +318,7 @@ namespace Combot.IRCServices.Messaging
KickEvent(this, kickMsg);
}
break;
// The message was a nick quiting the irc network
case "QUIT":
QuitInfo quitMsg = new QuitInfo();
quitMsg.Nick = new Nick() { Nickname = senderNick, Realname = senderRealname, Host = senderHost };
@@ -320,7 +334,7 @@ namespace Combot.IRCServices.Messaging
}
}
}
else if (pingRegex.IsMatch(message))
else if (pingRegex.IsMatch(message)) // The message was a PING
{
Match match = pingRegex.Match(message);
PingInfo ping = new PingInfo();
@@ -331,7 +345,7 @@ namespace Combot.IRCServices.Messaging
PingEvent(this, ping);
}
}
else if (pongRegex.IsMatch(message))
else if (pongRegex.IsMatch(message)) // The message was a PONG
{
Match match = pongRegex.Match(message);
PongInfo pong = new PongInfo();
@@ -342,7 +356,7 @@ namespace Combot.IRCServices.Messaging
PongEvent(this, pong);
}
}
else if (errorRegex.IsMatch(message))
else if (errorRegex.IsMatch(message)) // The message was a server error
{
Match match = errorRegex.Match(message);
ErrorMessage error = new ErrorMessage();

+ 14
- 14
IRCServices/Nick.cs View File

@@ -16,7 +16,7 @@ namespace Combot.IRCServices
public bool Identified { get; set; }
public bool Registered { get; set; }
public List<UserMode> Modes { get; set; }
public List<PrivaledgeMode> Privaledges { get; set; }
public List<PrivilegeMode> Privileges { get; set; }

public Nick()
{
@@ -28,7 +28,7 @@ namespace Combot.IRCServices
Identified = false;
Registered = false;
Modes = new List<UserMode>();
Privaledges = new List<PrivaledgeMode>();
Privileges = new List<PrivilegeMode>();
}

public void AddMode(UserMode mode)
@@ -63,35 +63,35 @@ namespace Combot.IRCServices
}
}

public void AddPrivaledge(PrivaledgeMode privaledge)
public void AddPrivilege(PrivilegeMode Privilege)
{
if (!Privaledges.Contains(privaledge))
if (!Privileges.Contains(Privilege))
{
Privaledges.Add(privaledge);
Privileges.Add(Privilege);
}
}

public void AddPrivaledges(List<PrivaledgeMode> privaledges)
public void AddPrivileges(List<PrivilegeMode> Privileges)
{
foreach (PrivaledgeMode privaledge in privaledges)
foreach (PrivilegeMode Privilege in Privileges)
{
AddPrivaledge(privaledge);
AddPrivilege(Privilege);
}
}

public void RemovePrivaledge(PrivaledgeMode privaledge)
public void RemovePrivilege(PrivilegeMode Privilege)
{
if (Privaledges.Contains(privaledge))
if (Privileges.Contains(Privilege))
{
Privaledges.Remove(privaledge);
Privileges.Remove(Privilege);
}
}

public void RemovePrivaledges(List<PrivaledgeMode> privaledges)
public void RemovePrivileges(List<PrivilegeMode> Privileges)
{
foreach (PrivaledgeMode privaledge in privaledges)
foreach (PrivilegeMode Privilege in Privileges)
{
RemovePrivaledge(privaledge);
RemovePrivilege(Privilege);
}
}
}

+ 2
- 2
IRCServices/Types.cs View File

@@ -102,7 +102,7 @@ namespace Combot.IRCServices
B,
[Description("Connection Notice")]
c,
[Description("C-oAdministrator")]
[Description("Co-Administrator")]
C,
[Description("Deaf")]
d,
@@ -186,7 +186,7 @@ namespace Combot.IRCServices
u
}

public enum PrivaledgeMode
public enum PrivilegeMode
{
[Description("Voice")]
v,

+ 32
- 0
Interface/Interface.csproj View File

@@ -14,6 +14,21 @@
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -109,6 +124,23 @@
<Name>IRCServices</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.5.1">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.5.1 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

Loading…
Cancel
Save