├── .vs
└── SimpleIRCLib
│ └── v14
│ └── .suo
├── FormExample
├── Home.md
├── App.config
├── Properties
│ ├── Settings.settings
│ ├── Settings.Designer.cs
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ └── Resources.resx
├── Program.cs
├── FormExample.csproj
├── FormExample.md
├── DebugForm.resx
├── DebugForm.cs
├── IrcClientForm.resx
├── DebugForm.Designer.cs
├── IrcClientForm.Designer.cs
└── IrcClientForm.cs
├── IrcLibTest
├── App.config
├── Properties
│ └── AssemblyInfo.cs
├── IrcLibTest.csproj
└── Program.cs
├── SimpleIRCLib
├── Home.md
├── SimpleIRCLib.csproj
├── IrcEventArgs.cs
├── DCCEventArgs.cs
├── SimpleIRCLib.md
├── SimpleIRC.cs
├── IrcCommands.cs
├── RFC1459Codes.cs
├── DCCClient.cs
└── IrcClient.cs
├── LICENSE
├── SimpleIRCLib.sln
├── gitignore
├── .gitignore
└── README.md
/.vs/SimpleIRCLib/v14/.suo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EldinZenderink/SimpleIRCLib/HEAD/.vs/SimpleIRCLib/v14/.suo
--------------------------------------------------------------------------------
/FormExample/Home.md:
--------------------------------------------------------------------------------
1 | # References
2 |
3 | ## [FormExample](FormExample)
4 |
5 | - [`DebugForm`](FormExample#debugform)
6 | - [`IrcClientForm`](FormExample#ircclientform)
7 |
8 |
--------------------------------------------------------------------------------
/FormExample/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/IrcLibTest/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/FormExample/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SimpleIRCLib/Home.md:
--------------------------------------------------------------------------------
1 | # References
2 |
3 | ## [SimpleIRCLib](SimpleIRCLib)
4 |
5 | - [`DCCClient`](SimpleIRCLib#dccclient)
6 | - [`DCCDebugMessageArgs`](SimpleIRCLib#dccdebugmessageargs)
7 | - [`DCCEventArgs`](SimpleIRCLib#dcceventargs)
8 | - [`IrcClient`](SimpleIRCLib#ircclient)
9 | - [`IrcDebugMessageEventArgs`](SimpleIRCLib#ircdebugmessageeventargs)
10 | - [`IrcRawReceivedEventArgs`](SimpleIRCLib#ircrawreceivedeventargs)
11 | - [`IrcReceivedEventArgs`](SimpleIRCLib#ircreceivedeventargs)
12 | - [`IrcUserListReceivedEventArgs`](SimpleIRCLib#ircuserlistreceivedeventargs)
13 | - [`SimpleIRC`](SimpleIRCLib#simpleirc)
14 |
15 |
--------------------------------------------------------------------------------
/FormExample/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using System.Windows.Forms;
6 |
7 | namespace FormExample
8 | {
9 | static class Program
10 | {
11 | ///
12 | /// The main entry point for the application.
13 | ///
14 | [STAThread]
15 | static void Main()
16 | {
17 | Application.EnableVisualStyles();
18 | Application.SetCompatibleTextRenderingDefault(false);
19 | Application.Run(new IrcClientForm());
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Eldin Zenderink
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/FormExample/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace FormExample.Properties
12 | {
13 |
14 |
15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
18 | {
19 |
20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
21 |
22 | public static Settings Default
23 | {
24 | get
25 | {
26 | return defaultInstance;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/SimpleIRCLib/SimpleIRCLib.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | true
6 | 2.2.1
7 | Eldin Zenderink
8 | None
9 | A easy to use, easy to implent, IRC library with DCC (Download) support for C#.
10 | See for more information:
11 | https://github.com/EldinZenderink/SimpleIRCLib
12 | https://github.com/EldinZenderink/SimpleIRCLib
13 | https://github.com/EldinZenderink/SimpleIRCLib/blob/master/LICENSE
14 | https://github.com/EldinZenderink/SimpleIRCLib
15 | GitHub
16 | C# IRC DCC PROTOCOL irc protocol simple
17 | -- Added byte list buffer to access data downloaded per second (for parsing during the download for example (espescially used within LittleWeeb to parse subtitles during download).
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/FormExample/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("FormExample")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("FormExample")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("a46528e0-6bb9-4200-8276-3f840e0a7c72")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/IrcLibTest/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("IrcLibTest")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("IrcLibTest")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("27c58f1a-4851-4a5b-85f7-c387971543da")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/SimpleIRCLib.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27428.2005
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleIRCLib", "SimpleIRCLib\SimpleIRCLib.csproj", "{3D881A50-DB1A-464E-A51E-4CE5EB8BD5F1}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IrcLibTest", "IrcLibTest\IrcLibTest.csproj", "{27C58F1A-4851-4A5B-85F7-C387971543DA}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FormExample", "FormExample\FormExample.csproj", "{A46528E0-6BB9-4200-8276-3F840E0A7C72}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Release|Any CPU = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {3D881A50-DB1A-464E-A51E-4CE5EB8BD5F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {3D881A50-DB1A-464E-A51E-4CE5EB8BD5F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {3D881A50-DB1A-464E-A51E-4CE5EB8BD5F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {3D881A50-DB1A-464E-A51E-4CE5EB8BD5F1}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {27C58F1A-4851-4A5B-85F7-C387971543DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {27C58F1A-4851-4A5B-85F7-C387971543DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {27C58F1A-4851-4A5B-85F7-C387971543DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {27C58F1A-4851-4A5B-85F7-C387971543DA}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {A46528E0-6BB9-4200-8276-3F840E0A7C72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {A46528E0-6BB9-4200-8276-3F840E0A7C72}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {A46528E0-6BB9-4200-8276-3F840E0A7C72}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {A46528E0-6BB9-4200-8276-3F840E0A7C72}.Release|Any CPU.Build.0 = Release|Any CPU
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | GlobalSection(ExtensibilityGlobals) = postSolution
35 | SolutionGuid = {584E8A95-B483-45A0-A38B-985C12EF6371}
36 | EndGlobalSection
37 | EndGlobal
38 |
--------------------------------------------------------------------------------
/FormExample/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace FormExample.Properties
12 | {
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources
26 | {
27 |
28 | private static global::System.Resources.ResourceManager resourceMan;
29 |
30 | private static global::System.Globalization.CultureInfo resourceCulture;
31 |
32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
33 | internal Resources()
34 | {
35 | }
36 |
37 | ///
38 | /// Returns the cached ResourceManager instance used by this class.
39 | ///
40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
41 | internal static global::System.Resources.ResourceManager ResourceManager
42 | {
43 | get
44 | {
45 | if ((resourceMan == null))
46 | {
47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FormExample.Properties.Resources", typeof(Resources).Assembly);
48 | resourceMan = temp;
49 | }
50 | return resourceMan;
51 | }
52 | }
53 |
54 | ///
55 | /// Overrides the current thread's CurrentUICulture property for all
56 | /// resource lookups using this strongly typed resource class.
57 | ///
58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
59 | internal static global::System.Globalization.CultureInfo Culture
60 | {
61 | get
62 | {
63 | return resourceCulture;
64 | }
65 | set
66 | {
67 | resourceCulture = value;
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/IrcLibTest/IrcLibTest.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {27C58F1A-4851-4A5B-85F7-C387971543DA}
8 | Exe
9 | Properties
10 | IrcLibTest
11 | IrcLibTest
12 | v4.5.2
13 | 512
14 | true
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 |
38 | ..\SimpleIRCLib\bin\Release\netstandard2.0\SimpleIRCLib.dll
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
65 |
--------------------------------------------------------------------------------
/SimpleIRCLib/IrcEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Threading.Tasks;
5 |
6 | namespace SimpleIRCLib
7 | {
8 | ///
9 | /// Event class for receiving messages from specific channels and users, fired within IrcClient.cs
10 | ///
11 | public class IrcReceivedEventArgs
12 | {
13 | ///
14 | /// Event for receiving messages from server, contains information about who send a message, from where, with the message send.
15 | ///
16 | /// message the user send
17 | /// name of the user
18 | /// channel where the user send it to
19 | public IrcReceivedEventArgs(string message, string user, string channel)
20 | {
21 | Message = message;
22 | User = user;
23 | Channel = channel;
24 | }
25 |
26 | ///
27 | /// Containing message from user on a specific channel
28 | ///
29 | public string Message { get; }
30 | ///
31 | /// Containing user name whom send the message on a specific channel
32 | ///
33 | public string User { get; }
34 | ///
35 | /// Containing channel name where user send his/hers/its message
36 | ///
37 | public string Channel { get; }
38 | }
39 |
40 | ///
41 | /// Event class for receiving raw messages from the irc server, fired within IrcClient.cs
42 | ///
43 | public class IrcRawReceivedEventArgs
44 | {
45 | ///
46 | /// Event for handeling raw messages from the server without any parsing applied.
47 | ///
48 | /// message from server
49 | public IrcRawReceivedEventArgs(string message)
50 | {
51 | Message = message;
52 | }
53 |
54 | ///
55 | /// Containing raw message from the irc server
56 | ///
57 | public string Message { get; }
58 | }
59 |
60 | ///
61 | /// Event class for receiving a list with users per channel, fired within IrcClient.cs
62 | ///
63 | public class IrcUserListReceivedEventArgs
64 | {
65 | ///
66 | /// Event for getting the usersperchannel list from the server.
67 | ///
68 | /// Dictionary containg a list with names per key (channel)
69 | public IrcUserListReceivedEventArgs(Dictionary> usersPerChannel)
70 | {
71 | UsersPerChannel = usersPerChannel;
72 | }
73 |
74 | ///
75 | /// Dicitonary containing a list with user names per channel
76 | ///
77 | public Dictionary> UsersPerChannel { get; }
78 | }
79 |
80 | ///
81 | /// Event class for receiving debug messages from the IrcClient, fired within IrcClient.cs
82 | ///
83 | public class IrcDebugMessageEventArgs
84 | {
85 | ///
86 | /// Event for receiving debug messages from the client
87 | ///
88 | /// debug message itself
89 | /// type of message, handy for identifying where the message occured
90 | public IrcDebugMessageEventArgs(string message, string type)
91 | {
92 | Message = message;
93 | Type = type;
94 | }
95 |
96 | ///
97 | /// Containing debug message.
98 | ///
99 | public string Message { get; }
100 | ///
101 | /// Containing type of message, handy for determining where the message originates from
102 | ///
103 | public string Type { get; }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/FormExample/FormExample.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {A46528E0-6BB9-4200-8276-3F840E0A7C72}
8 | WinExe
9 | Properties
10 | FormExample
11 | FormExample
12 | v4.5.2
13 | 512
14 | true
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 | bin\Debug\FormExample.xml
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 | bin\Release\FormExample.xml
36 |
37 |
38 |
39 | False
40 | ..\SimpleIRCLib\bin\Debug\SimpleIRCLib.dll
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | Form
57 |
58 |
59 | DebugForm.cs
60 |
61 |
62 | Form
63 |
64 |
65 | IrcClientForm.cs
66 |
67 |
68 |
69 |
70 | DebugForm.cs
71 |
72 |
73 | IrcClientForm.cs
74 |
75 |
76 | ResXFileCodeGenerator
77 | Resources.Designer.cs
78 | Designer
79 |
80 |
81 | True
82 | Resources.resx
83 |
84 |
85 | SettingsSingleFileGenerator
86 | Settings.Designer.cs
87 |
88 |
89 | True
90 | Settings.settings
91 | True
92 |
93 |
94 |
95 |
96 |
97 |
98 |
105 |
--------------------------------------------------------------------------------
/gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opendb
80 | *.opensdf
81 | *.sdf
82 | *.cachefile
83 |
84 | # Visual Studio profiler
85 | *.psess
86 | *.vsp
87 | *.vspx
88 | *.sap
89 |
90 | # TFS 2012 Local Workspace
91 | $tf/
92 |
93 | # Guidance Automation Toolkit
94 | *.gpState
95 |
96 | # ReSharper is a .NET coding add-in
97 | _ReSharper*/
98 | *.[Rr]e[Ss]harper
99 | *.DotSettings.user
100 |
101 | # JustCode is a .NET coding add-in
102 | .JustCode
103 |
104 | # TeamCity is a build add-in
105 | _TeamCity*
106 |
107 | # DotCover is a Code Coverage Tool
108 | *.dotCover
109 |
110 | # NCrunch
111 | _NCrunch_*
112 | .*crunch*.local.xml
113 | nCrunchTemp_*
114 |
115 | # MightyMoose
116 | *.mm.*
117 | AutoTest.Net/
118 |
119 | # Web workbench (sass)
120 | .sass-cache/
121 |
122 | # Installshield output folder
123 | [Ee]xpress/
124 |
125 | # DocProject is a documentation generator add-in
126 | DocProject/buildhelp/
127 | DocProject/Help/*.HxT
128 | DocProject/Help/*.HxC
129 | DocProject/Help/*.hhc
130 | DocProject/Help/*.hhk
131 | DocProject/Help/*.hhp
132 | DocProject/Help/Html2
133 | DocProject/Help/html
134 |
135 | # Click-Once directory
136 | publish/
137 |
138 | # Publish Web Output
139 | *.[Pp]ublish.xml
140 | *.azurePubxml
141 | # TODO: Comment the next line if you want to checkin your web deploy settings
142 | # but database connection strings (with potential passwords) will be unencrypted
143 | *.pubxml
144 | *.publishproj
145 |
146 | # NuGet Packages
147 | *.nupkg
148 | # The packages folder can be ignored because of Package Restore
149 | **/packages/*
150 | # except build/, which is used as an MSBuild target.
151 | !**/packages/build/
152 | # Uncomment if necessary however generally it will be regenerated when needed
153 | #!**/packages/repositories.config
154 | # NuGet v3's project.json files produces more ignoreable files
155 | *.nuget.props
156 | *.nuget.targets
157 |
158 | # Microsoft Azure Build Output
159 | csx/
160 | *.build.csdef
161 |
162 | # Microsoft Azure Emulator
163 | ecf/
164 | rcf/
165 |
166 | # Windows Store app package directories and files
167 | AppPackages/
168 | BundleArtifacts/
169 | Package.StoreAssociation.xml
170 | _pkginfo.txt
171 |
172 | # Visual Studio cache files
173 | # files ending in .cache can be ignored
174 | *.[Cc]ache
175 | # but keep track of directories ending in .cache
176 | !*.[Cc]ache/
177 |
178 | # Others
179 | ClientBin/
180 | ~$*
181 | *~
182 | *.dbmdl
183 | *.dbproj.schemaview
184 | *.pfx
185 | *.publishsettings
186 | node_modules/
187 | orleans.codegen.cs
188 |
189 | # Since there are multiple workflows, uncomment next line to ignore bower_components
190 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
191 | #bower_components/
192 |
193 | # RIA/Silverlight projects
194 | Generated_Code/
195 |
196 | # Backup & report files from converting an old project file
197 | # to a newer Visual Studio version. Backup files are not needed,
198 | # because we have git ;-)
199 | _UpgradeReport_Files/
200 | Backup*/
201 | UpgradeLog*.XML
202 | UpgradeLog*.htm
203 |
204 | # SQL Server files
205 | *.mdf
206 | *.ldf
207 |
208 | # Business Intelligence projects
209 | *.rdl.data
210 | *.bim.layout
211 | *.bim_*.settings
212 |
213 | # Microsoft Fakes
214 | FakesAssemblies/
215 |
216 | # GhostDoc plugin setting file
217 | *.GhostDoc.xml
218 |
219 | # Node.js Tools for Visual Studio
220 | .ntvs_analysis.dat
221 |
222 | # Visual Studio 6 build log
223 | *.plg
224 |
225 | # Visual Studio 6 workspace options file
226 | *.opt
227 |
228 | # Visual Studio LightSwitch build output
229 | **/*.HTMLClient/GeneratedArtifacts
230 | **/*.DesktopClient/GeneratedArtifacts
231 | **/*.DesktopClient/ModelManifest.xml
232 | **/*.Server/GeneratedArtifacts
233 | **/*.Server/ModelManifest.xml
234 | _Pvt_Extensions
235 |
236 | # Paket dependency manager
237 | .paket/paket.exe
238 | paket-files/
239 |
240 | # FAKE - F# Make
241 | .fake/
242 |
243 | # JetBrains Rider
244 | .idea/
245 | *.sln.iml
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.suo## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opendb
80 | *.opensdf
81 | *.sdf
82 | *.cachefile
83 |
84 | # Visual Studio profiler
85 | *.psess
86 | *.vsp
87 | *.vspx
88 | *.sap
89 |
90 | # TFS 2012 Local Workspace
91 | $tf/
92 |
93 | # Guidance Automation Toolkit
94 | *.gpState
95 |
96 | # ReSharper is a .NET coding add-in
97 | _ReSharper*/
98 | *.[Rr]e[Ss]harper
99 | *.DotSettings.user
100 |
101 | # JustCode is a .NET coding add-in
102 | .JustCode
103 |
104 | # TeamCity is a build add-in
105 | _TeamCity*
106 |
107 | # DotCover is a Code Coverage Tool
108 | *.dotCover
109 |
110 | # NCrunch
111 | _NCrunch_*
112 | .*crunch*.local.xml
113 | nCrunchTemp_*
114 |
115 | # MightyMoose
116 | *.mm.*
117 | AutoTest.Net/
118 |
119 | # Web workbench (sass)
120 | .sass-cache/
121 |
122 | # Installshield output folder
123 | [Ee]xpress/
124 |
125 | # DocProject is a documentation generator add-in
126 | DocProject/buildhelp/
127 | DocProject/Help/*.HxT
128 | DocProject/Help/*.HxC
129 | DocProject/Help/*.hhc
130 | DocProject/Help/*.hhk
131 | DocProject/Help/*.hhp
132 | DocProject/Help/Html2
133 | DocProject/Help/html
134 |
135 | # Click-Once directory
136 | publish/
137 |
138 | # Publish Web Output
139 | *.[Pp]ublish.xml
140 | *.azurePubxml
141 | # TODO: Comment the next line if you want to checkin your web deploy settings
142 | # but database connection strings (with potential passwords) will be unencrypted
143 | *.pubxml
144 | *.publishproj
145 |
146 | # NuGet Packages
147 | *.nupkg
148 | # The packages folder can be ignored because of Package Restore
149 | **/packages/*
150 | # except build/, which is used as an MSBuild target.
151 | !**/packages/build/
152 | # Uncomment if necessary however generally it will be regenerated when needed
153 | #!**/packages/repositories.config
154 | # NuGet v3's project.json files produces more ignoreable files
155 | *.nuget.props
156 | *.nuget.targets
157 |
158 | # Microsoft Azure Build Output
159 | csx/
160 | *.build.csdef
161 |
162 | # Microsoft Azure Emulator
163 | ecf/
164 | rcf/
165 |
166 | # Windows Store app package directories and files
167 | AppPackages/
168 | BundleArtifacts/
169 | Package.StoreAssociation.xml
170 | _pkginfo.txt
171 |
172 | # Visual Studio cache files
173 | # files ending in .cache can be ignored
174 | *.[Cc]ache
175 | # but keep track of directories ending in .cache
176 | !*.[Cc]ache/
177 |
178 | # Others
179 | ClientBin/
180 | ~$*
181 | *~
182 | *.dbmdl
183 | *.dbproj.schemaview
184 | *.pfx
185 | *.publishsettings
186 | node_modules/
187 | orleans.codegen.cs
188 |
189 | # Since there are multiple workflows, uncomment next line to ignore bower_components
190 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
191 | #bower_components/
192 |
193 | # RIA/Silverlight projects
194 | Generated_Code/
195 |
196 | # Backup & report files from converting an old project file
197 | # to a newer Visual Studio version. Backup files are not needed,
198 | # because we have git ;-)
199 | _UpgradeReport_Files/
200 | Backup*/
201 | UpgradeLog*.XML
202 | UpgradeLog*.htm
203 |
204 | # SQL Server files
205 | *.mdf
206 | *.ldf
207 |
208 | # Business Intelligence projects
209 | *.rdl.data
210 | *.bim.layout
211 | *.bim_*.settings
212 |
213 | # Microsoft Fakes
214 | FakesAssemblies/
215 |
216 | # GhostDoc plugin setting file
217 | *.GhostDoc.xml
218 |
219 | # Node.js Tools for Visual Studio
220 | .ntvs_analysis.dat
221 |
222 | # Visual Studio 6 build log
223 | *.plg
224 |
225 | # Visual Studio 6 workspace options file
226 | *.opt
227 |
228 | # Visual Studio LightSwitch build output
229 | **/*.HTMLClient/GeneratedArtifacts
230 | **/*.DesktopClient/GeneratedArtifacts
231 | **/*.DesktopClient/ModelManifest.xml
232 | **/*.Server/GeneratedArtifacts
233 | **/*.Server/ModelManifest.xml
234 | _Pvt_Extensions
235 |
236 | # Paket dependency manager
237 | .paket/paket.exe
238 | paket-files/
239 |
240 | # FAKE - F# Make
241 | .fake/
242 |
243 | # JetBrains Rider
244 | .idea/
245 | *.sln.iml
246 | *.suo
--------------------------------------------------------------------------------
/SimpleIRCLib/DCCEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Threading.Tasks;
5 |
6 | namespace SimpleIRCLib
7 | {
8 | ///
9 | /// Event Class for containing eventhandler for Download Updates from DCCClient.cs
10 | ///
11 | public class DCCEventArgs
12 | {
13 | ///
14 | /// Event for download updates, containging information about the following
15 | /// DccString : unparsed dccstring received from server, handy for debugging purposes
16 | /// FileName : file that is currently being downloaded
17 | /// FileSize : size of file that is currently being downloaded
18 | /// Ip : server address where file originates from
19 | /// Port : port of server where file originates from
20 | /// Pack : original pack that the user requested
21 | /// Bot : original bot where the user requested a pack (file) from
22 | /// BytesPerSecond : current download speed in bytes p/s
23 | /// KBytesPerSecond : current download speed in kbytes p/s
24 | /// MBytesPerSecond : current download speed in mbytes p/s
25 | /// Status : current download status, for example: (WAITING, DOWNLOADING, FAILED, ABORTED, etc)
26 | /// Progress : percentage downloaded (0-100%) (is int!)
27 | ///
28 | ///
29 | public DCCEventArgs(DCCClient currentClient)
30 | {
31 | DccString = currentClient.NewDccString;
32 | FileName = currentClient.NewFileName;
33 | FileSize = currentClient.NewFileSize;
34 | Ip = currentClient.NewIP;
35 | Port = currentClient.NewPortNum;
36 | Pack = currentClient.PackNum;
37 | Bot = currentClient.BotName;
38 | BytesPerSecond = currentClient.BytesPerSecond;
39 | KBytesPerSecond = currentClient.KBytesPerSecond;
40 | MBytesPerSecond = currentClient.MBytesPerSecond;
41 | Status = currentClient.Status;
42 | Progress = currentClient.Progress;
43 | FilePath = currentClient.CurrentFilePath;
44 | Buffer = currentClient.Buffer;
45 | }
46 |
47 | ///
48 | /// To access the latest downloaded data (per second).
49 | ///
50 | public List Buffer { get; }
51 | ///
52 | /// Raw DCC String used for getting the file location (server) and some basic file information
53 | ///
54 | public string DccString { get; }
55 | ///
56 | /// File name of the file being downloaded
57 | ///
58 | public string FileName { get; }
59 | ///
60 | /// FileSize of the file being downloaded
61 | ///
62 | public Int64 FileSize { get; }
63 | ///
64 | /// Server address of file location
65 | ///
66 | public string Ip { get; }
67 | ///
68 | /// Port of server of file location
69 | ///
70 | public int Port { get; }
71 | ///
72 | /// Pack ID of file on bot where file resides
73 | ///
74 | public string Pack { get; }
75 | ///
76 | /// Bot name where file resides
77 | ///
78 | public string Bot { get; }
79 | ///
80 | /// Download speed in: B/s
81 | ///
82 | public long BytesPerSecond { get; }
83 | ///
84 | /// Download speed in: KB/s
85 | ///
86 | public int KBytesPerSecond { get; }
87 | ///
88 | /// Download speed in: MB/s
89 | ///
90 | public int MBytesPerSecond { get; }
91 | ///
92 | /// Download status, such as: WAITING,DOWNLOADING,FAILED:[ERROR],ABORTED
93 | ///
94 | public string Status { get; }
95 | ///
96 | /// Progress from 0-100 (%)
97 | ///
98 | public int Progress { get; }
99 | ///
100 | /// Path to file that is being downloaded
101 | ///
102 | public string FilePath { get; }
103 | }
104 |
105 | ///
106 | /// Event Class for handeling debug events fired within DCCClient.cs
107 | ///
108 | public class DCCDebugMessageArgs
109 | {
110 | ///
111 | /// Event for debug messages specific to the DCC Client
112 | ///
113 | /// debug message
114 | /// type of debug message, handy for determing where message occured
115 | public DCCDebugMessageArgs(string message, string type)
116 | {
117 | Message = message;
118 | Type = type;
119 | }
120 |
121 | ///
122 | /// Containing debug message
123 | ///
124 | public string Message { get; }
125 | ///
126 | /// Containing debug type
127 | ///
128 | public string Type { get; }
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/FormExample/FormExample.md:
--------------------------------------------------------------------------------
1 | ## `DebugForm`
2 |
3 | ```csharp
4 | public class FormExample.DebugForm
5 | : Form, IComponent, IDisposable, IOleControl, IOleObject, IOleInPlaceObject, IOleInPlaceActiveObject, IOleWindow, IViewObject, IViewObject2, IPersist, IPersistStreamInit, IPersistPropertyBag, IPersistStorage, IQuickActivate, ISupportOleDropSource, IDropTarget, ISynchronizeInvoke, IWin32Window, IArrangedElement, IBindableComponent, IContainerControl
6 |
7 | ```
8 |
9 | Methods
10 |
11 | | Type | Name | Summary |
12 | | --- | --- | --- |
13 | | `void` | ClearButton_Click(`Object` sender, `EventArgs` e) | Clears a specific rich textbox |
14 | | `void` | DebugForm_FormClosing(`Object` sender, `FormClosingEventArgs` e) | Makes sure that the form doesn't actually close, but hides instead, so debug messages can still be appended! |
15 | | `void` | DebugForm_Load(`Object` sender, `EventArgs` e) | Register event handlers for the IrcClient and DCCClient when the form loads. |
16 | | `void` | Dispose(`Boolean` disposing) | Clean up any resources being used. |
17 | | `void` | OnDccDebugMessage(`Object` source, `DCCDebugMessageArgs` args) | Event for receiving debug messages from the DccClient |
18 | | `void` | OnDccDebugMessageLocal(`String` type, `String` message) | For appending the debug message on the main thread using invoke required. |
19 | | `void` | OnIrcDebugMessage(`Object` source, `IrcDebugMessageEventArgs` args) | Event for receiving debug messages from the IrcClient |
20 | | `void` | OnIrcDebugMessageLocal(`String` type, `String` message) | For appending the debug message on the main thread using invoke required. |
21 | | `void` | OnRawMessageReceived(`Object` source, `IrcRawReceivedEventArgs` args) | Event for receiving raw messages from the irc server. |
22 | | `void` | OnRawMessageReceivedLocal(`String` message) | For appending the rawmessage on the main thread using invoke required. |
23 |
24 |
25 | ## `IrcClientForm`
26 |
27 | This class is meant as example on how to use SimpleIRCLib, this does not mean that this is the correct way to program! It's meant to showcase a few of the available methods within SimpleIRCLib, you should figure out on your own how to implement it to suit your needs! It lacks a few options, such as leaving a specific channel, which will be implemented in the future. If your knowledged, you could send a raw message to the server containing commands to PART from a channel and use the OnRawMessageReceived event to check the server response.
28 | ```csharp
29 | public class FormExample.IrcClientForm
30 | : Form, IComponent, IDisposable, IOleControl, IOleObject, IOleInPlaceObject, IOleInPlaceActiveObject, IOleWindow, IViewObject, IViewObject2, IPersist, IPersistStreamInit, IPersistPropertyBag, IPersistStorage, IQuickActivate, ISupportOleDropSource, IDropTarget, ISynchronizeInvoke, IWin32Window, IArrangedElement, IBindableComponent, IContainerControl
31 |
32 | ```
33 |
34 | Methods
35 |
36 | | Type | Name | Summary |
37 | | --- | --- | --- |
38 | | `void` | ConnectButton_Click(`Object` sender, `EventArgs` e) | Gets the values from the input fields and starts the client |
39 | | `void` | DisconnectButton_Click(`Object` sender, `EventArgs` e) | Disconnects the irc client, closes all open tabs. |
40 | | `void` | Dispose(`Boolean` disposing) | Clean up any resources being used. |
41 | | `void` | DownloadsList_MouseDoubleClick(`Object` sender, `MouseEventArgs` e) | Opens the folder where the selected file is being downloaded to |
42 | | `void` | Form1_FormClosing(`Object` sender, `FormClosingEventArgs` e) | Stops the irc client on form close, otherwise it would keep running in the background!!! |
43 | | `void` | MessageInput_KeyDown(`Object` sender, `KeyEventArgs` e) | Sends if enter is pressed. |
44 | | `void` | OnDccEvent(`Object` sender, `DCCEventArgs` args) | Event that fires when DCCClient starts downloading. |
45 | | `void` | OnMessagesReceived(`Object` sender, `IrcReceivedEventArgs` args) | Event handler for receiving messages from the Irc Client. |
46 | | `void` | OnMessagesReceivedLocal(`String` channel, `String` user, `String` message) | Method that gets invoked on the main thread, adds a message to the richtextbox within a the correct channel tab. |
47 | | `void` | OnUserListReceived(`Object` sender, `IrcUserListReceivedEventArgs` args) | Event that gets fired when a user list has been received. |
48 | | `void` | OnUserListReceivedLocal(`Dictionary>` userList) | Method to invoke on the main thread, checks if a tab for the chat exists with name of the channel, if not, it creates it, same goes for the tab with the user name list. |
49 | | `void` | SendToAll_Click(`Object` sender, `EventArgs` e) | Sends a message to all channels. |
50 | | `void` | SendToChannel_Click(`Object` sender, `EventArgs` e) | Sends a message to a specific channel. |
51 | | `void` | SetDownloadFolderButton_Click(`Object` sender, `EventArgs` e) | Set download directory to a custom directory |
52 | | `void` | ShowDebugButton_Click(`Object` sender, `EventArgs` e) | Opens the debug form |
53 | | `void` | UpdateDownloadList(`String` toUpdate, `String` fileName) | Updates the DownloadList object on the main form while the download is going, invoke is necesary because method is being called from a different Thread! |
54 | | `void` | UpdateProgressBar(`Int32` progress) | Updates the progress bar |
55 | | `void` | UpdateUserList_Click(`Object` sender, `EventArgs` e) | Gets the users in the current channel. |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/IrcLibTest/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using SimpleIRCLib;
7 | using System.Threading;
8 |
9 | namespace IrcLibTest
10 | {
11 | class Program
12 | {
13 |
14 | private static SimpleIRC irc;
15 | static void Main(string[] args)
16 | {
17 | //setup vars
18 | string ip;
19 | int port;
20 | string username;
21 | string password;
22 | string channel;
23 |
24 | Console.WriteLine("Server IP(default is : irc.rizon.net) = ");
25 | if ((ip = Console.ReadLine()) == "")
26 | {
27 | ip = "irc.rizon.net";
28 | }
29 |
30 | Console.WriteLine("Server Port(default is : 6697 with ssl enabled) = ");
31 | if (Console.ReadLine() != "")
32 | {
33 | port = Convert.ToInt32(Console.ReadLine());
34 | }
35 | else
36 | {
37 | port = 6697;
38 | }
39 |
40 | Console.WriteLine("Username(default is : RareIRC_Client) = ");
41 | if ((username = Console.ReadLine()) == "")
42 | {
43 | username = "RareIRC_ConsoleTestClient";
44 | }
45 |
46 | Console.WriteLine("Password(not working yet, default is : ) = ");
47 | if ((password = Console.ReadLine()) == "")
48 | {
49 | password = "";
50 | }
51 |
52 | Console.WriteLine("Channel(default is : #RareIRC) = ");
53 | if ((channel = Console.ReadLine()) == "")
54 | {
55 | channel = "#RareIRC";
56 | }
57 |
58 | irc = new SimpleIRC();
59 |
60 | irc.SetupIrc(ip, username, channel, port);
61 |
62 | irc.IrcClient.OnDebugMessage += debugOutputCallback;
63 | irc.IrcClient.OnMessageReceived += chatOutputCallback;
64 | irc.IrcClient.OnRawMessageReceived += rawOutputCallback;
65 | irc.IrcClient.OnUserListReceived += userListCallback;
66 |
67 | irc.DccClient.OnDccDebugMessage += dccDebugCallback;
68 | irc.DccClient.OnDccEvent += downloadStatusChanged;
69 |
70 | irc.StartClient();
71 |
72 | while (true)
73 | {
74 |
75 | string Input = Console.ReadLine();
76 | if (Input != null || Input != "" || Input != String.Empty && irc.IsClientRunning())
77 | {
78 | irc.SendMessageToAll(Input);
79 | }
80 |
81 | }
82 | }
83 |
84 | public static void downloadStatusChanged(object source, DCCEventArgs args)
85 | {
86 | Console.WriteLine("===============DCC EVENT===============");
87 | Console.WriteLine("DOWNLOAD STATUS: " + args.Status);
88 | Console.WriteLine("DOWNLOAD FILENAME: " + args.FileName);
89 | Console.WriteLine("DOWNLOAD PROGRESS: " + args.Progress + "%");
90 | Console.WriteLine("===============END DCC EVENT===============");
91 | Console.WriteLine("");
92 | }
93 |
94 | public static void chatOutputCallback(object source, IrcReceivedEventArgs args)
95 | {
96 | Console.WriteLine("===============IRC MESSAGE===============");
97 | Console.WriteLine(args.Channel + " | " + args.User + ": " + args.Message);
98 | Console.WriteLine("===============END IRC MESSAGE===============");
99 | Console.WriteLine("");
100 | }
101 |
102 | public static void rawOutputCallback(object source, IrcRawReceivedEventArgs args)
103 | {
104 | Console.WriteLine("===============RAW MESSAGE===============");
105 | Console.WriteLine("RAW: " + args.Message);
106 | Console.WriteLine("===============END RAW MESSAGE===============");
107 | }
108 |
109 | public static void debugOutputCallback(object source, IrcDebugMessageEventArgs args)
110 | {
111 | Console.WriteLine("===============IRC DEBUG MESSAGE===============");
112 | Console.WriteLine(args.Type + "|" + args.Message);
113 | Console.WriteLine("===============END IRC DEBUG MESSAGE===============");
114 | }
115 |
116 | public static void userListCallback(object source, IrcUserListReceivedEventArgs args)
117 | {
118 | foreach(KeyValuePair> usersPerChannel in args.UsersPerChannel)
119 | {
120 | Console.WriteLine("===============USERS ON CHANNEL " + usersPerChannel.Key + " ===============");
121 | foreach (string user in usersPerChannel.Value)
122 | {
123 | Console.WriteLine(user);
124 | }
125 | Console.WriteLine("===============END USERS ON CHANNEL " + usersPerChannel.Key + " ===============");
126 | }
127 | }
128 |
129 | public static void dccDebugCallback(object source, DCCDebugMessageArgs args)
130 | {
131 | Console.WriteLine("===============IRC DEBUG MESSAGE===============");
132 | Console.WriteLine(args.Type + "|" + args.Message);
133 | Console.WriteLine("===============END IRC DEBUG MESSAGE===============");
134 | }
135 |
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SimpleIRCLib for Csharp
2 | **THIS LIBRARY IS STILL IN DEVELOPMENT**
3 | **STARTING AT V2.0.0 THIS LIBRARY IS NOT BACK-WARDS COMPATIBLE WITH PREVIOUS VERSIONS!**
4 |
5 | This library is designed to make communication through IRC easier to implement in your application. In comparison to other C# IRC libraries, this library also enables you to download using the DCC (XDCC) protocol, used by IRC.
6 |
7 | It's main features are:
8 |
9 | - Is simple to use.
10 | - Is simple to implement
11 | - It's lightweight
12 | - Multiple channel support
13 | - DCC Download support
14 |
15 | ### NuGet
16 | [NuGet Package](https://www.nuget.org/packages/SimpleIRCLib)
17 |
18 | ### Version
19 | 1.0.0:
20 | - First release version
21 |
22 | 1.0.1:
23 | - Fixed bug where leaving out debug callback would cause nullreferenceexception.
24 |
25 |
26 | 1.1.1:
27 | - Added split in username | message
28 | - Added quit/disconnect method
29 | - removed usesless getters and setters
30 | - fixed a few more less significant bugs
31 |
32 | 1.1.2:
33 | - Removed getDownloadProgress, now download information can be retreived within the downloadStatusChangedCallback.
34 | - Fixed error when you try to check if client is running before connecting to a server!
35 |
36 | 1.1.3:
37 | - Code mostly reworked by following feedback from this post: [reddit](https://www.reddit.com/r/csharp/comments/452i80/simple_irc_library_with_dcc_download_option_d/), such as:
38 | - removed static fields
39 | - removed inheriting classes
40 | - text now being parsed through regex
41 | - for receiving messages: a async task instead of a thread
42 | - getDownloadProgress/downloadStatusChangedCallback has different way of operation (see below)
43 | - addes status attribute for downloadstatus/progress
44 |
45 | 1.1.3 -> 1.1.7:
46 | - stability issues fixed
47 |
48 | 1.1.8:
49 | - bugfixes, see commit description
50 |
51 | 1.1.9:
52 | - bugfixes, see commit description
53 |
54 | 1.2.0
55 | - Functionality update: Added method to retreive all the users in the current channel, as well as in other channels (but most of them will be hidden, so not very usefull ^^).
56 |
57 | 1.2.1
58 | - Functionality update: Send Raw Messages (such as NICK, PRIVMSG etc.)
59 | - Functionality update: Retreive Raw Data
60 | - Functionality update: Send /msg using normal sendMessage() function
61 | - Functionality update: Receive Notice message just like PRIVMSG (end user sees the source of the notice, for example: NickServ: bla bla bla)
62 | - Code update: changed parsing messages a bit.
63 |
64 | 1.2.2
65 | - Fixed issue with downloading filesizes larger than 4Gb.
66 |
67 | 1.2.3
68 | - Abort download only deletes file if it was actually downloading the file.(had issues where it would still delete even if the file was already done downloading)
69 |
70 | 1.2.4
71 | - Bug where some DCC SEND messages from bots were not detected & parsed properly.
72 | - Should support IPv6 now. (Not really tested).
73 | - Added function to check if download thread is still running.
74 | - Added some debug messages for debugging purposes.
75 | - Default download directory is now set to the same directory where the libary resides.
76 | - Added flag to check if an error occured of any kind within the library (doesn't tell what kind of error yet).
77 |
78 | 2.0.0
79 | - Rewritten IrcConnect class (now called IrcClient) to prevent Race conditions!
80 | - Added timeout warnings.
81 | - Added support for TLS/SSL
82 | - Added better error handeling using the error codes from RFC 1459 IRC Protocol
83 | - Added full support for receiving and sending to seperate channels
84 | - Added comments and changed names to fit C# code convention
85 | - Under the hood DCC fixes for more stability and error handeling when downloads go wrong
86 | - **Changed Action based callback methods to Event handlers**
87 |
88 | 2.1.0
89 | - Support for multiple .NET FrameWorks such as: .NET 4.5, .NET 4.6, .NET 4.7 & .NET CORE 2.0 & .NET CORE 2.1
90 | - Renamed a few properties.
91 |
92 | 2.1.1 & 2.1.2
93 | - DCC Fixes
94 |
95 | 2.2.0
96 | - Moved from multiple target framework to single framework: NETStandard2.0.
97 |
98 | ### Wiki
99 | To get a better picture of the available methods and properties, go to this wiki:
100 | [SimpleIRCLib Wiki](https://github.com/EldinZenderink/SimpleIRCLib/wiki/SimpleIRCLib-Methods-Wiki#simpleirc)
101 |
102 | For a full WinForms example, go to:
103 | [WinForm Example](https://github.com/EldinZenderink/SimpleIRCLib/tree/master/FormExample)
104 |
105 | For a simplified console example:
106 | [Console Example](https://github.com/EldinZenderink/SimpleIRCLib/tree/master/IrcLibTest)
107 |
108 | ### Tutorial
109 | A winform example including video tutorial (v1.1.2) **OLD - NOT SUPPORTED FOR v2.0.0**:
110 | [YouTube](https://www.youtube.com/watch?v=Y5JPdwFwoSI)
111 |
112 | -New v2.0.0 and up tutorial comming soon!
113 |
114 | ### Development
115 | I will try to fix (significant) bugs as quick as possible, but due to my study taking a rollercoaster dive in a few days it might take a while before an actual update will appear. It is very barebone and does need some refinement. So, progress in development will come down to how much free time I have and how much of it I want to spend working on this library.
116 |
117 | ### Todos
118 |
119 | - Some DCC fixes, most things seem to work, but there are some odd cases where it might not work.
120 | - More readable code (getting better)
121 | - Renaming some stupidly named names
122 |
123 |
124 | ### Disclaimer
125 | This library is still in alpha stadium, many things might go wrong and therefore I am not
126 | responsible for whatever happens while you use this application.
127 |
128 | License
129 | ----
130 |
131 | MIT
132 |
133 |
134 | **Free Software, Hell Yeah!**
135 |
136 |
--------------------------------------------------------------------------------
/SimpleIRCLib/SimpleIRCLib.md:
--------------------------------------------------------------------------------
1 | ## `DCCClient`
2 |
3 | ```csharp
4 | public class SimpleIRCLib.DCCClient
5 |
6 | ```
7 |
8 | Properties
9 |
10 | | Type | Name | Summary |
11 | | --- | --- | --- |
12 | | `String` | BotName | |
13 | | `Int64` | BytesPerSecond | |
14 | | `String` | CurrentFilePath | |
15 | | `Boolean` | IsDownloading | |
16 | | `Int32` | KBytesPerSecond | |
17 | | `Int32` | MBytesPerSecond | |
18 | | `String` | NewDccString | |
19 | | `String` | NewFileName | |
20 | | `Int64` | NewFileSize | |
21 | | `String` | NewIp | |
22 | | `String` | NewIp2 | |
23 | | `Int32` | NewPortNum | |
24 | | `String` | PackNum | |
25 | | `Int32` | Progress | |
26 | | `String` | Status | |
27 |
28 |
29 | Events
30 |
31 | | Type | Name | Summary |
32 | | --- | --- | --- |
33 | | `EventHandler` | OnDccDebugMessage | |
34 | | `EventHandler` | OnDccEvent | |
35 |
36 |
37 | Methods
38 |
39 | | Type | Name | Summary |
40 | | --- | --- | --- |
41 | | `Boolean` | AbortDownloader(`Int32` timeOut) | |
42 | | `Boolean` | CheckIfDownloading() | |
43 | | `void` | Downloader() | |
44 | | `void` | StartDownloader(`String` dccString, `String` downloaddir, `String` bot, `String` pack, `IrcClient` client) | |
45 |
46 |
47 | ## `DCCDebugMessageArgs`
48 |
49 | ```csharp
50 | public class SimpleIRCLib.DCCDebugMessageArgs
51 |
52 | ```
53 |
54 | Properties
55 |
56 | | Type | Name | Summary |
57 | | --- | --- | --- |
58 | | `String` | Message | |
59 | | `String` | Type | |
60 |
61 |
62 | ## `DCCEventArgs`
63 |
64 | ```csharp
65 | public class SimpleIRCLib.DCCEventArgs
66 |
67 | ```
68 |
69 | Properties
70 |
71 | | Type | Name | Summary |
72 | | --- | --- | --- |
73 | | `String` | Bot | |
74 | | `Int64` | BytesPerSecond | |
75 | | `String` | DccString | |
76 | | `String` | FileName | |
77 | | `Int64` | FileSize | |
78 | | `String` | Ip | |
79 | | `Int32` | KBytesPerSecond | |
80 | | `Int32` | MBytesPerSecond | |
81 | | `String` | Pack | |
82 | | `Int32` | Port | |
83 | | `Int32` | Progress | |
84 | | `String` | Status | |
85 |
86 |
87 | ## `IrcClient`
88 |
89 | ```csharp
90 | public class SimpleIRCLib.IrcClient
91 |
92 | ```
93 |
94 | Events
95 |
96 | | Type | Name | Summary |
97 | | --- | --- | --- |
98 | | `EventHandler` | OnDebugMessageReceived | |
99 | | `EventHandler` | OnMessageReceived | |
100 | | `EventHandler` | OnRawMessageReceived | |
101 | | `EventHandler` | OnUserListReceived | |
102 |
103 |
104 | Methods
105 |
106 | | Type | Name | Summary |
107 | | --- | --- | --- |
108 | | `Boolean` | CheckIfDownloading() | |
109 | | `Boolean` | Connect() | |
110 | | `Boolean` | GetUsersInChannel(`String` channel = ) | |
111 | | `Boolean` | IsClientRunning() | |
112 | | `Boolean` | IsConnectionEstablished() | |
113 | | `Boolean` | QuitConnect() | |
114 | | `Boolean` | SendMessageToAll(`String` input) | |
115 | | `Boolean` | SendMessageToChannel(`String` input, `String` channel) | |
116 | | `Boolean` | SendRawMsg(`String` msg) | |
117 | | `void` | SetConnectionInformation(`String` ip, `String` username, `String` channel, `DCCClient` dccClient, `String` downloadDirectory, `Int32` port = 0, `String` password = , `Int32` timeout = 3000, `Boolean` enableSSL = True) | |
118 | | `void` | SetDownloadDirectory(`String` downloadDirectory) | |
119 | | `void` | StartReceivingChat() | |
120 | | `void` | StopClient() | |
121 | | `Boolean` | StopXDCCDownload() | |
122 | | `Boolean` | WriteIrc(`String` input) | |
123 |
124 |
125 | ## `IrcDebugMessageEventArgs`
126 |
127 | ```csharp
128 | public class SimpleIRCLib.IrcDebugMessageEventArgs
129 |
130 | ```
131 |
132 | Properties
133 |
134 | | Type | Name | Summary |
135 | | --- | --- | --- |
136 | | `String` | Message | |
137 | | `String` | Type | |
138 |
139 |
140 | ## `IrcRawReceivedEventArgs`
141 |
142 | ```csharp
143 | public class SimpleIRCLib.IrcRawReceivedEventArgs
144 |
145 | ```
146 |
147 | Properties
148 |
149 | | Type | Name | Summary |
150 | | --- | --- | --- |
151 | | `String` | Message | |
152 |
153 |
154 | ## `IrcReceivedEventArgs`
155 |
156 | ```csharp
157 | public class SimpleIRCLib.IrcReceivedEventArgs
158 |
159 | ```
160 |
161 | Properties
162 |
163 | | Type | Name | Summary |
164 | | --- | --- | --- |
165 | | `String` | Channel | |
166 | | `String` | Message | |
167 | | `String` | User | |
168 |
169 |
170 | ## `IrcUserListReceivedEventArgs`
171 |
172 | ```csharp
173 | public class SimpleIRCLib.IrcUserListReceivedEventArgs
174 |
175 | ```
176 |
177 | Properties
178 |
179 | | Type | Name | Summary |
180 | | --- | --- | --- |
181 | | `Dictionary>` | UsersPerChannel | |
182 |
183 |
184 | ## `SimpleIRC`
185 |
186 | ```csharp
187 | public class SimpleIRCLib.SimpleIRC
188 |
189 | ```
190 |
191 | Properties
192 |
193 | | Type | Name | Summary |
194 | | --- | --- | --- |
195 | | `DCCClient` | DccClient | |
196 | | `IrcClient` | IrcClient | |
197 |
198 |
199 | Methods
200 |
201 | | Type | Name | Summary |
202 | | --- | --- | --- |
203 | | `Boolean` | CheckIfDownload() | |
204 | | `void` | GetUsersInCurrentChannel() | |
205 | | `void` | GetUsersInDifferentChannel(`String` channel) | |
206 | | `Boolean` | IsClientRunning() | |
207 | | `Boolean` | SendMessageToAll(`String` message) | |
208 | | `Boolean` | SendMessageToChannel(`String` message, `String` channel) | |
209 | | `Boolean` | SendRawMessage(`String` message) | |
210 | | `void` | SetCustomDownloadDir(`String` downloaddir) | |
211 | | `void` | SetupIrc(`String` ip, `String` username, `String` channel, `Int32` port = 0, `String` password = , `Int32` timeout = 3000, `Boolean` enableSSL = True) | |
212 | | `Boolean` | StartClient() | |
213 | | `Boolean` | StopClient() | |
214 | | `Boolean` | StopXDCCDownload() | |
215 |
216 |
217 |
--------------------------------------------------------------------------------
/FormExample/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/FormExample/DebugForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/FormExample/DebugForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 | using SimpleIRCLib;
11 |
12 | namespace FormExample
13 | {
14 | public partial class DebugForm : Form
15 | {
16 |
17 | private readonly SimpleIRC _simpleIrc;
18 |
19 | ///
20 | /// Constructor for the debug form.
21 | ///
22 | /// SimpleIRC instance
23 | public DebugForm(SimpleIRC irc)
24 | {
25 | _simpleIrc = irc;
26 | InitializeComponent();
27 | }
28 |
29 | ///
30 | /// Clears a specific rich textbox
31 | ///
32 | ///
33 | ///
34 | public void ClearButton_Click(object sender, EventArgs e)
35 | {
36 | RichTextBox selectedRtb = (RichTextBox)debugTabs.SelectedTab.Controls[0];
37 | selectedRtb.Clear();
38 | }
39 |
40 | ///
41 | /// Makes sure that the form doesn't actually close, but hides instead, so debug messages can still be appended!
42 | ///
43 | ///
44 | ///
45 | public void DebugForm_FormClosing(object sender, FormClosingEventArgs e)
46 | {
47 | if (e.CloseReason == CloseReason.UserClosing)
48 | {
49 | e.Cancel = true;
50 | Hide();
51 | }
52 | }
53 |
54 | ///
55 | /// Register event handlers for the IrcClient and DCCClient when the form loads.
56 | ///
57 | ///
58 | ///
59 | public void DebugForm_Load(object sender, EventArgs e)
60 | {
61 | _simpleIrc.IrcClient.OnDebugMessage += OnIrcDebugMessage;
62 | _simpleIrc.IrcClient.OnRawMessageReceived += OnRawMessageReceived;
63 | _simpleIrc.DccClient.OnDccDebugMessage += OnDccDebugMessage;
64 | }
65 |
66 | ///
67 | /// Event for receiving debug messages from the IrcClient
68 | ///
69 | /// source class
70 | /// IrcDebugMessageEventArgs contains debug message and type
71 | public void OnIrcDebugMessage(object source, IrcDebugMessageEventArgs args)
72 | {
73 | OnIrcDebugMessageLocal(args.Type, args.Message);
74 | }
75 |
76 | ///
77 | /// For appending the debug message on the main thread using invoke required.
78 | ///
79 | /// Debug message type, handy for figuring out where the debug message came from
80 | /// message to append to the rich textbox
81 | public void OnIrcDebugMessageLocal(string type, string message)
82 | {
83 | if (this.InvokeRequired)
84 | {
85 | this.Invoke(new MethodInvoker(() => OnIrcDebugMessageLocal(type, message)));
86 | }
87 | else
88 | {
89 | if (debugTabs != null)
90 | {
91 | RichTextBox selectedRtb = (RichTextBox)debugTabs.TabPages[0].Controls[0];
92 | selectedRtb.AppendText(type + " | " + message + Environment.NewLine);
93 | }
94 | }
95 | }
96 |
97 | ///
98 | /// Event for receiving raw messages from the irc server.
99 | ///
100 | /// source class
101 | /// IrcRawReceivedEventArgs contains the message received
102 | public void OnRawMessageReceived(object source, IrcRawReceivedEventArgs args)
103 | {
104 | OnRawMessageReceivedLocal(args.Message);
105 | }
106 |
107 | ///
108 | /// For appending the rawmessage on the main thread using invoke required.
109 | ///
110 | /// message to append to the rich textbox
111 | public void OnRawMessageReceivedLocal(string message)
112 | {
113 | if (this.InvokeRequired)
114 | {
115 | this.Invoke(new MethodInvoker(() => OnRawMessageReceivedLocal(message)));
116 | }
117 | else
118 | {
119 | if (debugTabs != null)
120 | {
121 | RichTextBox selectedRtb = (RichTextBox) debugTabs.TabPages[2].Controls[0];
122 | selectedRtb.AppendText(message + Environment.NewLine);
123 | }
124 | }
125 | }
126 |
127 | ///
128 | /// Event for receiving debug messages from the DccClient
129 | ///
130 | /// source class
131 | /// DCCDebugMessageArgs contains the debug message and type
132 | public void OnDccDebugMessage(object source, DCCDebugMessageArgs args)
133 | {
134 | OnDccDebugMessageLocal(args.Type, args.Message);
135 | }
136 |
137 | ///
138 | /// For appending the debug message on the main thread using invoke required.
139 | ///
140 | /// Debug message type, handy for figuring out where the debug message came from
141 | /// message to append to the rich textbox
142 | public void OnDccDebugMessageLocal(string type, string message)
143 | {
144 | if (this.InvokeRequired)
145 | {
146 | this.Invoke(new MethodInvoker(() => OnDccDebugMessageLocal(type, message)));
147 | }
148 | else
149 | {
150 | if (debugTabs != null)
151 | {
152 | RichTextBox selectedRtb = (RichTextBox) debugTabs.TabPages[1].Controls[0];
153 | selectedRtb.AppendText(type + " | " + message + Environment.NewLine);
154 | }
155 | }
156 | }
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/FormExample/IrcClientForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
124 | 181, 17
125 |
126 |
--------------------------------------------------------------------------------
/FormExample/DebugForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace FormExample
2 | {
3 | partial class DebugForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.ClearButton = new System.Windows.Forms.Button();
32 | this.debugTabs = new System.Windows.Forms.TabControl();
33 | this.ircDebug = new System.Windows.Forms.TabPage();
34 | this.dccDebug = new System.Windows.Forms.TabPage();
35 | this.ircDebugRichTextbox = new System.Windows.Forms.RichTextBox();
36 | this.dccDebugRichTextBox = new System.Windows.Forms.RichTextBox();
37 | this.ircRawOutput = new System.Windows.Forms.TabPage();
38 | this.rawIrcOutput = new System.Windows.Forms.RichTextBox();
39 | this.debugTabs.SuspendLayout();
40 | this.ircDebug.SuspendLayout();
41 | this.dccDebug.SuspendLayout();
42 | this.ircRawOutput.SuspendLayout();
43 | this.SuspendLayout();
44 | //
45 | // ClearButton
46 | //
47 | this.ClearButton.Location = new System.Drawing.Point(12, 394);
48 | this.ClearButton.Name = "ClearButton";
49 | this.ClearButton.Size = new System.Drawing.Size(449, 23);
50 | this.ClearButton.TabIndex = 1;
51 | this.ClearButton.Text = "Clear";
52 | this.ClearButton.UseVisualStyleBackColor = true;
53 | this.ClearButton.Click += new System.EventHandler(this.ClearButton_Click);
54 | //
55 | // debugTabs
56 | //
57 | this.debugTabs.Controls.Add(this.ircDebug);
58 | this.debugTabs.Controls.Add(this.dccDebug);
59 | this.debugTabs.Controls.Add(this.ircRawOutput);
60 | this.debugTabs.Location = new System.Drawing.Point(12, 0);
61 | this.debugTabs.Name = "debugTabs";
62 | this.debugTabs.SelectedIndex = 0;
63 | this.debugTabs.Size = new System.Drawing.Size(460, 388);
64 | this.debugTabs.TabIndex = 2;
65 | //
66 | // ircDebug
67 | //
68 | this.ircDebug.Controls.Add(this.ircDebugRichTextbox);
69 | this.ircDebug.Location = new System.Drawing.Point(4, 22);
70 | this.ircDebug.Name = "ircDebug";
71 | this.ircDebug.Padding = new System.Windows.Forms.Padding(3);
72 | this.ircDebug.Size = new System.Drawing.Size(452, 362);
73 | this.ircDebug.TabIndex = 0;
74 | this.ircDebug.Text = "IRC Debug";
75 | this.ircDebug.UseVisualStyleBackColor = true;
76 | //
77 | // dccDebug
78 | //
79 | this.dccDebug.Controls.Add(this.dccDebugRichTextBox);
80 | this.dccDebug.Location = new System.Drawing.Point(4, 22);
81 | this.dccDebug.Name = "dccDebug";
82 | this.dccDebug.Padding = new System.Windows.Forms.Padding(3);
83 | this.dccDebug.Size = new System.Drawing.Size(452, 362);
84 | this.dccDebug.TabIndex = 1;
85 | this.dccDebug.Text = "DCC Debug";
86 | this.dccDebug.UseVisualStyleBackColor = true;
87 | //
88 | // ircDebugRichTextbox
89 | //
90 | this.ircDebugRichTextbox.Location = new System.Drawing.Point(6, 6);
91 | this.ircDebugRichTextbox.Name = "ircDebugRichTextbox";
92 | this.ircDebugRichTextbox.Size = new System.Drawing.Size(439, 350);
93 | this.ircDebugRichTextbox.TabIndex = 0;
94 | this.ircDebugRichTextbox.Text = "";
95 | //
96 | // dccDebugRichTextBox
97 | //
98 | this.dccDebugRichTextBox.Location = new System.Drawing.Point(6, 6);
99 | this.dccDebugRichTextBox.Name = "dccDebugRichTextBox";
100 | this.dccDebugRichTextBox.Size = new System.Drawing.Size(440, 353);
101 | this.dccDebugRichTextBox.TabIndex = 0;
102 | this.dccDebugRichTextBox.Text = "";
103 | //
104 | // ircRawOutput
105 | //
106 | this.ircRawOutput.Controls.Add(this.rawIrcOutput);
107 | this.ircRawOutput.Location = new System.Drawing.Point(4, 22);
108 | this.ircRawOutput.Name = "ircRawOutput";
109 | this.ircRawOutput.Size = new System.Drawing.Size(452, 362);
110 | this.ircRawOutput.TabIndex = 2;
111 | this.ircRawOutput.Text = "Irc Raw Output";
112 | this.ircRawOutput.UseVisualStyleBackColor = true;
113 | //
114 | // rawIrcOutput
115 | //
116 | this.rawIrcOutput.Location = new System.Drawing.Point(4, 4);
117 | this.rawIrcOutput.Name = "rawIrcOutput";
118 | this.rawIrcOutput.Size = new System.Drawing.Size(441, 355);
119 | this.rawIrcOutput.TabIndex = 0;
120 | this.rawIrcOutput.Text = "";
121 | //
122 | // DebugForm
123 | //
124 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
125 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
126 | this.ClientSize = new System.Drawing.Size(473, 427);
127 | this.Controls.Add(this.debugTabs);
128 | this.Controls.Add(this.ClearButton);
129 | this.Name = "DebugForm";
130 | this.Text = "DebugForm";
131 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.DebugForm_FormClosing);
132 | this.Load += new System.EventHandler(this.DebugForm_Load);
133 | this.debugTabs.ResumeLayout(false);
134 | this.ircDebug.ResumeLayout(false);
135 | this.dccDebug.ResumeLayout(false);
136 | this.ircRawOutput.ResumeLayout(false);
137 | this.ResumeLayout(false);
138 |
139 | }
140 |
141 | #endregion
142 | private System.Windows.Forms.Button ClearButton;
143 | private System.Windows.Forms.TabControl debugTabs;
144 | private System.Windows.Forms.TabPage ircDebug;
145 | private System.Windows.Forms.RichTextBox ircDebugRichTextbox;
146 | private System.Windows.Forms.TabPage dccDebug;
147 | private System.Windows.Forms.RichTextBox dccDebugRichTextBox;
148 | private System.Windows.Forms.TabPage ircRawOutput;
149 | private System.Windows.Forms.RichTextBox rawIrcOutput;
150 | }
151 | }
--------------------------------------------------------------------------------
/SimpleIRCLib/SimpleIRC.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 | using System.Threading;
5 |
6 | namespace SimpleIRCLib
7 | {
8 | ///
9 | /// A combiner class that combines all the logic from both the IrcClient & DCCClient with simple methods to control these clients.
10 | ///
11 | public class SimpleIRC
12 | {
13 |
14 |
15 | ///
16 | /// Ip address of irc server
17 | ///
18 | public string NewIP{ get; set; }
19 | ///
20 | /// Port of irc server to connect to
21 | ///
22 | public int NewPort { get; set; }
23 | ///
24 | /// Username to register on irc server
25 | ///
26 | public string NewUsername { get; set; }
27 | ///
28 | /// List with channels seperated with ',' to join when connecting to IRC server
29 | ///
32 | /// Password to connect to a secured irc server
33 | ///
34 | public string NewPassword { get; set; }
35 | ///
36 | /// download directory used for DCCClient.cs
37 | ///
38 | public string DownloadDir { get; set; }
39 |
40 | ///
41 | /// Irc Client for sending and receiving messages to a irc server
42 | ///
43 | public IrcClient IrcClient { get; set; }
44 | ///
45 | /// DCCClient used by the IRCClient for starting a download on a separate thread using the DCC Protocol
46 | ///
47 | public DCCClient DccClient { get; set; }
48 |
49 |
50 | ///
51 | /// Constructor, sets up bot ircclient and dccclient, so that users can register event handlers.
52 | ///
53 | public SimpleIRC()
54 | {
55 | NewIP= "";
56 | NewPort = 0;
57 | NewUsername = "";
58 | NewPassword = "";
59 | NewChannels = "";
60 | DownloadDir = "";
61 | IrcClient = new IrcClient();
62 | DccClient = new DCCClient();
63 | }
64 |
65 |
66 | ///
67 | /// Setup the client to be able to connect to the server
68 | ///
69 | /// Server address, possibly works with dns addresses (irc.xxx.x), but ip addresses works just fine (of type string)
70 | /// Username the client wants to use, of type string
71 | /// Channel(s) the client wants to connect to, possible to connect to multiple channels at once by seperating each channel with a ',' (Example: #chan1,#chan2), of type string
72 | /// Port, optional parameter, where default = 0 (Automatic port selection), is port of the server you want to connect to, of type int
73 | /// Password, optional parameter, where default value is "", can be used to connect to a password protected server.
74 | /// Timeout, optional parameter, where default value is 3000 milliseconds, the maximum time before a server needs to answer, otherwise errors are thrown.
75 | /// Timeout, optional parameter, where default value is 3000 milliseconds, the maximum time before a server needs to answer, otherwise errors are thrown.
76 | public void SetupIrc(string ip, string username, string channels, int port = 0, string password = "", int timeout = 3000, bool enableSSL = true)
77 | {
78 | NewIP= ip;
79 | NewPort = port;
80 | NewUsername = username;
81 | NewPassword = password;
82 | NewChannels = channels;
83 | DownloadDir = "";
84 |
85 | IrcClient.SetConnectionInformation(ip, username, channels, DccClient, DownloadDir, port, password, timeout, enableSSL);
86 |
87 | }
88 |
89 | ///
90 | /// Sets the download directory for dcc downloads.
91 | ///
92 | /// Requires a path to a directory of type string as parameter.
93 | public void SetCustomDownloadDir(string downloaddir)
94 | {
95 | DownloadDir = downloaddir;
96 | IrcClient.SetDownloadDirectory(downloaddir);
97 | }
98 |
99 | ///
100 | /// Starts the irc client with the given parameters in the constructor
101 | ///
102 | /// true or false depending if it starts succesfully
103 | public bool StartClient()
104 | {
105 | if (IrcClient != null)
106 | {
107 | if (!IrcClient.IsConnectionEstablished())
108 | {
109 | IrcClient.Connect();
110 |
111 | int timeout = 0;
112 | while (!IrcClient.IsClientRunning())
113 | {
114 | Thread.Sleep(1);
115 | if (timeout >= 3000)
116 | {
117 | return false;
118 | }
119 | timeout++;
120 | }
121 | return true;
122 | }
123 | }
124 |
125 | return false;
126 | }
127 |
128 | ///
129 | /// Checks if the client is running.
130 | ///
131 | /// true or false
132 | public bool IsClientRunning()
133 | {
134 | return IrcClient.IsClientRunning();
135 | }
136 |
137 | ///
138 | /// Stops the client
139 | ///
140 | /// true or false depending on succes
141 | public bool StopClient()
142 | {
143 | //execute quit stuff
144 | bool check = false;
145 |
146 | check = IrcClient.StopClient();
147 | check = IrcClient.StopXDCCDownload();
148 | return check;
149 | }
150 |
151 | ///
152 | ///returns true or false upon calling this method, for telling you if the downlaod has been stopped or not
153 | ///
154 | ///
155 | public bool StopXDCCDownload()
156 | {
157 | return IrcClient.StopXDCCDownload();
158 | }
159 |
160 | ///
161 | ///returns true or false upon calling this method, for telling you if the downlaod has been stopped or not
162 | ///
163 | ///
164 | public bool CheckIfDownload()
165 | {
166 | return IrcClient.CheckIfDownloading();
167 | }
168 |
169 | ///
170 | ///get users in current channel
171 | ///
172 | public void GetUsersInCurrentChannel()
173 | {
174 | IrcClient.GetUsersInChannel();
175 | }
176 |
177 | ///
178 | ///get users in different channel, parameter is the channel name of type string (example: "#yourchannel")
179 | ///
180 | ///
181 | public void GetUsersInDifferentChannel(string channel)
182 | {
183 | IrcClient.GetUsersInChannel(channel);
184 | }
185 |
186 | ///
187 | ///send message to all channels
188 | ///
189 | /// message to send
190 | /// true if succesfully send
191 | public bool SendMessageToAll(string message)
192 | {
193 | return IrcClient.SendMessageToAll(message);
194 | }
195 |
196 | ///
197 | /// Sends a message to a specific channel.
198 | ///
199 | /// message to send
200 | /// channel for destination
201 | /// true/false depending if sending was succesfull
202 | public bool SendMessageToChannel(string message, string channel)
203 | {
204 | return IrcClient.SendMessageToChannel(message, channel);
205 | }
206 |
207 | ///
208 | /// Sends a raw message to irc server
209 | ///
210 | /// message to send
211 | /// true/false depending if sending was succesfull
212 | public bool SendRawMessage(string message)
213 | {
214 | return IrcClient.SendRawMsg(message);
215 | }
216 |
217 | }
218 | }
219 |
--------------------------------------------------------------------------------
/SimpleIRCLib/IrcCommands.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.Net.Security;
6 | using System.Net.Sockets;
7 | using System.Text;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 |
11 | namespace SimpleIRCLib
12 | {
13 | ///
14 | /// Class used for sending specific commands to the IRC server, and waiting for responses from the irc server before continueing
15 | ///
16 | class IrcCommands
17 | {
18 | ///
19 | /// reader to read from the irc server stream
20 | ///
21 | private readonly StreamReader _reader;
22 |
23 | ///
24 | /// reader to write to the irc server stream
25 | ///
26 | private readonly StreamWriter _writer;
27 |
28 | ///
29 | /// global error message string, used for defining the error that might occur with a readable string
30 | ///
31 | private string _errorMessage;
32 |
33 | ///
34 | /// global error integer, used for getting the specific error id specified within the IRC specs RFC 2812
35 | ///
36 | private int _responseNumber;
37 |
38 | ///
39 | /// user name that has been registered
40 | ///
41 | private string _username;
42 |
43 | ///
44 | /// channel that hs been joined
45 | ///
46 | private string _channels;
47 |
48 | ///
49 | /// Constructor, that requires the stream reader and writer set before initializing
50 | ///
51 | /// Stream to read/write from/to
52 | public IrcCommands(NetworkStream stream)
53 | {
54 | _reader = new StreamReader(stream);
55 | _writer = new StreamWriter(stream);
56 | }
57 |
58 | ///
59 | /// Constructor, that requires the stream reader and writer set before initializing
60 | ///
61 | /// Stream to read/write from/to
62 | public IrcCommands(SslStream stream)
63 | {
64 | _reader = new StreamReader(stream);
65 | _writer = new StreamWriter(stream);
66 | }
67 |
68 | ///
69 | /// Get the error message that probably has occured when calling this method
70 | ///
71 | /// returns error message
72 | public string GetErrorMessage()
73 | {
74 | return _errorMessage;
75 | }
76 |
77 | ///
78 | /// Get the error number that probably had occured when calling this method (RFC 2812)
79 | ///
80 | ///
81 | public int GetErrorNumber()
82 | {
83 | return _responseNumber;
84 | }
85 |
86 | ///
87 | /// Sets the password for a connection and waits if there is any response, if there is, it may continue, unless the reponse contains an error message
88 | ///
89 | /// password to set
90 | /// true/false depending if error occured
91 | public bool SetPassWord(string password)
92 | {
93 | _writer.WriteLine("PASS " + password + Environment.NewLine);
94 | _writer.Flush();
95 |
96 | while (true)
97 | {
98 | string ircData = _reader.ReadLine();
99 | if (ircData.Contains("462"))
100 | {
101 | _responseNumber = 462;
102 | _errorMessage = "PASSWORD ALREADY REGISTERED";
103 | return false;
104 | }
105 | else if (ircData.Contains("461"))
106 | {
107 | _responseNumber = 461;
108 | _errorMessage = "PASSWORD COMMAND NEEDS MORE PARAMETERS";
109 | return false;
110 | }else if (ircData.Contains("004"))
111 | {
112 | return true;
113 | }
114 | else
115 | {
116 | return true;
117 | }
118 | }
119 | }
120 |
121 | ///
122 | /// Sends the user and nick command to the irc server, checks for error messages (it waits for a reply to come through first, before deciding what to do).
123 | ///
124 | /// Username
125 | ///
126 | /// True/False, depending if error occured or not
127 | public bool JoinNetwork(string user, string channels)
128 | {
129 | _username = user;
130 | _channels = channels;
131 | _writer.WriteLine("NICK " + user + Environment.NewLine);
132 | _writer.Flush();
133 | _writer.WriteLine("USER " + user + " 8 * :" + user + "_SimpleIRCLib" + Environment.NewLine);
134 | _writer.Flush();
135 |
136 | while (true)
137 | {
138 | try
139 | {
140 | string ircData = _reader.ReadLine();
141 | if (ircData != null)
142 | {
143 | if (ircData.Contains("PING"))
144 | {
145 | string pingID = ircData.Split(':')[1];
146 | _writer.WriteLine("PONG :" + pingID);
147 | _writer.Flush();
148 | }
149 |
150 | if (CheckMessageForError(ircData))
151 | {
152 | if (_responseNumber == 266)
153 | {
154 | return JoinChannel(channels, user);
155 | }
156 | }
157 | }
158 | Thread.Sleep(1);
159 | }
160 | catch (Exception e)
161 | {
162 |
163 | Debug.WriteLine("RECEIVED: " + e.ToString());
164 | return false;
165 | }
166 | }
167 | }
168 |
169 | ///
170 | /// Sends a join request to the irc server, then waits for a response before continueing
171 | ///
172 | /// Channels to join
173 | /// Username that joins
174 | /// True on sucess, false on error
175 | public bool JoinChannel(string channels, string username)
176 | {
177 | _channels = channels;
178 |
179 | _writer.WriteLine("JOIN " + channels + Environment.NewLine);
180 | _writer.Flush();
181 | while (true)
182 | {
183 |
184 | string ircData = _reader.ReadLine();
185 | if (ircData != null)
186 | {
187 | if (ircData.Contains("PING"))
188 | {
189 | string pingID = ircData.Split(':')[1];
190 | _writer.WriteLine("PONG :" + pingID);
191 | _writer.Flush();
192 | }
193 |
194 | if (ircData.Contains(username) && ircData.Contains("JOIN"))
195 | {
196 | return true;
197 | }
198 | }
199 | Thread.Sleep(1);
200 | }
201 | }
202 |
203 | ///
204 | /// Sends the set nickname request to the server, waits until a response is given from the server before deciding to continue
205 | ///
206 | /// Nickname
207 | /// True on success, false on error.
208 | public bool SetNickName(string nickname)
209 | {
210 | _writer.WriteLine("NICK " + nickname + Environment.NewLine);
211 | _writer.Flush();
212 |
213 | while (true)
214 | {
215 |
216 | string ircData = _reader.ReadLine();
217 |
218 | return CheckMessageForError(ircData);
219 | }
220 | }
221 |
222 |
223 |
224 | public bool CheckMessageForError(string message)
225 | {
226 | string codeString = message.Split(' ')[1].Trim();
227 | if (int.TryParse(codeString, out _responseNumber))
228 | {
229 | foreach (string errorMessage in RFC1459Codes.ListWithErrors)
230 | {
231 | if (errorMessage.Contains(codeString))
232 | {
233 | _errorMessage = errorMessage;
234 | return false;
235 | }
236 | }
237 |
238 | _errorMessage = "Message does not contain Error Code!";
239 | return true;
240 | }
241 | else
242 | {
243 | Debug.WriteLine("Could not parse number");
244 | _responseNumber = 0;
245 | _errorMessage = "Message does not contain Error Code, could not parse number!";
246 | return true;
247 | }
248 |
249 |
250 | }
251 | }
252 | }
253 |
--------------------------------------------------------------------------------
/SimpleIRCLib/RFC1459Codes.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace SimpleIRCLib
8 | {
9 | ///
10 | /// Contians all the error codes specified by the RFC1459 protocol
11 | ///
12 | class RFC1459Codes
13 | {
14 | ///
15 | /// List with error messages.
16 | ///
17 | public static string[] ListWithErrors = new string[] { @"
18 | 401 ERR_NOSUCHNICK
19 | "" :No such nick/channel""
20 |
21 | - Used to indicate the nickname parameter supplied to a
22 | command is currently unused.
23 | ", @"
24 |
25 | 402 ERR_NOSUCHSERVER
26 | "" :No such server""
27 |
28 | - Used to indicate the server name given currently
29 | doesn't exist.
30 | ", @"
31 | 403 ERR_NOSUCHCHANNEL
32 | "" :No such channel""
33 |
34 | - Used to indicate the given channel name is invalid.
35 | ", @"
36 | 404 ERR_CANNOTSENDTOCHAN
37 | "" :Cannot send to channel""
38 |
39 | - Sent to a user who is either (a) not on a channel
40 | which is mode +n or (b) not a chanop (or mode +v) on
41 | a channel which has mode +m set and is trying to send
42 | a PRIVMSG message to that channel.
43 | ", @"
44 | 405 ERR_TOOMANYCHANNELS
45 | "" :You have joined too many \
46 | channels""
47 | - Sent to a user when they have joined the maximum
48 | number of allowed channels and they try to join
49 | another channel.
50 | ", @"
51 | 406 ERR_WASNOSUCHNICK
52 | "" :There was no such nickname""
53 |
54 | - Returned by WHOWAS to indicate there is no history
55 | information for that nickname.
56 | ", @"
57 | 407 ERR_TOOMANYTARGETS
58 | "" :Duplicate recipients. No message delivered""
59 |
60 | - Returned to a client which is attempting to send a
61 | PRIVMSG/NOTICE using the user@host destination format
62 | and for a user@host which has several occurrences.
63 | ", @"
64 | 409 ERR_NOORIGIN
65 | "":No origin specified""
66 |
67 | - PING or PONG message missing the originator parameter
68 | which is required since these commands must work
69 | without valid prefixes.
70 | ", @"
71 | 411 ERR_NORECIPIENT
72 | "":No recipient given ()""
73 | ", @"
74 | 412 ERR_NOTEXTTOSEND
75 | "":No text to send""
76 | ", @"
77 | 413 ERR_NOTOPLEVEL
78 | "" :No toplevel domain specified""
79 | ", @"
80 | 414 ERR_WILDTOPLEVEL
81 | "" :Wildcard in toplevel domain""
82 |
83 | - 412 - 414 are returned by PRIVMSG to indicate that
84 | the message wasn't delivered for some reason.
85 | ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that
86 | are returned when an invalid use of
87 | ""PRIVMSG $"" or ""PRIVMSG #"" is attempted.
88 | ", @"
89 | 421 ERR_UNKNOWNCOMMAND
90 | "" :Unknown command""
91 |
92 | - Returned to a registered client to indicate that the
93 | command sent is unknown by the server.
94 | ", @"
95 | 422 ERR_NOMOTD
96 | "":MOTD File is missing""
97 |
98 | - Server's MOTD file could not be opened by the server.
99 | ", @"
100 | 423 ERR_NOADMININFO
101 | "" :No administrative info available""
102 |
103 | - Returned by a server in response to an ADMIN message
104 | when there is an error in finding the appropriate
105 | information.
106 | ", @"
107 | 424 ERR_FILEERROR
108 | "":File error doing on ""
109 |
110 | - Generic error message used to report a failed file
111 | operation during the processing of a message.
112 | ", @"
113 | 431 ERR_NONICKNAMEGIVEN
114 | "":No nickname given""
115 |
116 | - Returned when a nickname parameter expected for a
117 | command and isn't found.
118 | ", @"
119 | 432 ERR_ERRONEUSNICKNAME
120 | "" :Erroneus nickname""
121 |
122 | - Returned after receiving a NICK message which contains
123 | characters which do not fall in the defined set. See
124 | section x.x.x for details on valid nicknames.
125 | ", @"
126 | 433 ERR_NICKNAMEINUSE
127 | "" :Nickname is already in use""
128 |
129 | - Returned when a NICK message is processed that results
130 | in an attempt to change to a currently existing
131 | nickname.
132 | ", @"
133 | 436 ERR_NICKCOLLISION
134 | "" :Nickname collision KILL""
135 |
136 | - Returned by a server to a client when it detects a
137 | nickname collision (registered of a NICK that
138 | already exists by another server).
139 | ", @"
140 | 441 ERR_USERNOTINCHANNEL
141 | "" :They aren't on that channel""
142 |
143 | - Returned by the server to indicate that the target
144 | user of the command is not on the given channel.
145 | ", @"
146 | 442 ERR_NOTONCHANNEL
147 | "" :You're not on that channel""
148 |
149 | - Returned by the server whenever a client tries to
150 | perform a channel effecting command for which the
151 | client isn't a member.
152 | ", @"
153 | 443 ERR_USERONCHANNEL
154 | "" :is already on channel""
155 |
156 | - Returned when a client tries to invite a user to a
157 | channel they are already on.
158 | ", @"
159 | 444 ERR_NOLOGIN
160 | "" :User not logged in""
161 |
162 | - Returned by the summon after a SUMMON command for a
163 | user was unable to be performed since they were not
164 | logged in.
165 | ", @"
166 | 445 ERR_SUMMONDISABLED
167 | "":SUMMON has been disabled""
168 |
169 | - Returned as a response to the SUMMON command. Must be
170 | returned by any server which does not implement it.
171 | ", @"
172 | 446 ERR_USERSDISABLED
173 | "":USERS has been disabled""
174 |
175 | - Returned as a response to the USERS command. Must be
176 | returned by any server which does not implement it.
177 | ", @"
178 | 451 ERR_NOTREGISTERED
179 | "":You have not registered""
180 |
181 | - Returned by the server to indicate that the client
182 | must be registered before the server will allow it
183 | to be parsed in detail.
184 | ", @"
185 | 461 ERR_NEEDMOREPARAMS
186 | "" :Not enough parameters""
187 |
188 | - Returned by the server by numerous commands to
189 | indicate to the client that it didn't supply enough
190 | parameters.
191 | ", @"
192 | 462 ERR_ALREADYREGISTRED
193 | "":You may not reregister""
194 |
195 | - Returned by the server to any link which tries to
196 | change part of the registered details (such as
197 | password or user details from second USER message).
198 | ", @"
199 | 463 ERR_NOPERMFORHOST
200 | "":Your host isn't among the privileged""
201 |
202 | - Returned to a client which attempts to register with
203 | a server which does not been setup to allow
204 | connections from the host the attempted connection
205 | is tried.
206 | ", @"
207 | 464 ERR_PASSWDMISMATCH
208 | "":Password incorrect""
209 |
210 | - Returned to indicate a failed attempt at registering
211 | a connection for which a password was required and
212 | was either not given or incorrect.
213 | ", @"
214 | 465 ERR_YOUREBANNEDCREEP
215 | "":You are banned from this server""
216 |
217 | - Returned after an attempt to connect and register
218 | yourself with a server which has been setup to
219 | explicitly deny connections to you.
220 | ", @"
221 | 467 ERR_KEYSET
222 | "" :Channel key already set""
223 | ", @"
224 | 471 ERR_CHANNELISFULL
225 | "" :Cannot join channel (+l)""
226 | ", @"
227 | 472 ERR_UNKNOWNMODE
228 | "" :is unknown mode char to me""
229 | ", @"
230 | 473 ERR_INVITEONLYCHAN
231 | "" :Cannot join channel (+i)""
232 | ", @"
233 | 474 ERR_BANNEDFROMCHAN
234 | "" :Cannot join channel (+b)""
235 | ", @"
236 | 475 ERR_BADCHANNELKEY
237 | "" :Cannot join channel (+k)""
238 | ", @"
239 | 481 ERR_NOPRIVILEGES
240 | "":Permission Denied- You're not an IRC operator""
241 |
242 | - Any command requiring operator privileges to operate
243 | must return this error to indicate the attempt was
244 | unsuccessful.
245 | ", @"
246 | 482 ERR_CHANOPRIVSNEEDED
247 | "" :You're not channel operator""
248 |
249 | - Any command requiring 'chanop' privileges (such as
250 | MODE messages) must return this error if the client
251 | making the attempt is not a chanop on the specified
252 | channel.
253 | ", @"
254 | 483 ERR_CANTKILLSERVER
255 | "":You cant kill a server!""
256 |
257 | - Any attempts to use the KILL command on a server
258 | are to be refused and this error returned directly
259 | to the client.
260 | ", @"
261 | 491 ERR_NOOPERHOST
262 | "":No O-lines for your host""
263 |
264 | - If a client sends an OPER message and the server has
265 | not been configured to allow connections from the
266 | client's host as an operator, this error must be
267 | returned.
268 | ", @"
269 | 501 ERR_UMODEUNKNOWNFLAG
270 | "":Unknown MODE flag""
271 |
272 | - Returned by the server to indicate that a MODE
273 | message was sent with a nickname parameter and that
274 | the a mode flag sent was not recognized.
275 | ", @"
276 | 502 ERR_USERSDONTMATCH
277 | "":Cant change mode for other users""
278 |
279 | - Error sent to any user trying to view or change the
280 | user mode for a user other than themselves.
281 | " };
282 |
283 | }
284 | }
285 |
--------------------------------------------------------------------------------
/FormExample/IrcClientForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace FormExample
2 | {
3 | partial class IrcClientForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.ServerInput = new System.Windows.Forms.TextBox();
32 | this.PortInput = new System.Windows.Forms.TextBox();
33 | this.UsernameInput = new System.Windows.Forms.TextBox();
34 | this.ChannelsInput = new System.Windows.Forms.TextBox();
35 | this.label1 = new System.Windows.Forms.Label();
36 | this.label2 = new System.Windows.Forms.Label();
37 | this.labelusername = new System.Windows.Forms.Label();
38 | this.labelsomething = new System.Windows.Forms.Label();
39 | this.ConnectButton = new System.Windows.Forms.Button();
40 | this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
41 | this.DisconnectButton = new System.Windows.Forms.Button();
42 | this.MessageInput = new System.Windows.Forms.TextBox();
43 | this.SendToAll = new System.Windows.Forms.Button();
44 | this.DownloadsList = new System.Windows.Forms.ListBox();
45 | this.ShowDebugButton = new System.Windows.Forms.Button();
46 | this.SetDownloadFolderButton = new System.Windows.Forms.Button();
47 | this.label3 = new System.Windows.Forms.Label();
48 | this.label4 = new System.Windows.Forms.Label();
49 | this.label5 = new System.Windows.Forms.Label();
50 | this.DownloadProgressBar = new System.Windows.Forms.ProgressBar();
51 | this.OpenFolderDialog = new System.Windows.Forms.FolderBrowserDialog();
52 | this.UpdateUserList = new System.Windows.Forms.Button();
53 | this.ircChatTabs = new System.Windows.Forms.TabControl();
54 | this.SendToChannel = new System.Windows.Forms.Button();
55 | this.userListTabs = new System.Windows.Forms.TabControl();
56 | this.SuspendLayout();
57 | //
58 | // ServerInput
59 | //
60 | this.ServerInput.Location = new System.Drawing.Point(49, 37);
61 | this.ServerInput.Name = "ServerInput";
62 | this.ServerInput.Size = new System.Drawing.Size(162, 20);
63 | this.ServerInput.TabIndex = 0;
64 | //
65 | // PortInput
66 | //
67 | this.PortInput.Location = new System.Drawing.Point(49, 76);
68 | this.PortInput.Name = "PortInput";
69 | this.PortInput.Size = new System.Drawing.Size(162, 20);
70 | this.PortInput.TabIndex = 1;
71 | //
72 | // UsernameInput
73 | //
74 | this.UsernameInput.Location = new System.Drawing.Point(49, 114);
75 | this.UsernameInput.Name = "UsernameInput";
76 | this.UsernameInput.Size = new System.Drawing.Size(162, 20);
77 | this.UsernameInput.TabIndex = 2;
78 | //
79 | // ChannelsInput
80 | //
81 | this.ChannelsInput.Location = new System.Drawing.Point(49, 152);
82 | this.ChannelsInput.Name = "ChannelsInput";
83 | this.ChannelsInput.Size = new System.Drawing.Size(162, 20);
84 | this.ChannelsInput.TabIndex = 3;
85 | //
86 | // label1
87 | //
88 | this.label1.AutoSize = true;
89 | this.label1.Location = new System.Drawing.Point(46, 21);
90 | this.label1.Name = "label1";
91 | this.label1.Size = new System.Drawing.Size(38, 13);
92 | this.label1.TabIndex = 4;
93 | this.label1.Text = "Server";
94 | //
95 | // label2
96 | //
97 | this.label2.AutoSize = true;
98 | this.label2.Location = new System.Drawing.Point(49, 60);
99 | this.label2.Name = "label2";
100 | this.label2.Size = new System.Drawing.Size(26, 13);
101 | this.label2.TabIndex = 5;
102 | this.label2.Text = "Port";
103 | //
104 | // labelusername
105 | //
106 | this.labelusername.AutoSize = true;
107 | this.labelusername.Location = new System.Drawing.Point(49, 99);
108 | this.labelusername.Name = "labelusername";
109 | this.labelusername.Size = new System.Drawing.Size(55, 13);
110 | this.labelusername.TabIndex = 6;
111 | this.labelusername.Text = "Username";
112 | //
113 | // labelsomething
114 | //
115 | this.labelsomething.AutoSize = true;
116 | this.labelsomething.Location = new System.Drawing.Point(49, 137);
117 | this.labelsomething.Name = "labelsomething";
118 | this.labelsomething.Size = new System.Drawing.Size(156, 13);
119 | this.labelsomething.TabIndex = 7;
120 | this.labelsomething.Text = "Channel(s) (comma to seperate)";
121 | //
122 | // ConnectButton
123 | //
124 | this.ConnectButton.Location = new System.Drawing.Point(49, 179);
125 | this.ConnectButton.Name = "ConnectButton";
126 | this.ConnectButton.Size = new System.Drawing.Size(162, 23);
127 | this.ConnectButton.TabIndex = 8;
128 | this.ConnectButton.Text = "Connect";
129 | this.ConnectButton.UseVisualStyleBackColor = true;
130 | this.ConnectButton.Click += new System.EventHandler(this.ConnectButton_Click);
131 | //
132 | // DisconnectButton
133 | //
134 | this.DisconnectButton.Location = new System.Drawing.Point(49, 208);
135 | this.DisconnectButton.Name = "DisconnectButton";
136 | this.DisconnectButton.Size = new System.Drawing.Size(162, 23);
137 | this.DisconnectButton.TabIndex = 9;
138 | this.DisconnectButton.Text = "Disconnect";
139 | this.DisconnectButton.UseVisualStyleBackColor = true;
140 | this.DisconnectButton.Click += new System.EventHandler(this.DisconnectButton_Click);
141 | //
142 | // MessageInput
143 | //
144 | this.MessageInput.Location = new System.Drawing.Point(233, 311);
145 | this.MessageInput.Name = "MessageInput";
146 | this.MessageInput.Size = new System.Drawing.Size(500, 20);
147 | this.MessageInput.TabIndex = 11;
148 | this.MessageInput.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MessageInput_KeyDown);
149 | //
150 | // SendToAll
151 | //
152 | this.SendToAll.Location = new System.Drawing.Point(752, 309);
153 | this.SendToAll.Name = "SendToAll";
154 | this.SendToAll.Size = new System.Drawing.Size(83, 23);
155 | this.SendToAll.TabIndex = 12;
156 | this.SendToAll.Text = "Send To All";
157 | this.SendToAll.UseVisualStyleBackColor = true;
158 | this.SendToAll.Click += new System.EventHandler(this.SendToAll_Click);
159 | //
160 | // DownloadsList
161 | //
162 | this.DownloadsList.FormattingEnabled = true;
163 | this.DownloadsList.HorizontalScrollbar = true;
164 | this.DownloadsList.Location = new System.Drawing.Point(106, 359);
165 | this.DownloadsList.Name = "DownloadsList";
166 | this.DownloadsList.ScrollAlwaysVisible = true;
167 | this.DownloadsList.Size = new System.Drawing.Size(854, 121);
168 | this.DownloadsList.TabIndex = 13;
169 | this.DownloadsList.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.DownloadsList_MouseDoubleClick);
170 | //
171 | // ShowDebugButton
172 | //
173 | this.ShowDebugButton.Location = new System.Drawing.Point(49, 237);
174 | this.ShowDebugButton.Name = "ShowDebugButton";
175 | this.ShowDebugButton.Size = new System.Drawing.Size(162, 23);
176 | this.ShowDebugButton.TabIndex = 14;
177 | this.ShowDebugButton.Text = "Show Debug";
178 | this.ShowDebugButton.UseVisualStyleBackColor = true;
179 | this.ShowDebugButton.Click += new System.EventHandler(this.ShowDebugButton_Click);
180 | //
181 | // SetDownloadFolderButton
182 | //
183 | this.SetDownloadFolderButton.Location = new System.Drawing.Point(49, 266);
184 | this.SetDownloadFolderButton.Name = "SetDownloadFolderButton";
185 | this.SetDownloadFolderButton.Size = new System.Drawing.Size(162, 23);
186 | this.SetDownloadFolderButton.TabIndex = 15;
187 | this.SetDownloadFolderButton.Text = "Choose Download Folder";
188 | this.SetDownloadFolderButton.UseVisualStyleBackColor = true;
189 | this.SetDownloadFolderButton.Click += new System.EventHandler(this.SetDownloadFolderButton_Click);
190 | //
191 | // label3
192 | //
193 | this.label3.AutoSize = true;
194 | this.label3.Location = new System.Drawing.Point(241, 21);
195 | this.label3.Name = "label3";
196 | this.label3.Size = new System.Drawing.Size(32, 13);
197 | this.label3.TabIndex = 16;
198 | this.label3.Text = "Chat:";
199 | //
200 | // label4
201 | //
202 | this.label4.AutoSize = true;
203 | this.label4.Location = new System.Drawing.Point(46, 346);
204 | this.label4.Name = "label4";
205 | this.label4.Size = new System.Drawing.Size(63, 13);
206 | this.label4.TabIndex = 17;
207 | this.label4.Text = "Downloads:";
208 | //
209 | // label5
210 | //
211 | this.label5.AutoSize = true;
212 | this.label5.Location = new System.Drawing.Point(49, 486);
213 | this.label5.Name = "label5";
214 | this.label5.Size = new System.Drawing.Size(51, 13);
215 | this.label5.TabIndex = 18;
216 | this.label5.Text = "Progress:";
217 | //
218 | // DownloadProgressBar
219 | //
220 | this.DownloadProgressBar.Location = new System.Drawing.Point(106, 495);
221 | this.DownloadProgressBar.Name = "DownloadProgressBar";
222 | this.DownloadProgressBar.Size = new System.Drawing.Size(854, 23);
223 | this.DownloadProgressBar.TabIndex = 19;
224 | //
225 | // UpdateUserList
226 | //
227 | this.UpdateUserList.Location = new System.Drawing.Point(966, 495);
228 | this.UpdateUserList.Name = "UpdateUserList";
229 | this.UpdateUserList.Size = new System.Drawing.Size(229, 23);
230 | this.UpdateUserList.TabIndex = 21;
231 | this.UpdateUserList.Text = "Update User List";
232 | this.UpdateUserList.UseVisualStyleBackColor = true;
233 | this.UpdateUserList.Click += new System.EventHandler(this.UpdateUserList_Click);
234 | //
235 | // ircChatTabs
236 | //
237 | this.ircChatTabs.Location = new System.Drawing.Point(233, 37);
238 | this.ircChatTabs.Name = "ircChatTabs";
239 | this.ircChatTabs.SelectedIndex = 0;
240 | this.ircChatTabs.Size = new System.Drawing.Size(727, 252);
241 | this.ircChatTabs.TabIndex = 22;
242 | //
243 | // SendToChannel
244 | //
245 | this.SendToChannel.Location = new System.Drawing.Point(841, 309);
246 | this.SendToChannel.Name = "SendToChannel";
247 | this.SendToChannel.Size = new System.Drawing.Size(112, 23);
248 | this.SendToChannel.TabIndex = 23;
249 | this.SendToChannel.Text = "Send To Channel";
250 | this.SendToChannel.UseVisualStyleBackColor = true;
251 | this.SendToChannel.Click += new System.EventHandler(this.SendToChannel_Click);
252 | //
253 | // userListTabs
254 | //
255 | this.userListTabs.Location = new System.Drawing.Point(966, 37);
256 | this.userListTabs.Name = "userListTabs";
257 | this.userListTabs.SelectedIndex = 0;
258 | this.userListTabs.Size = new System.Drawing.Size(229, 452);
259 | this.userListTabs.TabIndex = 24;
260 | //
261 | // IrcClientForm
262 | //
263 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
264 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
265 | this.ClientSize = new System.Drawing.Size(1207, 530);
266 | this.Controls.Add(this.userListTabs);
267 | this.Controls.Add(this.SendToChannel);
268 | this.Controls.Add(this.ircChatTabs);
269 | this.Controls.Add(this.UpdateUserList);
270 | this.Controls.Add(this.DownloadProgressBar);
271 | this.Controls.Add(this.label5);
272 | this.Controls.Add(this.label4);
273 | this.Controls.Add(this.label3);
274 | this.Controls.Add(this.SetDownloadFolderButton);
275 | this.Controls.Add(this.ShowDebugButton);
276 | this.Controls.Add(this.DownloadsList);
277 | this.Controls.Add(this.SendToAll);
278 | this.Controls.Add(this.MessageInput);
279 | this.Controls.Add(this.DisconnectButton);
280 | this.Controls.Add(this.ConnectButton);
281 | this.Controls.Add(this.labelsomething);
282 | this.Controls.Add(this.labelusername);
283 | this.Controls.Add(this.label2);
284 | this.Controls.Add(this.label1);
285 | this.Controls.Add(this.ChannelsInput);
286 | this.Controls.Add(this.UsernameInput);
287 | this.Controls.Add(this.PortInput);
288 | this.Controls.Add(this.ServerInput);
289 | this.Name = "IrcClientForm";
290 | this.Text = "SimpleIRCLib Irc Client";
291 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
292 | this.ResumeLayout(false);
293 | this.PerformLayout();
294 |
295 | }
296 |
297 | #endregion
298 |
299 | private System.Windows.Forms.TextBox ServerInput;
300 | private System.Windows.Forms.TextBox PortInput;
301 | private System.Windows.Forms.TextBox UsernameInput;
302 | private System.Windows.Forms.TextBox ChannelsInput;
303 | private System.Windows.Forms.Label label1;
304 | private System.Windows.Forms.Label label2;
305 | private System.Windows.Forms.Label labelusername;
306 | private System.Windows.Forms.Label labelsomething;
307 | private System.Windows.Forms.Button ConnectButton;
308 | private System.ComponentModel.BackgroundWorker backgroundWorker1;
309 | private System.Windows.Forms.Button DisconnectButton;
310 | private System.Windows.Forms.TextBox MessageInput;
311 | private System.Windows.Forms.Button SendToAll;
312 | private System.Windows.Forms.ListBox DownloadsList;
313 | private System.Windows.Forms.Button ShowDebugButton;
314 | private System.Windows.Forms.Button SetDownloadFolderButton;
315 | private System.Windows.Forms.Label label3;
316 | private System.Windows.Forms.Label label4;
317 | private System.Windows.Forms.Label label5;
318 | private System.Windows.Forms.ProgressBar DownloadProgressBar;
319 | private System.Windows.Forms.FolderBrowserDialog OpenFolderDialog;
320 | private System.Windows.Forms.Button UpdateUserList;
321 | private System.Windows.Forms.TabControl ircChatTabs;
322 | private System.Windows.Forms.Button SendToChannel;
323 | private System.Windows.Forms.TabControl userListTabs;
324 | }
325 | }
326 |
327 |
--------------------------------------------------------------------------------
/FormExample/IrcClientForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 | using System.IO;
4 | using System.Diagnostics;
5 | //the library
6 | using SimpleIRCLib;
7 | using System.Collections.Generic;
8 |
9 | namespace FormExample
10 | {
11 | ///
12 | /// This class is meant as example on how to use SimpleIRCLib, this does not mean that this is the correct way to program!
13 | /// It's meant to showcase a few of the available methods within SimpleIRCLib, you should figure out on your own how to implement it to suit your needs!
14 | /// It lacks a few options, such as leaving a specific channel, which will be implemented in the future. If your knowledged, you could send a raw message
15 | /// to the server containing commands to PART from a channel and use the OnRawMessageReceived event to check the server response.
16 | ///
17 | public partial class IrcClientForm : Form
18 | {
19 | //initiate irc client
20 | private readonly SimpleIRC _irc;
21 |
22 | //initiate debugform
23 | private readonly DebugForm _debugForm;
24 |
25 | private string _defaultDownloadDirectory;
26 |
27 | ///
28 | /// Form Contstructor, initializes SimpleIRC Library and registers event handlers.
29 | ///
30 | public IrcClientForm()
31 | {
32 | _irc = new SimpleIRC();
33 | _irc.IrcClient.OnMessageReceived += OnMessagesReceived;
34 | _irc.IrcClient.OnUserListReceived += OnUserListReceived;
35 | _irc.DccClient.OnDccEvent += OnDccEvent;
36 | _debugForm = new DebugForm(_irc);
37 | _defaultDownloadDirectory = Directory.GetCurrentDirectory();
38 |
39 | InitializeComponent();
40 | }
41 |
42 | ///
43 | /// Gets the values from the input fields and starts the client
44 | ///
45 | ///
46 | ///
47 | public void ConnectButton_Click(object sender, EventArgs e)
48 | {
49 | if (ServerInput.Text != "" && PortInput.Text != "" && UsernameInput.Text != "" && ChannelsInput.Text != "" && _irc.IsClientRunning() == false)
50 | {
51 | int port = -1;
52 | if ((port = int.Parse(PortInput.Text)) != -1)
53 | {
54 | //parameters as follows: ip or address to irc server, username, password(not functional), channels, and method to execute when message is received (see line 103)
55 | _irc.SetupIrc(ServerInput.Text, UsernameInput.Text, ChannelsInput.Text, int.Parse(PortInput.Text));
56 |
57 | //Sets event handlers for all the possible events (!IMPORTANT: do this after intializing irc.SetupIRC !!!)
58 |
59 |
60 | _irc.StartClient();
61 | }
62 | } else
63 | {
64 | MessageBox.Show("You need to fill in all the information fields!");
65 | }
66 | }
67 |
68 | ///
69 | /// Disconnects the irc client, closes all open tabs.
70 | ///
71 | ///
72 | ///
73 | public void DisconnectButton_Click(object sender, EventArgs e)
74 | {
75 | if (_irc.StopClient())
76 | {
77 | ircChatTabs.TabPages.Clear();
78 | userListTabs.TabPages.Clear();
79 | }
80 | }
81 |
82 | ///
83 | /// Sends if enter is pressed.
84 | ///
85 | ///
86 | ///
87 | public void MessageInput_KeyDown(object sender, KeyEventArgs e)
88 | {
89 | if(e.KeyCode == Keys.Enter)
90 | {
91 | if (MessageInput.Text != "" && _irc.IsClientRunning())
92 | {
93 | _irc.SendMessageToAll(MessageInput.Text);
94 | }
95 | }
96 |
97 | }
98 |
99 | ///
100 | /// Event handler for receiving messages from the Irc Client.
101 | ///
102 | /// Values of the class that fired the event
103 | /// IrcReceivedEventArgs containing the message information
104 | public void OnMessagesReceived(object sender, IrcReceivedEventArgs args)
105 | {
106 | OnMessagesReceivedLocal(args.Channel, args.User, args.Message);
107 | }
108 |
109 | ///
110 | /// Method that gets invoked on the main thread, adds a message to the richtextbox within a the correct channel tab.
111 | ///
112 | /// channel messaged was received on
113 | /// user that send the message to the channel
114 | /// message that the user had send on the channel
115 | public void OnMessagesReceivedLocal(string channel, string user, string message)
116 | {
117 | if (this.ircChatTabs.InvokeRequired)
118 | {
119 | this.ircChatTabs.Invoke(new MethodInvoker(() => OnMessagesReceivedLocal(channel, user, message)));
120 | }
121 | else
122 | {
123 | //searches for the tab for the correct channel
124 | bool found = false;
125 | int index = 0;
126 | foreach (TabPage tab in ircChatTabs.TabPages)
127 | {
128 | if (channel.Contains(tab.Name))
129 | {
130 | found = true;
131 | break;
132 | }
133 |
134 | index++;
135 | }
136 |
137 | //if the tab has been found, add a message to the richtextbox within that tab.
138 | if (found)
139 | {
140 | if (ircChatTabs.TabPages[index].Controls.ContainsKey(channel))
141 | {
142 | RichTextBox selectedRtb = (RichTextBox)ircChatTabs.TabPages[index].Controls[channel];
143 | selectedRtb.AppendText(user + " : " + message + Environment.NewLine);
144 | selectedRtb.ScrollToCaret();
145 | }
146 | }
147 |
148 | }
149 | }
150 |
151 | ///
152 | /// Event that gets fired when a user list has been received.
153 | ///
154 | /// Values of the class that fired the event
155 | /// IrcUserListReceivedEventArgs contains the Dictionary where the key is the channel and the list contains the usernames
156 | public void OnUserListReceived(object sender, IrcUserListReceivedEventArgs args )
157 | {
158 | OnUserListReceivedLocal(args.UsersPerChannel);
159 | }
160 |
161 | ///
162 | /// Method to invoke on the main thread, checks if a tab for the chat exists with name of the channel, if not, it creates it, same goes for the tab with the user name list.
163 | ///
164 | /// Dictionary where the key is the channel and the list contains the usernames
165 | public void OnUserListReceivedLocal(Dictionary> userList)
166 | {
167 | if (this.InvokeRequired)
168 | {
169 | this.Invoke(new MethodInvoker(() => OnUserListReceivedLocal(userList)));
170 | }
171 | else
172 | {
173 | //iterate through each channel
174 | foreach (KeyValuePair> channelsAndUsers in userList)
175 | {
176 | //search for a tab with the same channel name within the chatTabs
177 | bool foundChatTab = false;
178 | int indexChatTab = 0;
179 | foreach (TabPage tab in ircChatTabs.TabPages)
180 | {
181 | if (channelsAndUsers.Key.Equals(tab.Name))
182 | {
183 | Debug.WriteLine("FOUND TAB: " + tab.Name);
184 | foundChatTab = true;
185 | break;
186 | }
187 |
188 | indexChatTab++;
189 | }
190 |
191 | if (!foundChatTab)
192 | {
193 | TabPage newTab = new TabPage(channelsAndUsers.Key);
194 | newTab.Name = channelsAndUsers.Key;
195 | RichTextBox rtb = new RichTextBox();
196 | rtb.Dock = DockStyle.Fill;
197 | rtb.BorderStyle = BorderStyle.None;
198 | rtb.Name = channelsAndUsers.Key;
199 | newTab.Controls.Add(rtb);
200 | ircChatTabs.TabPages.Add(newTab);
201 | }
202 |
203 | //search for a tab with the same channel name within the userListTabs
204 | bool foundUserListTab = false;
205 | int userListTabIndex = 0;
206 | foreach (TabPage tab in userListTabs.TabPages)
207 | {
208 | if (channelsAndUsers.Key.Equals(tab.Name))
209 | {
210 | foundUserListTab = true;
211 | break;
212 | }
213 |
214 | userListTabIndex++;
215 | }
216 |
217 | if (!foundUserListTab)
218 | {
219 | TabPage newTab = new TabPage(channelsAndUsers.Key);
220 | newTab.Name = channelsAndUsers.Key;
221 | RichTextBox rtb = new RichTextBox();
222 | rtb.Dock = DockStyle.Fill;
223 | rtb.BorderStyle = BorderStyle.None;
224 | rtb.Name = channelsAndUsers.Key;
225 | foreach (string user in channelsAndUsers.Value)
226 | {
227 | rtb.AppendText(user + Environment.NewLine);
228 | }
229 | rtb.ScrollToCaret();
230 | newTab.Controls.Add(rtb);
231 | userListTabs.TabPages.Add(newTab);
232 | }
233 | else
234 | {
235 |
236 | if (userListTabs.TabPages[userListTabIndex].Controls.ContainsKey(channelsAndUsers.Key))
237 | {
238 | RichTextBox selectedRtb = (RichTextBox)userListTabs.TabPages[userListTabIndex].Controls[channelsAndUsers.Key];
239 | foreach (string user in channelsAndUsers.Value)
240 | {
241 | selectedRtb.AppendText(user + Environment.NewLine);
242 | }
243 | selectedRtb.ScrollToCaret();
244 | }
245 | }
246 | }
247 | }
248 | }
249 |
250 | ///
251 | /// Event that fires when DCCClient starts downloading.
252 | ///
253 | /// Values of the class that fired the event
254 | /// DCCEventArgs contains all the information about the download update
255 | public void OnDccEvent(object sender, DCCEventArgs args)
256 | {
257 | string fileName = args.FileName;
258 | int downloadProgress = args.Progress;
259 | string downloadSpeed = args.KBytesPerSecond.ToString();
260 | string status = args.Status;
261 |
262 | string fullDownloadInformation = fileName + " | " + status + " | " + downloadSpeed + " kb/s | " + _defaultDownloadDirectory;
263 |
264 | UpdateDownloadList(fullDownloadInformation, fileName);
265 |
266 | UpdateProgressBar(downloadProgress);
267 |
268 | if (status.Contains("COMPLETED"))
269 | {
270 | UpdateProgressBar(100);
271 | }
272 |
273 | }
274 |
275 | ///
276 | /// Updates the DownloadList object on the main form while the download is going, invoke is necesary because
277 | /// method is being called from a different Thread!
278 | ///
279 | /// string that needs to be added/updated
280 | /// the filename which is used for searching the item in the download list for updating
281 | public void UpdateDownloadList(string toUpdate, string fileName)
282 | {
283 | if (this.DownloadsList.InvokeRequired)
284 | {
285 | this.DownloadsList.Invoke(new MethodInvoker(() => UpdateDownloadList(toUpdate, fileName)));
286 | }
287 | else
288 | {
289 | int indexOfDownloadItem = 0;
290 | for (int i = indexOfDownloadItem; i < DownloadsList.Items.Count; ++i)
291 | {
292 | string lbString = DownloadsList.Items[i].ToString();
293 | if (lbString.Contains(fileName))
294 | {
295 | indexOfDownloadItem = i;
296 | break;
297 | }
298 | }
299 |
300 | try
301 | {
302 | DownloadsList.Items.RemoveAt(indexOfDownloadItem);
303 | DownloadsList.Items.Insert(indexOfDownloadItem, toUpdate);
304 | DownloadsList.SelectedIndex = indexOfDownloadItem;
305 | }
306 | catch
307 | {
308 | DownloadsList.Items.Add(toUpdate);
309 | }
310 | }
311 | }
312 |
313 | ///
314 | /// Updates the progress bar
315 | ///
316 | /// defines the current progress
317 | public void UpdateProgressBar(int progress)
318 | {
319 | if (this.DownloadProgressBar.InvokeRequired)
320 | {
321 | this.DownloadProgressBar.Invoke(new MethodInvoker(() => UpdateProgressBar(progress)));
322 | } else
323 | {
324 | this.DownloadProgressBar.Value = progress;
325 | }
326 | }
327 |
328 | ///
329 | /// Opens the debug form
330 | ///
331 | ///
332 | ///
333 | public void ShowDebugButton_Click(object sender, EventArgs e)
334 | {
335 | try
336 | {
337 | _debugForm.Show();
338 | } catch
339 | {
340 |
341 | }
342 | }
343 |
344 | ///
345 | /// Opens the folder where the selected file is being downloaded to
346 | ///
347 | ///
348 | ///
349 | public void DownloadsList_MouseDoubleClick(object sender, MouseEventArgs e)
350 | {
351 | int currentlySelected = DownloadsList.SelectedIndex;
352 | try
353 | {
354 | string currentItem = DownloadsList.Items[currentlySelected].ToString();
355 |
356 | if (currentItem.Contains("|"))
357 | {
358 | string fileLocation = currentItem.Split('|')[currentItem.Split('|').Length - 1].Trim();
359 | Process.Start(fileLocation);
360 | }
361 | }
362 | catch
363 | {
364 |
365 | }
366 | }
367 |
368 | ///
369 | /// Set download directory to a custom directory
370 | ///
371 | ///
372 | ///
373 | public void SetDownloadFolderButton_Click(object sender, EventArgs e)
374 | {
375 | DialogResult result = OpenFolderDialog.ShowDialog();
376 | if (result == DialogResult.OK)
377 | {
378 | string newDownloadDirectory = OpenFolderDialog.SelectedPath;
379 | _defaultDownloadDirectory = newDownloadDirectory;
380 | _irc.SetCustomDownloadDir(newDownloadDirectory);
381 | }
382 | }
383 |
384 | ///
385 | /// Stops the irc client on form close, otherwise it would keep running in the background!!!
386 | ///
387 | ///
388 | ///
389 | public void Form1_FormClosing(object sender, FormClosingEventArgs e)
390 | {
391 | if (_irc.IsClientRunning())
392 | {
393 | _irc.StopClient();
394 | }
395 | }
396 |
397 | ///
398 | /// Gets the users in the current channel.
399 | ///
400 | ///
401 | ///
402 | public void UpdateUserList_Click(object sender, EventArgs e)
403 | {
404 | RichTextBox selectedRtb = (RichTextBox)userListTabs.SelectedTab.Controls[0];
405 | selectedRtb.Clear();
406 | if (_irc.IsClientRunning())
407 | {
408 | _irc.GetUsersInDifferentChannel(userListTabs.SelectedTab.Name);
409 | }
410 | }
411 |
412 | ///
413 | /// Sends a message to a specific channel.
414 | ///
415 | ///
416 | ///
417 | public void SendToChannel_Click(object sender, EventArgs e)
418 | {
419 | string channel = ircChatTabs.SelectedTab.Name;
420 | _irc.SendMessageToChannel(MessageInput.Text, channel);
421 | }
422 |
423 | ///
424 | /// Sends a message to all channels.
425 | ///
426 | ///
427 | ///
428 | public void SendToAll_Click(object sender, EventArgs e)
429 | {
430 | _irc.SendMessageToAll(MessageInput.Text);
431 | }
432 |
433 | }
434 | }
435 |
--------------------------------------------------------------------------------
/SimpleIRCLib/DCCClient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.RegularExpressions;
3 | using System.Net;
4 | using System.Net.Sockets;
5 | using System.Threading;
6 | using System.IO;
7 | using System.Text;
8 | using System.Collections.Generic;
9 |
10 | namespace SimpleIRCLib
11 | {
12 | ///
13 | /// Class for downloading files using the DCC protocol on a sperarate thread from the main IRC Client thread.
14 | ///
15 | public class DCCClient
16 | {
17 |
18 | ///
19 | /// For firing update event using DCCEventArgs from DCCEventArgs.cs
20 | ///
21 | public event EventHandler OnDccEvent;
22 | ///
23 | /// For firing debug event using DCCDebugMessageArgs from DCCEventArgs.cs
24 | ///
25 | public event EventHandler OnDccDebugMessage;
26 |
27 | ///
28 | /// Raw DCC String used for getting the file location (server) and some basic file information
29 | ///
30 | public string NewDccString { get; set; }
31 | ///
32 | /// File name of the file being downloaded
33 | ///
34 | public string NewFileName { get; set; }
35 | ///
36 | /// Pack ID of file on bot where file resides
37 | ///
38 | public int NewPortNum { get; set; }
39 | ///
40 | /// FileSize of the file being downloaded
41 | ///
42 | public Int64 NewFileSize { get; set; }
43 | ///
44 | /// Port of server of file location
45 | ///
46 | public string NewIP{ get; set; }
47 | ///
48 | /// Progress from 0-100 (%)
49 | ///
50 | public int Progress { get; set; }
51 | ///
52 | /// Download status, such as: WAITING,DOWNLOADING,FAILED:[ERROR],ABORTED
53 | ///
54 | public string Status { get; set; }
55 | ///
56 | /// Download speed in: KB/s
57 | ///
58 | public Int64 BytesPerSecond { get; set; }
59 | ///
60 | /// Download speed in: MB/s
61 | ///
62 | public int KBytesPerSecond { get; set; }
63 | ///
64 | /// Download status, such as: WAITING,DOWNLOADING,FAILED:[ERROR],ABORTED
65 | ///
66 | public int MBytesPerSecond { get; set; }
67 | ///
68 | /// Bot name where file resides
69 | ///
70 | public string BotName { get; set; }
71 | ///
72 | /// Pack ID of file on bot where file resides
73 | ///
74 | public string PackNum { get; set; }
75 | ///
76 | /// Check for status of DCCClient
77 | ///
78 | public bool IsDownloading { get; set; }
79 | ///
80 | /// Path to the file that is being downloaded, or has been downloaded
81 | ///
82 | public string CurrentFilePath { get; set; }
83 |
84 | ///
85 | /// To provide the latest data downloaded to outside the library
86 | ///
87 | public List Buffer { get; set; }
88 |
89 | ///
90 | /// Local bool to tell the while loop within the download thread to stop.
91 | ///
92 | private bool _shouldAbort = false;
93 |
94 |
95 |
96 | ///
97 | /// Client that is currently running, used for sending abort messages when a download fails, or a dcc string fails to parse.
98 | ///
99 | private IrcClient _ircClient;
100 |
101 | ///
102 | /// Current download directory that will be used when starting a download
103 | ///
104 | private string _curDownloadDir;
105 |
106 | ///
107 | /// Thread where download logic is running
108 | ///
109 | private Thread _downloader;
110 |
111 | ///
112 | /// Initial constructor.
113 | ///
114 | public DCCClient()
115 | {
116 | IsDownloading = false;
117 | }
118 |
119 | ///
120 | /// Starts a downloader by parsing the received message from the irc server on information
121 | ///
122 | /// message from irc server
123 | /// download directory
124 | /// bot where the file came from
125 | /// pack on bot where the file came from
126 | /// irc client used the moment it received the dcc message, used for sending abort messages when download fails unexpectedly
127 | public void StartDownloader(string dccString, string downloaddir, string bot, string pack, IrcClient client)
128 | {
129 | if ((dccString ?? downloaddir ?? bot ?? pack) != null && dccString.Contains("SEND") && !IsDownloading)
130 | {
131 | NewDccString = dccString;
132 | _curDownloadDir = downloaddir;
133 | BotName = bot;
134 | PackNum = pack;
135 | _ircClient = client;
136 |
137 | //parsing the data for downloader thread
138 |
139 | UpdateStatus("PARSING");
140 | bool isParsed = ParseData(dccString);
141 |
142 | //try to set the necesary information for the downloader
143 | if (isParsed)
144 | {
145 | _shouldAbort = false;
146 | //start the downloader thread
147 | _downloader = new Thread(new ThreadStart(this.Downloader));
148 | _downloader.IsBackground = true;
149 | _downloader.Start();
150 | }
151 | else
152 | {
153 | OnDccDebugMessage?.Invoke(this,
154 | new DCCDebugMessageArgs(
155 | "Can't parse dcc string and start downloader, failed to parse data, removing from que\n", "DCC STARTER"));
156 | _ircClient.SendMessageToAll("/msg " + BotName + " xdcc remove " + PackNum);
157 | _ircClient.SendMessageToAll("/msg " + BotName + " xdcc cancel");
158 | }
159 | }
160 | else
161 | {
162 | if (IsDownloading)
163 | {
164 | OnDccDebugMessage?.Invoke(this,
165 | new DCCDebugMessageArgs("You are already downloading! Ignore SEND request\n", "DCC STARTER"));
166 | }
167 | else
168 | {
169 | OnDccDebugMessage?.Invoke(this,
170 | new DCCDebugMessageArgs("DCC String does not contain SEND and/or invalid values for parsing! Ignore SEND request\n", "DCC STARTER"));
171 | }
172 | }
173 | }
174 |
175 | ///
176 | /// Parses the received DCC string
177 | ///
178 | /// dcc string
179 | /// returns true if parsing was succesfull, false if failed
180 | private bool ParseData(string dccString)
181 | {
182 | /*
183 | * :_bot PRIVMSG nickname :DCC SEND \"filename\" ip_networkbyteorder port filesize
184 | *AnimeDispenser!~desktop@Rizon-6AA4F43F.ip-37-187-118.eu PRIVMSG WeebIRCDev :DCC SEND "[LNS] Death Parade - 02 [BD 720p] [7287AE5C].mkv" 633042523 59538 258271780
185 | *HelloKitty!~nyaa@ny.aa.ny.aa PRIVMSG WeebIRCDev :DCC SEND [Coalgirls]_Spirited_Away_(1280x692_Blu-ray_FLAC)_[5805EE6B].mkv 3281692293 35567 10393049211
186 | :[EWG]-bOnez!EWG@CRiTEN-BB8A59E9.ip-158-69-126.net PRIVMSG LittleWeeb_jtokck :DCC SEND The.Good.Doctor.S01E13.Seven.Reasons.1080p.AMZN.WEB-DL.DD+5.1.H.264-QOQ.mkv 2655354388 55000 1821620363
187 | *Ginpa2:DCC SEND "[HorribleSubs] Dies Irae - 05 [480p].mkv" 84036312 35016 153772128
188 | */
189 |
190 | dccString = RemoveSpecialCharacters(dccString).Substring(1);
191 | OnDccDebugMessage?.Invoke(this,
192 | new DCCDebugMessageArgs("DCCClient: DCC STRING: " + dccString, "DCC PARSER"));
193 |
194 |
195 | if (!dccString.Contains(" :DCC"))
196 | {
197 | BotName = dccString.Split(':')[0];
198 | if (dccString.Contains("\""))
199 | {
200 | NewFileName = dccString.Split('"')[1];
201 |
202 | OnDccDebugMessage?.Invoke(this,
203 | new DCCDebugMessageArgs("DCCClient1: FILENAME PARSED: " + NewFileName, "DCC PARSER"));
204 | string[] thaimportantnumbers = dccString.Split('"')[2].Trim().Split(' ');
205 | if (thaimportantnumbers[0].Contains(":"))
206 | {
207 | NewIP= thaimportantnumbers[0];
208 | }
209 | else
210 | {
211 | try
212 | {
213 |
214 | OnDccDebugMessage?.Invoke(this,
215 | new DCCDebugMessageArgs("DCCClient1: PARSING FOLLOWING IPBYTES: " + thaimportantnumbers[0], "DCC PARSER"));
216 | string ipAddress = UInt64ToIPAddress(Int64.Parse(thaimportantnumbers[0]));
217 | NewIP= ipAddress;
218 | }
219 | catch
220 | {
221 | return false;
222 | }
223 | }
224 |
225 | OnDccDebugMessage?.Invoke(this,
226 | new DCCDebugMessageArgs("DCCClient1: IP PARSED: " + NewIP, "DCC PARSER"));
227 | NewPortNum = int.Parse(thaimportantnumbers[1]);
228 | NewFileSize = Int64.Parse(thaimportantnumbers[2]);
229 |
230 | return true;
231 | }
232 | else
233 | {
234 | NewFileName = dccString.Split(' ')[2];
235 |
236 |
237 | OnDccDebugMessage?.Invoke(this,
238 | new DCCDebugMessageArgs("DCCClient2: FILENAME PARSED: " + NewFileName, "DCC PARSER"));
239 |
240 | if (dccString.Split(' ')[3].Contains(":"))
241 | {
242 | NewIP= dccString.Split(' ')[3];
243 | }
244 | else
245 | {
246 | try
247 | {
248 |
249 |
250 | OnDccDebugMessage?.Invoke(this,
251 | new DCCDebugMessageArgs("DCCClient2: PARSING FOLLOWING IPBYTES DIRECTLY: " + dccString.Split(' ')[3], "DCC PARSER"));
252 | string ipAddress = UInt64ToIPAddress(Int64.Parse(dccString.Split(' ')[3]));
253 | NewIP= ipAddress;
254 | }
255 | catch
256 | {
257 |
258 | return false;
259 | }
260 | }
261 | OnDccDebugMessage?.Invoke(this,
262 | new DCCDebugMessageArgs("DCCClient2: IP PARSED: " + NewIP, "DCC PARSER"));
263 | NewPortNum = int.Parse(dccString.Split(' ')[4]);
264 | NewFileSize = Int64.Parse(dccString.Split(' ')[5]);
265 | return true;
266 | }
267 | } else
268 | {
269 | BotName = dccString.Split('!')[0];
270 | if (dccString.Contains("\""))
271 | {
272 | NewFileName = dccString.Split('"')[1];
273 |
274 | OnDccDebugMessage?.Invoke(this,
275 | new DCCDebugMessageArgs("DCCClient3: FILENAME PARSED: " + NewFileName, "DCC PARSER"));
276 | string[] thaimportantnumbers = dccString.Split('"')[2].Trim().Split(' ');
277 |
278 | if (thaimportantnumbers[0].Contains(":"))
279 | {
280 | NewIP= thaimportantnumbers[0];
281 | }
282 | else
283 | {
284 | try
285 | {
286 |
287 | OnDccDebugMessage?.Invoke(this,
288 | new DCCDebugMessageArgs("DCCClient3: PARSING FOLLOWING IPBYTES DIRECTLY: " + thaimportantnumbers[0], "DCC PARSER"));
289 | string ipAddress = UInt64ToIPAddress(Int64.Parse(thaimportantnumbers[0]));
290 | NewIP= ipAddress;
291 | }
292 | catch
293 | {
294 | return false;
295 | }
296 | }
297 |
298 |
299 | OnDccDebugMessage?.Invoke(this,
300 | new DCCDebugMessageArgs("DCCClient3: IP PARSED: " + NewIP, "DCC PARSER"));
301 | NewPortNum = int.Parse(thaimportantnumbers[1]);
302 | NewFileSize = Int64.Parse(thaimportantnumbers[2]);
303 | return true;
304 | } else
305 | {
306 | NewFileName = dccString.Split(' ')[5];
307 |
308 | OnDccDebugMessage?.Invoke(this,
309 | new DCCDebugMessageArgs("DCCClient4: FILENAME PARSED: " + NewFileName, "DCC PARSER"));
310 |
311 | if (dccString.Split(' ')[6].Contains(":"))
312 | {
313 | NewIP= dccString.Split(' ')[6];
314 | } else
315 | {
316 | try
317 | {
318 |
319 | OnDccDebugMessage?.Invoke(this,
320 | new DCCDebugMessageArgs("DCCClient4: PARSING FOLLOWING IPBYTES DIRECTLY: " + dccString.Split(' ')[6], "DCC PARSER"));
321 | string ipAddress = UInt64ToIPAddress(Int64.Parse(dccString.Split(' ')[6]));
322 | NewIP= ipAddress;
323 | }
324 | catch
325 | {
326 | return false;
327 | }
328 |
329 | }
330 |
331 | OnDccDebugMessage?.Invoke(this,
332 | new DCCDebugMessageArgs("DCCClient4: IP PARSED: " + NewIP, "DCC PARSER"));
333 | NewPortNum = int.Parse(dccString.Split(' ')[7]);
334 | NewFileSize = Int64.Parse(dccString.Split(' ')[8]);
335 | return true;
336 |
337 | }
338 |
339 |
340 | }
341 |
342 | }
343 |
344 | ///
345 | /// Method ran within downloader thread, starts a connection to the file server, and receives the file accordingly, sends updates using event handler during the download.
346 | ///
347 | public void Downloader()
348 | {
349 |
350 | UpdateStatus("WAITING");
351 |
352 | Buffer = new List();
353 |
354 | //combining download directory path with filename
355 |
356 | if (_curDownloadDir != null)
357 | {
358 | if (_curDownloadDir != string.Empty)
359 | {
360 | if (_curDownloadDir.Length > 0)
361 | {
362 | if (!Directory.Exists(_curDownloadDir))
363 | {
364 | Directory.CreateDirectory(_curDownloadDir);
365 | }
366 | }
367 | else
368 | {
369 | _curDownloadDir = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "Downloads");
370 | if (!Directory.Exists(_curDownloadDir))
371 | {
372 | Directory.CreateDirectory(_curDownloadDir);
373 | }
374 | }
375 | }
376 | else
377 | {
378 | _curDownloadDir = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "Downloads");
379 | if (!Directory.Exists(_curDownloadDir))
380 | {
381 | Directory.CreateDirectory(_curDownloadDir);
382 | }
383 | }
384 | }
385 | else
386 | {
387 | _curDownloadDir = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "Downloads");
388 | if (!Directory.Exists(_curDownloadDir))
389 | {
390 | Directory.CreateDirectory(_curDownloadDir);
391 | }
392 | }
393 |
394 | string dlDirAndFileName = Path.Combine(_curDownloadDir, NewFileName);
395 | CurrentFilePath = dlDirAndFileName;
396 | try
397 | {
398 | if (!File.Exists(dlDirAndFileName))
399 | {
400 | OnDccDebugMessage?.Invoke(this,
401 | new DCCDebugMessageArgs("File does not exist yet, start connection with: " + NewIP + ":" + NewPortNum + Environment.NewLine, "DCC DOWNLOADER"));
402 | Thread.Sleep(500);
403 | //start connection with tcp server
404 |
405 | IPAddress ip = IPAddress.Parse(NewIP);
406 |
407 | using (TcpClient dltcp = new TcpClient(ip.AddressFamily))
408 | {
409 |
410 | dltcp.Connect(ip, NewPortNum);
411 | using (NetworkStream dlstream = dltcp.GetStream())
412 | {
413 | //succesfully connected to tcp server, status is downloading
414 | UpdateStatus("DOWNLOADING");
415 |
416 | //values to keep track of progress
417 | Int64 bytesReceived = 0;
418 | Int64 oldBytesReceived = 0;
419 | Int64 oneprocent = NewFileSize / 100;
420 | DateTime start = DateTime.Now;
421 | bool timedOut = false;
422 |
423 | //values to keep track of download position
424 | int count;
425 |
426 | //to me this buffer size seemed to be the most efficient.
427 | byte[] buffer;
428 | if (NewFileSize > 1048576)
429 | {
430 | OnDccDebugMessage?.Invoke(this,
431 | new DCCDebugMessageArgs("Big file, big buffer (1 mb) \n ", "DCC DOWNLOADER"));
432 | buffer = new byte[16384];
433 | } else if(NewFileSize < 1048576 && NewFileSize > 2048)
434 | {
435 | OnDccDebugMessage?.Invoke(this,
436 | new DCCDebugMessageArgs("Smaller file (< 1 mb), smaller buffer (2 kb) \n ", "DCC DOWNLOADER"));
437 | buffer = new byte[2048];
438 | } else if (NewFileSize < 2048 && NewFileSize > 128)
439 | {
440 | OnDccDebugMessage?.Invoke(this,
441 | new DCCDebugMessageArgs("Small file (< 2kb mb), small buffer (128 b) \n ", "DCC DOWNLOADER"));
442 | buffer = new byte[128];
443 | } else
444 | {
445 | OnDccDebugMessage?.Invoke(this,
446 | new DCCDebugMessageArgs("Tiny file (< 128 b), tiny buffer (2 b) \n ", "DCC DOWNLOADER"));
447 | buffer = new byte[2];
448 | }
449 |
450 |
451 | //create file to write to
452 | using (FileStream writeStream = new FileStream(dlDirAndFileName, FileMode.Append, FileAccess.Write, FileShare.Read))
453 | {
454 | writeStream.SetLength(NewFileSize);
455 | IsDownloading = true;
456 | //download while connected and filesize is not reached
457 | while (dltcp.Connected && bytesReceived < NewFileSize && !_shouldAbort)
458 | {
459 | if (_shouldAbort)
460 | {
461 | dltcp.Close();
462 | dlstream.Dispose();
463 | writeStream.Close();
464 | }
465 | //keep track of progress
466 | DateTime end = DateTime.Now;
467 | if (end.Second != start.Second)
468 | {
469 |
470 | BytesPerSecond = bytesReceived - oldBytesReceived;
471 | KBytesPerSecond = (int)(BytesPerSecond / 1024);
472 | MBytesPerSecond = (KBytesPerSecond / 1024);
473 | oldBytesReceived = bytesReceived;
474 | start = DateTime.Now;
475 | UpdateStatus("DOWNLOADING");
476 | Buffer.Clear();
477 | }
478 |
479 | //count bytes received
480 | count = dlstream.Read(buffer, 0, buffer.Length);
481 |
482 | //write to buffer
483 | Buffer.AddRange(buffer);
484 |
485 | //write to file
486 | writeStream.Write(buffer, 0, count);
487 |
488 | //count bytes received
489 | bytesReceived += count;
490 |
491 | Progress = (int)(bytesReceived / oneprocent);
492 | }
493 |
494 | //close all connections and streams (just to be save)
495 | dltcp.Close();
496 | dlstream.Dispose();
497 | writeStream.Close();
498 |
499 | IsDownloading = false;
500 |
501 | if (_shouldAbort)
502 | {
503 | try
504 | {
505 | OnDccDebugMessage?.Invoke(this,
506 | new DCCDebugMessageArgs("Downloader Stopped", "DCC DOWNLOADER"));
507 | OnDccDebugMessage?.Invoke(this,
508 | new DCCDebugMessageArgs("File " + CurrentFilePath + " will be deleted due to aborting", "DCC DOWNLOADER"));
509 | File.Delete(CurrentFilePath);
510 |
511 | }
512 | catch (Exception e)
513 | {
514 | OnDccDebugMessage?.Invoke(this,
515 | new DCCDebugMessageArgs("File " + CurrentFilePath + " probably doesn't exist :X", "DCC DOWNLOADER"));
516 | OnDccDebugMessage?.Invoke(this,
517 | new DCCDebugMessageArgs(e.ToString(), "DCC DOWNLOADER"));
518 | }
519 |
520 | UpdateStatus("ABORTED");
521 | } else
522 | {
523 |
524 | //consider 95% downloaded as done, files are sequentually downloaded, sometimes download stops early, but the file still is usable
525 | if (Progress < 95 && !_shouldAbort)
526 | {
527 | UpdateStatus("FAILED");
528 | OnDccDebugMessage?.Invoke(this,
529 | new DCCDebugMessageArgs("Download stopped at < 95 % finished, deleting file: " + NewFileName + " \n", "DCC DOWNLOADER"));
530 | OnDccDebugMessage?.Invoke(this,
531 | new DCCDebugMessageArgs("Download stopped at : " + bytesReceived + " bytes, a total of " + Progress + "%", "DCC DOWNLOADER"));
532 | File.Delete(dlDirAndFileName);
533 | timedOut = false;
534 |
535 |
536 | }
537 | else if (timedOut && Progress < 95 && !_shouldAbort)
538 | {
539 | UpdateStatus("FAILED: TIMED OUT");
540 | OnDccDebugMessage?.Invoke(this,
541 | new DCCDebugMessageArgs("Download timed out at < 95 % finished, deleting file: " + NewFileName + " \n", "DCC DOWNLOADER"));
542 | OnDccDebugMessage?.Invoke(this,
543 | new DCCDebugMessageArgs("Download stopped at : " + bytesReceived + " bytes, a total of " + Progress + "%", "DCC DOWNLOADER"));
544 | File.Delete(dlDirAndFileName);
545 | timedOut = false;
546 | }
547 | else if (!_shouldAbort)
548 | {
549 | //make sure that in the event something happens and the downloader calls delete after finishing, the file will remain where it is.
550 | dlDirAndFileName = "";
551 | UpdateStatus("COMPLETED");
552 | }
553 |
554 | }
555 | _shouldAbort = false;
556 |
557 | }
558 | }
559 | }
560 | }
561 | else
562 | {
563 | OnDccDebugMessage?.Invoke(this,
564 | new DCCDebugMessageArgs("File already exists, removing from xdcc que!\n", "DCC DOWNLOADER"));
565 | _ircClient.SendMessageToAll("/msg " + BotName + " xdcc remove " + PackNum);
566 | _ircClient.SendMessageToAll("/msg " + BotName + " xdcc cancel");
567 | UpdateStatus("FAILED: ALREADY EXISTS");
568 | }
569 | OnDccDebugMessage?.Invoke(this,
570 | new DCCDebugMessageArgs("File has been downloaded! \n File Location:" + CurrentFilePath , "DCC DOWNLOADER"));
571 |
572 | }
573 | catch (SocketException e)
574 | {
575 | OnDccDebugMessage?.Invoke(this,
576 | new DCCDebugMessageArgs("Something went wrong while downloading the file! Removing from xdcc que to be sure! Error:\n" + e.ToString(), "DCC DOWNLOADER"));
577 | _ircClient.SendMessageToAll("/msg " + BotName + " xdcc remove " + PackNum);
578 | _ircClient.SendMessageToAll("/msg " + BotName + " xdcc cancel");
579 | UpdateStatus("FAILED: CONNECTING");
580 | }
581 | catch (Exception ex)
582 | {
583 | OnDccDebugMessage?.Invoke(this,
584 | new DCCDebugMessageArgs("Something went wrong while downloading the file! Removing from xdcc que to be sure! Error:\n" + ex.ToString(), "DCC DOWNLOADER"));
585 | _ircClient.SendMessageToAll("/msg " + BotName + " xdcc remove " + PackNum);
586 | _ircClient.SendMessageToAll("/msg " + BotName + " xdcc cancel");
587 | UpdateStatus("FAILED: UNKNOWN");
588 | }
589 | IsDownloading = false;
590 | }
591 |
592 | ///
593 | /// Fires the event with the update about the download currently running
594 | ///
595 | /// the current status of the download
596 | private void UpdateStatus(string statusin)
597 | {
598 | Status = statusin;
599 | OnDccEvent?.Invoke(this, new DCCEventArgs(this));
600 | }
601 |
602 | ///
603 | /// Stops a download if one is running, checks if the donwnloader thread actually stops.
604 | ///
605 | /// true if stopped succesfully
606 | public bool AbortDownloader(int timeOut)
607 | {
608 | if (CheckIfDownloading())
609 | {
610 | OnDccDebugMessage?.Invoke(this,
611 | new DCCDebugMessageArgs("File " + CurrentFilePath + " will be deleted after aborting.", "DCC DOWNLOADER"));
612 |
613 | _shouldAbort = true;
614 |
615 | int timeout = 0;
616 | while (CheckIfDownloading())
617 | {
618 | if (timeout > timeOut)
619 | {
620 | return false;
621 | }
622 | timeout++;
623 | Thread.Sleep(1);
624 | }
625 |
626 | return true;
627 | }
628 | else
629 | {
630 | return false;
631 | }
632 | }
633 |
634 | ///
635 | /// Checks if download is still running.
636 | ///
637 | /// true if still downloading
638 | public bool CheckIfDownloading()
639 | {
640 | return IsDownloading;
641 | }
642 |
643 | ///
644 | /// Removes special characters from a string (used for filenames)
645 | ///
646 | /// string to parse
647 | /// string wihtout special chars
648 | private string RemoveSpecialCharacters(string str)
649 | {
650 | StringBuilder sb = new StringBuilder();
651 | foreach (char c in str)
652 | {
653 | if (c > 31 && c < 219)
654 | {
655 | sb.Append(c);
656 | }
657 | }
658 | return sb.ToString();
659 | }
660 |
661 | ///
662 | /// Reverses IP from little endian to big endian or vice versa depending on what succeeds.
663 | ///
664 | /// ip string
665 | /// reversed ip string
666 | private string ReverseIp(string ip)
667 | {
668 | string[] parts = ip.Trim().Split('.');
669 | if(parts.Length >= 3)
670 | {
671 | OnDccDebugMessage?.Invoke(this,
672 | new DCCDebugMessageArgs("DCCClient: converting ip: " + ip, "DCC IP PARSER"));
673 | string NewIP= parts[3] + "." + parts[2] + "." + parts[1] + "." + parts[0];
674 | OnDccDebugMessage?.Invoke(this,
675 | new DCCDebugMessageArgs("DCCClient: to: " + NewIP, "DCC IP PARSER"));
676 |
677 | return NewIP;
678 | } else
679 | {
680 | OnDccDebugMessage?.Invoke(this,
681 | new DCCDebugMessageArgs("DCCClient: converting ip: " + ip, "DCC IP PARSER"));
682 | OnDccDebugMessage?.Invoke(this,
683 | new DCCDebugMessageArgs("DCCClient: amount of parts: " + parts.Length, "DCC IP PARSER"));
684 | return "0.0.0.0";
685 | }
686 | }
687 |
688 | ///
689 | /// Converts a long/int64 to a ip string.
690 | ///
691 | /// int64 numbers representing IP address
692 | /// string with ip
693 | private string UInt64ToIPAddress(Int64 address)
694 | {
695 | string ip = string.Empty;
696 | for (int i = 0; i < 4; i++)
697 | {
698 | int num = (int)(address / Math.Pow(256, (3 - i)));
699 | address = address - (long)(num * Math.Pow(256, (3 - i)));
700 | if (i == 0)
701 | {
702 | ip = num.ToString();
703 | }
704 | else
705 | {
706 | ip = ip + "." + num.ToString();
707 | }
708 | }
709 | return ip;
710 | }
711 | }
712 | }
713 |
--------------------------------------------------------------------------------
/SimpleIRCLib/IrcClient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using System.Net.Sockets;
4 | using System.IO;
5 | using System.Threading;
6 | using System.Text.RegularExpressions;
7 | using System.Collections.Generic;
8 | using System.Diagnostics;
9 | using System.Net.Security;
10 |
11 | namespace SimpleIRCLib
12 | {
13 | ///
14 | /// For running IRC Client logic, here is where all the magic happens
15 | ///
16 | public class IrcClient
17 | {
18 |
19 | ///
20 | /// Event Handler for firing when a (parsed) message is received on a channel from other users, event uses IrcReceivedEventArgs from IrcEventArgs.cs
21 | ///
22 | public event EventHandler OnMessageReceived;
23 |
24 | ///
25 | /// Event Handler for firing when a raw message is received from the irc server, event uses IrcRawReceivedEventArgs from IrcEventArgs.cs
26 | ///
27 | public event EventHandler OnRawMessageReceived;
28 |
29 | ///
30 | /// Event Handler for firing when a list with users per channel is received, event uses IrcUserListReceivedEventArgs from IrcEventArgs.cs
31 | ///
32 | public event EventHandler OnUserListReceived;
33 |
34 | ///
35 | /// Event Handler for firing when this client wants to send a debug message, event uses IrcDebugMessageEventArgs from IrcEventArgs.cs
36 | ///
37 | public event EventHandler OnDebugMessage;
38 |
39 | ///
40 | /// Port of irc server to connect to
41 | ///
42 | private int _NewPort;
43 | ///
44 | /// Username to register on irc server
45 | ///
46 | private string _NewUsername;
47 | ///
48 | /// Password to connect to a secured irc server
49 | ///
50 | private string _newPassword;
51 | ///
52 | /// Ip address of irc server
53 | ///
54 | private string _newIp;
55 | ///
56 | /// List with channels seperated with ',' to join when connecting to IRC server
57 | ///
58 | private string _NewChannelss;
59 | ///
60 | /// timeout before throwing timeout errors (using OnDebugMessage)
61 | ///
62 | private int _timeOut;
63 | ///
64 | /// download directory used for DCCClient.cs
65 | ///
66 | private string _downloadDirectory;
67 | ///
68 | /// for enabling tls/ssl secured connection to the irc server
69 | ///
70 | private bool _enableSSL;
71 | ///
72 | /// for checking if a connection is succesfully established
73 | ///
74 | private bool _isConnectionEstablised;
75 | ///
76 | /// for checking if client has started listening to the server
77 | ///
78 | private bool _IsClientRunning;
79 | ///
80 | /// packnumber used to initialize dccclient downloader
81 | ///
82 | private string _packNumber;
83 | ///
84 | /// bot used to initialzie dccclient downloader
85 | ///
86 | private string _bot;
87 | ///
88 | /// DCCClient to be used for downloading
89 | ///
90 | private DCCClient _dccClient;
91 | ///
92 | /// TcpClient used for connecting to the irc server
93 | ///
94 | private TcpClient _tcpClient;
95 | ///
96 | /// IRC commands
97 | ///
98 | private IrcCommands _ircCommands;
99 | ///
100 | /// unsecure network stream for listening and reading to the irc server
101 | ///
102 | private NetworkStream _networkStream;
103 | ///
104 | /// secure network stream for listening and reading to the irc server
105 | ///
106 | private SslStream _networkSStream;
107 | ///
108 | /// used for writing to the irc server
109 | ///
110 | private StreamWriter _streamWriter;
111 | ///
112 | /// used for reading from the irc server
113 | ///
114 | private StreamReader _streamReader;
115 | ///
116 | /// receiver task
117 | ///
118 | private Task _receiverTask = null;
119 | ///
120 | /// used for stopping the receiver task
121 | ///
122 | private bool _stopTask = false;
123 |
124 | ///
125 | /// Default constructor, needed so that the client can register events before starting the connection.
126 | ///
127 | public IrcClient()
128 | {
129 | _isConnectionEstablised = false;
130 | _IsClientRunning = false;
131 | }
132 |
133 | ///
134 | /// Sets up the information needed for the client to start a connection to the irc server. Sends a warning to the debug message event if ports are out of the standard specified ports for IRC.
135 | ///
136 | /// Server address, possibly works with dns addresses (irc.xxx.x), but ip addresses works just fine (of type string)
137 | /// Username the client wants to use, of type string
138 | /// Channel(s) the client wants to connect to, possible to connect to multiple channels at once by seperating each channel with a ',' (Example: #chan1,#chan2), of type string
139 | /// DCC Client, for downloading using the DCC protocol
140 | /// Download Directory, used by the DCC CLient to store files in the specified directory, if left empty, it will create a "Download" directory within the same folder where this library resides
141 | /// Port, optional parameter, where default = 0 (Automatic port selection), is port of the server you want to connect to, of type int
142 | /// Password, optional parameter, where default value is "", can be used to connect to a password protected server.
143 | /// Timeout, optional parameter, where default value is 3000 milliseconds, the maximum time before a server needs to answer, otherwise errors are thrown.
144 | /// Timeout, optional parameter, where default value is 3000 milliseconds, the maximum time before a server needs to answer, otherwise errors are thrown.
145 | public void SetConnectionInformation(string ip, string username, string channels,
146 | DCCClient dccClient, string downloadDirectory, int port = 0, string password = "", int timeout = 3000, bool enableSSL = true)
147 | {
148 | _newIp = ip;
149 | _NewPort = port;
150 | _NewUsername = username;
151 | _newPassword = password;
152 | _NewChannelss = channels;
153 | _isConnectionEstablised = false;
154 | _IsClientRunning = false;
155 | _timeOut = timeout;
156 | _downloadDirectory = downloadDirectory;
157 | _dccClient = dccClient;
158 | _enableSSL = enableSSL;
159 |
160 | if (_enableSSL)
161 | {
162 | if (port == 0)
163 | {
164 | _NewPort = 6697;
165 | } else if (port != 6697)
166 | {
167 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs("PORT: " + port.ToString() + " IS NOT COMMONLY USED FOR TLS/SSL CONNECTIONS, PREFER TO USE 6697 FOR SSL!", "SETUP WARNING"));
168 | }
169 | }
170 | else
171 | {
172 | if (port == 0)
173 | {
174 | _NewPort = 6667;
175 | }
176 | else if (port < 6665 && port > 6669)
177 | {
178 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs("PORT: " + port.ToString() + " IS NOT COMMONLY USED FOR NON TLS/SSL CONNECTIONS, PREFER TO USE PORTS BETWEEN 6665 & 6669!", "SETUP WARNING"));
179 | }
180 | }
181 | }
182 |
183 | ///
184 | /// Changes the download directory, will apply to the next instantiated download.
185 | ///
186 | /// Path to directory (creates it if it does not exist)
187 | public void SetDownloadDirectory(string downloadDirectory)
188 | {
189 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs("SET DOWNLOAD DIRECTORY: " + downloadDirectory, "SETTING DOWNLOAD DIRECTORY"));
190 | _downloadDirectory = downloadDirectory;
191 | }
192 |
193 | ///
194 | /// Starts the connection to the irc server, sends the register user command and register nick name command.
195 | ///
196 | /// true/false depending if error coccured
197 | public bool Connect()
198 | {
199 | try
200 | {
201 | _isConnectionEstablised = false;
202 | _receiverTask = new Task(StartReceivingChat);
203 | _receiverTask.Start();
204 |
205 | int timeout = 0;
206 | while (!_isConnectionEstablised)
207 | {
208 | Thread.Sleep(1);
209 | if (timeout > _timeOut)
210 | {
211 | return false;
212 | }
213 | timeout++;
214 | }
215 |
216 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs("IRC CLIENT SUCCESFULLY RUNNING", "IRC SETUP"));
217 | return true;
218 | }
219 | catch(Exception e)
220 | {
221 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs(e.ToString(), "SETUP ERROR"));
222 | return false;
223 | }
224 | }
225 |
226 | ///
227 | /// Starts quiting procedure, sends QUIT message to server and waits until server closes connection with the client, after that, it shuts down every reader and stream, and stops the receiver task.
228 | ///
229 | ///
230 | public bool QuitConnect()
231 | {
232 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs("STARTING IRC CLIENT SHUTDOWN PROCEDURE", "QUIT"));
233 | //send quit to server
234 | if (WriteIrc("QUIT"))
235 | {
236 | int timeout = 0;
237 | while (_tcpClient.Connected)
238 | {
239 | Thread.Sleep(1);
240 | if (timeout >= _timeOut)
241 | {
242 | return false;
243 | }
244 | timeout++;
245 | }
246 |
247 | _stopTask = true;
248 | Thread.Sleep(200);
249 | //stop everything in right order
250 | _receiverTask.Dispose();
251 | _streamReader.Dispose();
252 | _networkStream.Close();
253 | _streamWriter.Close();
254 | _tcpClient.Close();
255 |
256 | _isConnectionEstablised = false;
257 |
258 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs("FINISHED SHUTDOWN PROCEDURE", "QUIT"));
259 | return true;
260 |
261 | }
262 | else
263 | {
264 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs("COULD NOT WRITE QUIT COMMAND TO SERVER", "QUIT"));
265 | return true;
266 | }
267 | }
268 |
269 | ///
270 | /// Starts the receiver task.
271 | ///
272 | public void StartReceivingChat()
273 | {
274 |
275 | _tcpClient = new TcpClient(_newIp, _NewPort);
276 |
277 | int timeout = 0;
278 | while (!_tcpClient.Connected)
279 | {
280 | Thread.Sleep(1);
281 |
282 | if (timeout >= _timeOut)
283 | {
284 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs("TIMEOUT, COULD NOT CONNECT TO TCP SOCKET", "IRC SETUP"));
285 | }
286 | timeout++;
287 | }
288 |
289 |
290 | try
291 | {
292 |
293 | if (!_enableSSL)
294 | {
295 | _networkStream = _tcpClient.GetStream(); Thread.Sleep(500);
296 | _streamReader = new StreamReader(_networkStream);
297 | _streamWriter = new StreamWriter(_networkStream);
298 | _ircCommands = new IrcCommands(_networkStream);
299 | }
300 | else
301 | {
302 | _networkSStream = new SslStream(_tcpClient.GetStream());
303 | _networkSStream.AuthenticateAsClient(_newIp);
304 | _streamReader = new StreamReader(_networkSStream);
305 | _streamWriter = new StreamWriter(_networkSStream);
306 | _ircCommands = new IrcCommands(_networkSStream);
307 |
308 | }
309 |
310 |
311 |
312 | _isConnectionEstablised = true;
313 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs("CONNECTED TO TCP SOCKET", "IRC SETUP"));
314 |
315 |
316 |
317 | if (_newPassword.Length > 0)
318 | {
319 | if (!_ircCommands.SetPassWord(_newPassword))
320 | {
321 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs(_ircCommands.GetErrorMessage(), "IRC SETUP ERROR"));
322 | _isConnectionEstablised = false;
323 | }
324 | }
325 | Debug.WriteLine("Joining channels: " + _NewChannelss);
326 | if (!_ircCommands.JoinNetwork(_NewUsername, _NewChannelss))
327 | {
328 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs(_ircCommands.GetErrorMessage(), "IRC SETUP ERROR"));
329 | _isConnectionEstablised = false;
330 | }
331 | }
332 | catch (Exception ex)
333 | {
334 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs(ex.ToString(), "IRC SETUP"));
335 | }
336 |
337 |
338 |
339 | if (_isConnectionEstablised)
340 | {
341 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs("CONNECTED TO IRC SERVER", "IRC SETUP"));
342 | _stopTask = false;
343 | Task.Run(() => ReceiveChat());
344 | }
345 | }
346 |
347 | ///
348 | /// Receiver task, receives messages from server, handles joining intial join to channels, if the server responses with a 004 (which is a welcome message, meaning it has succesfully connected)
349 | /// Handles PRIVMSG messages
350 | /// Handles PING messages
351 | /// Handles JOIN messages
352 | /// Handles QUIT messages (though it's not yet possible to determine which channels these users have left
353 | /// Handles 353 messages (Users list per channel)
354 | /// Handles 366 messages (Finished user list per channel)
355 | /// Handles DCC SEND messages
356 | ///
357 | private void ReceiveChat()
358 | {
359 | try
360 | {
361 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs("STARTING LISTENER!", "IRC RECEIVER"));
362 |
363 |
364 | Dictionary> usersPerChannelDictionary = new Dictionary>();
365 |
366 | _IsClientRunning = true;
367 | _isConnectionEstablised = true;
368 | while (!_stopTask)
369 | {
370 |
371 | string ircData = _streamReader.ReadLine();
372 |
373 | OnRawMessageReceived?.Invoke(this, new IrcRawReceivedEventArgs(ircData));
374 |
375 |
376 |
377 | if (ircData.Contains("PING"))
378 | {
379 | string pingID = ircData.Split(':')[1];
380 | WriteIrc("PONG :" + pingID);
381 | }
382 | if ( ircData.Contains("PRIVMSG"))
383 | {
384 |
385 |
386 | //:MrRareie!~MrRareie_@Rizon-AC4B78B2.cm-3-2a.dynamic.ziggo.nl PRIVMSG #RareIRC :wassup
387 |
388 |
389 |
390 | try
391 | {
392 | string messageAndChannel = ircData.Split(new string[] { "PRIVMSG" }, StringSplitOptions.None)[1];
393 | string message = messageAndChannel.Split(':')[1].Trim();
394 | string channel = messageAndChannel.Split(':')[0].Trim();
395 | string user = ircData.Split(new string[] { "PRIVMSG" }, StringSplitOptions.None)[0].Split('!')[0].Substring(1);
396 |
397 | channel = channel.Replace("=", string.Empty);
398 |
399 | OnMessageReceived?.Invoke(this, new IrcReceivedEventArgs(message, user, channel));
400 | }
401 | catch(Exception ex)
402 | {
403 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs(ex.ToString(), "MESSAGE RECEIVED ERROR (PRIVMSG)"));
404 | }
405 |
406 |
407 |
408 | }
409 | else if (ircData.Contains("JOIN"))
410 | {
411 | //RAW: :napiz!~napiz@Rizon-BF96A69D.dyn.optonline.net JOIN :#NIBL
412 |
413 |
414 | try
415 | {
416 | string channel = ircData.Split(new string[] { "JOIN" }, StringSplitOptions.None)[1].Split(':')[1];
417 | string userThatJoined = ircData.Split(new string[] { "JOIN" }, StringSplitOptions.None)[0].Split(':')[1].Split('!')[0];
418 |
419 | OnMessageReceived?.Invoke(this, new IrcReceivedEventArgs("User Joined", userThatJoined, channel));
420 | }
421 | catch (Exception ex)
422 | {
423 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs(ex.ToString(), "MESSAGE RECEIVED ERROR (JOIN)"));
424 | }
425 |
426 | }
427 | else if (ircData.Contains("QUIT"))
428 | {
429 |
430 | //RAW: :MrRareie!~MrRareie_@Rizon-AC4B78B2.cm-3-2a.dynamic.ziggo.nl QUIT
431 | try
432 | {
433 | string user = ircData.Split(new string[] { "QUIT" }, StringSplitOptions.None)[0].Split('!')[0].Substring(1);
434 |
435 | OnMessageReceived?.Invoke(this, new IrcReceivedEventArgs("User Left", user, "unknown"));
436 | }
437 | catch (Exception ex)
438 | {
439 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs(ex.ToString(), "MESSAGE RECEIVED ERROR (JOIN)"));
440 | };
441 | }
442 |
443 | if (ircData.Contains("DCC SEND") && ircData.Contains(_NewUsername))
444 | {
445 | _dccClient.StartDownloader(ircData, _downloadDirectory, _bot, _packNumber, this);
446 | }
447 |
448 | //RareIRC_Client = #weebirc :RareIRC_Client
449 | if (ircData.Contains(" 353 "))
450 | {
451 | //:irc.x2x.cc 353 RoflHerp = #RareIRC :RoflHerp @MrRareie
452 | try
453 | {
454 | string channel = ircData.Split(new[] { " " + _NewUsername + " ="}, StringSplitOptions.None)[1].Split(':')[0].Replace(" ", string.Empty);
455 | string userListFullString = ircData.Split(new[] { " " + _NewUsername + " =" }, StringSplitOptions.None)[1].Split(':')[1];
456 |
457 |
458 | if (!channel.Contains(_NewUsername) && !channel.Contains("="))
459 | {
460 | string[] users = userListFullString.Split(' ');
461 | if (usersPerChannelDictionary.ContainsKey(channel))
462 | {
463 | usersPerChannelDictionary.TryGetValue(channel, out var currentUsers);
464 |
465 |
466 | foreach (string name in users)
467 | {
468 | if (!name.Contains(_NewUsername))
469 | {
470 | currentUsers.Add(name);
471 | }
472 | }
473 | usersPerChannelDictionary[channel.Trim()] = currentUsers;
474 | }
475 | else
476 | {
477 | List currentUsers = new List();
478 | foreach (string name in users)
479 | {
480 | currentUsers.Add(name);
481 | }
482 | usersPerChannelDictionary.Add(channel.Trim(), currentUsers);
483 | }
484 | }
485 |
486 |
487 | } catch (Exception ex)
488 | {
489 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs(ex.ToString(), "MESSAGE RECEIVED ERROR (USERLIST)"));
490 | }
491 |
492 |
493 | }
494 |
495 | if(ircData.ToLower().Contains(" 366 "))
496 | {
497 | OnUserListReceived?.Invoke(this, new IrcUserListReceivedEventArgs(usersPerChannelDictionary));
498 | usersPerChannelDictionary.Clear();
499 | }
500 | Thread.Sleep(1);
501 | }
502 |
503 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs("RECEIVER HAS STOPPED RUNNING", "MESSAGE RECEIVER"));
504 |
505 | QuitConnect();
506 | _stopTask = false;
507 | } catch (Exception ioex)
508 | {
509 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs("LOST CONNECTION: " + ioex.ToString(), "MESSAGE RECEIVER"));
510 | if (_isConnectionEstablised)
511 | {
512 | _stopTask = false;
513 | QuitConnect();
514 | }
515 | }
516 | _IsClientRunning = false;
517 | }
518 |
519 |
520 | ///
521 | /// Sends message to all channels, if message is not one of the following:
522 | /// /msg [bot] xdcc send [pack]
523 | /// /msg [bot] xdcc cancel
524 | /// /msg [bot] xdcc remove [pack]
525 | /// /names [channels] (can be empty)
526 | /// /join [channels]
527 | /// /quit
528 | /// /msg [channel/user] [message]
529 | ///
530 | /// String to send
531 | /// true / false depending if it could send the message to the server
532 | public bool SendMessageToAll(string input)
533 | {
534 |
535 | input = input.Trim();
536 | Regex regex1 = new Regex(@"^(?=.*(?(?<=/msg)(.*)(?=xdcc)))(?=.*(?(?<=(send)+(\s))(.*)))");
537 | Match matches1 = regex1.Match(input.ToLower());
538 | Regex regex2 = new Regex(@"^(?=.*(?(?<=/msg)(.*)(?=xdcc)))(?=.*(?(?<=(cancel))(.*)))");
539 | Match matches2 = regex2.Match(input.ToLower());
540 | Regex regex3 = new Regex(@"^(?=.*(?(?<=/msg)(.*)(?=xdcc)))(?=.*(?(?<=(remove)+(\s))(.*)))");
541 | Match matches3 = regex3.Match(input.ToLower());
542 |
543 | if (matches1.Success)
544 | {
545 | _bot = matches1.Groups["botname"].Value.Trim();
546 | _packNumber = matches1.Groups["packnum"].Value.Trim();
547 | string xdccdl = "PRIVMSG " + _bot + " :XDCC SEND " + _packNumber;
548 | return WriteIrc(xdccdl);
549 | }
550 | else if (matches2.Success)
551 | {
552 | _bot = matches2.Groups["botname"].Value;
553 | string xdcccl = "PRIVMSG " + _bot + " :XDCC CANCEL";
554 | return WriteIrc(xdcccl);
555 | }
556 | else if (matches3.Success)
557 | {
558 | _bot = matches3.Groups["botname"].Value;
559 | _packNumber = matches3.Groups["packnum"].Value;
560 | string xdccdl = "PRIVMSG " + _bot + " :XDCC REMOVE " + _packNumber;
561 | return WriteIrc(xdccdl);
562 | } else if (input.ToLower().Contains("/names"))
563 | {
564 | if (input.Contains("#"))
565 | {
566 | string channelList = input.Split(' ')[1];
567 | return GetUsersInChannel(channelList);
568 | } else
569 | {
570 | return GetUsersInChannel("");
571 | }
572 | }
573 | else if (input.ToLower().Contains("/join"))
574 | {
575 |
576 | if (input.Split(' ').Length > 0)
577 | {
578 | string channels = input.Split(' ')[1];
579 | _NewChannelss += channels;
580 | return WriteIrc("JOIN " + channels);
581 | }
582 | else
583 | {
584 | return false;
585 | }
586 | }
587 | else if(input.ToLower().Contains("/quit"))
588 | {
589 | return QuitConnect();
590 | }
591 | else if (input.ToLower().Contains("/msg"))
592 | {
593 | return WriteIrc(input.Replace("/msg", "PRIVMSG"));
594 | }
595 | else
596 | {
597 | return WriteIrc("PRIVMSG " + _NewChannelss + " :" + input);
598 | }
599 |
600 |
601 | }
602 |
603 |
604 | ///
605 | /// Sends message to specific channels, if message is not one of the following:
606 | /// /msg [bot] xdcc send [pack]
607 | /// /msg [bot] xdcc cancel
608 | /// /msg [bot] xdcc remove [pack]
609 | /// /names [channels] (can be empty)
610 | /// /join [channels]
611 | /// /quit
612 | /// /msg [channel/user] [message]
613 | ///
614 | /// String to send
615 | /// Channel(s) to send to
616 | /// true / false depending if it could send the message to the server
617 | public bool SendMessageToChannel(string input, string channel)
618 | {
619 |
620 | input = input.Trim();
621 | Regex regex1 = new Regex(@"^(?=.*(?(?<=/msg)(.*)(?=xdcc)))(?=.*(?(?<=(send)+(\s))(.*)))");
622 | Match matches1 = regex1.Match(input.ToLower());
623 | Regex regex2 = new Regex(@"^(?=.*(?(?<=/msg)(.*)(?=xdcc)))(?=.*(?(?<=(cancel))(.*)))");
624 | Match matches2 = regex2.Match(input.ToLower());
625 | Regex regex3 = new Regex(@"^(?=.*(?(?<=/msg)(.*)(?=xdcc)))(?=.*(?(?<=(remove)+(\s))(.*)))");
626 | Match matches3 = regex3.Match(input.ToLower());
627 |
628 | if (matches1.Success)
629 | {
630 | _bot = matches1.Groups["botname"].Value.Trim();
631 | _packNumber = matches1.Groups["packnum"].Value.Trim();
632 | string xdccdl = "PRIVMSG " + _bot + " :XDCC SEND " + _packNumber;
633 | return WriteIrc(xdccdl);
634 | }
635 | else if (matches2.Success)
636 | {
637 | _bot = matches2.Groups["botname"].Value;
638 | string xdcccl = "PRIVMSG " + _bot + " :XDCC CANCEL";
639 | return WriteIrc(xdcccl);
640 | }
641 | else if (matches3.Success)
642 | {
643 | _bot = matches3.Groups["botname"].Value;
644 | _packNumber = matches3.Groups["packnum"].Value;
645 | string xdccdl = "PRIVMSG " + _bot + " :XDCC REMOVE " + _packNumber;
646 | return WriteIrc(xdccdl);
647 | }
648 | else if (input.ToLower().Contains("/names"))
649 | {
650 | if (input.Contains("#"))
651 | {
652 | string channelList = input.Split(' ')[1];
653 | return GetUsersInChannel(channelList);
654 | }
655 | else
656 | {
657 | return GetUsersInChannel(channel);
658 | }
659 | }
660 | else if (input.ToLower().Contains("/join"))
661 | {
662 |
663 | if (input.Split(' ').Length > 0)
664 | {
665 | string channels = input.Split(' ')[1];
666 | _NewChannelss += channels;
667 | return WriteIrc("JOIN " + channels);
668 | }
669 | else
670 | {
671 | return false;
672 | }
673 | }
674 | else if (input.ToLower().Contains("/quit"))
675 | {
676 | return QuitConnect();
677 | }
678 | else if (input.ToLower().Contains("/msg"))
679 | {
680 | return WriteIrc(input.Replace("/msg", "PRIVMSG"));
681 | }
682 | else
683 | {
684 | return WriteIrc("PRIVMSG " + channel + " :" + input);
685 | }
686 |
687 |
688 | }
689 |
690 | ///
691 | /// Sends a raw message to the irc server, without any parsing applied
692 | ///
693 | /// message to send
694 | /// true/false depending if it could write to the irc server
695 | public bool SendRawMsg(string msg)
696 | {
697 | return WriteIrc(msg);
698 | }
699 |
700 | ///
701 | /// Sends the get names for specific channels or for all channels.
702 | ///
703 | /// channel, optional, default = "" = all channels,
704 | /// true/false depending if it could write to the server
705 | public bool GetUsersInChannel(string channel = "")
706 | {
707 |
708 | if (channel != "")
709 | {
710 | return WriteIrc("NAMES " + channel);
711 | } else
712 | {
713 | return WriteIrc("NAMES " + _NewChannelss);
714 | }
715 | }
716 |
717 | ///
718 | /// Writes a message to the irc server.
719 | ///
720 | /// Message to send
721 | /// true/false depending if it could write to the irc server
722 | public bool WriteIrc(string input)
723 | {
724 | try
725 | {
726 | _streamWriter.Write(input + Environment.NewLine);
727 | _streamWriter.Flush();
728 | return true;
729 | } catch(Exception e)
730 | {
731 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs("Could not send message" + input + ", _tcpClient client is not running :X, error : " + e.ToString(), "MESSAGE SENDER")); ;
732 | return false;
733 | }
734 |
735 | }
736 |
737 | ///
738 | /// Stops a download if a download is running.
739 | ///
740 | /// true/false depending if an error occured or not
741 | public bool StopXDCCDownload()
742 | {
743 | try
744 | {
745 | return !_dccClient.AbortDownloader(_timeOut);
746 | } catch (Exception e)
747 | {
748 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs("Could not stop XDCC Download, error: " + e.ToString(), "IRC CLIENT XDCC STOP"));
749 | return true;
750 | }
751 | }
752 |
753 | ///
754 | /// Checks if a download is running or not.
755 | ///
756 | /// true/false depending if a download is running, or if an error occured
757 | public bool CheckIfDownloading()
758 | {
759 | try
760 | {
761 | return _dccClient.CheckIfDownloading();
762 | }
763 | catch (Exception e)
764 | {
765 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs("Could not check if download has started, error: " + e.ToString(), "IRC CLIENT XDCC CHECK"));
766 | return false;
767 | }
768 | }
769 |
770 | ///
771 | /// Stops the client.
772 | ///
773 | public bool StopClient()
774 | {
775 | _stopTask = true;
776 | OnDebugMessage?.Invoke(this, new IrcDebugMessageEventArgs("CLOSING CLIENT", "CLOSE"));
777 | return QuitConnect();
778 | }
779 |
780 | ///
781 | /// Gets the connection status
782 | ///
783 | /// true/false depending on the connection status
784 | public bool IsConnectionEstablished()
785 | {
786 | return _isConnectionEstablised;
787 | }
788 |
789 | ///
790 | /// Gets the client status
791 | ///
792 | /// true or false depending if the client is running or not
793 | public bool IsClientRunning()
794 | {
795 | return _IsClientRunning;
796 | }
797 | }
798 |
799 |
800 | }
801 |
--------------------------------------------------------------------------------