-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathProgram.cs
More file actions
181 lines (151 loc) · 8.1 KB
/
Program.cs
File metadata and controls
181 lines (151 loc) · 8.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
using NetIRC.Messages;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace NetIRC.ConsoleCli
{
public class Program
{
public const string Server = "irc.rizon.net";
public const string MyCommander = "Fredi_"; // Who can control me
public const string CommandPrefix = "EXECUTE ";
private const string nickName = "NetIRCConsoleClient";
private const string channel = "#NetIRCChannel";
// Set this to true if you want all raw messages received from the server to be written to the console
private const bool verbose = false;
static async Task Main()
{
var cancelKeyPress = new TaskCompletionSource();
Console.CancelKeyPress += (s, e) =>
{
cancelKeyPress.SetResult();
e.Cancel = true;
};
Console.WriteLine("Press Ctrl+C to stop this application.");
var builder = Client.CreateBuilder()
.WithNick(nickName, "NetIRC")
.WithServer(Server, 6667);
// Create IRC client instance with a using statement so it gets properly disposed (IDisposable pattern)
using var client = builder.Build();
// Subscribe to IRC client events
client.RawDataReceived += Client_RawDataReceived;
client.IRCMessageParsed += Client_IRCMessageParsed;
client.RegistrationCompleted += EventHub_RegistrationCompleted;
// Queries is an ObservableCollection, so we can subscribe to the CollectionChanged event
// A new Query will be automatically created when initiating a private conversation with someone
client.Queries.CollectionChanged += Queries_CollectionChanged;
// Channels is also an ObservableCollection, so we can subscribe to the CollectionChanged event
// A new Channel will be automatically created when joining a channel
client.Channels.CollectionChanged += Channels_CollectionChanged;
// Handy method to register all custom message handlers in an assembly
client.RegisterCustomMessageHandlers(typeof(Program).Assembly);
// Custom message handlers can also be manually registered
//client.RegisterCustomMessageHandler<PrivMsgHandler>();
Console.WriteLine($"Connecting to {Server}...");
// Connect to the server and let the magic happen in the background
await client.ConnectAsync();
// Wait for Ctrl+C before exiting the console application
await Task.WhenAny(cancelKeyPress.Task, Task.Delay(Timeout.Infinite));
Console.WriteLine("Shutting down...");
}
// This event handler will be called everytime a raw message is received from the server (interesting to inspect the IRC protocol)
private static void Client_RawDataReceived(Client client, string rawData)
{
if (verbose)
{
#pragma warning disable CS0162 // Suppress warning: Unreachable code detected
WriteLine(rawData);
#pragma warning restore CS0162 // Suppress warning: Unreachable code detected
}
}
// This event handler will be called after the IRC client has parsed a raw message (nicer to work with when compared to the raw message string)
private static void Client_IRCMessageParsed(Client client, ParsedIRCMessage ircMessage)
{
_ = HandleIrcMessageParsedAsync(client, ircMessage);
}
private static async Task HandleIrcMessageParsedAsync(Client client, ParsedIRCMessage ircMessage)
{
// When receiving a topic message
// NOTE: Just an example, because having a custom message handler deriving from CustomMessageHandler<TopicMessage> would be better
// as TopicMessage will have the message parsed even further
if (ircMessage.IRCCommand == IRCCommand.TOPIC)
{
var channel = ircMessage.Parameters[0];
var topic = ircMessage.Trailing;
WriteLine($"* {channel}'s TOPIC: {topic}", ConsoleColor.Cyan);
}
// If we joined a channel, or someone joined a channel we're in
// NOTE: Just as an example. We can use a custom message handler deriving from CustomMessageHandler<JoinMessage>
if (ircMessage.IRCCommand == IRCCommand.JOIN)
{
// At this point we can create an instance of JoinMessage using the ParsedIRCMessage (Since we know for sure this is a JOIN message)
// This could have been done in the TOPIC message above with: var topicMessage = new TopicMessage(ircMessage);
// Having a more specific message object saves us from having to get information from Parameters and Trailing properties (as seen above with TOPIC)
var joinMessage = new JoinMessage(ircMessage);
// If we joined the #NetIRCChannel channel, change its topic
if (joinMessage.Nick == nickName && joinMessage.Channel == channel)
{
await client.SendAsync(new TopicMessage(channel, "NetIRC is nice!!"));
}
}
}
// This event handler will be called when the user registration has been completed (usefull to know when we can start sending messages to the server)
private static void EventHub_RegistrationCompleted(object sender, EventArgs e)
{
_ = HandleRegistrationCompletedAsync(sender);
}
private static async Task HandleRegistrationCompletedAsync(object sender)
{
if (sender is Client client)
{
WriteLine("Ready to Roll!", ConsoleColor.Yellow);
await client.SendAsync(new JoinMessage(channel));
}
}
// This event handler will be called when a new Query is created (after initiating a new private conversation)
private static void Queries_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
// Explicitly using the Query type in the foreach
foreach (Query item in e.NewItems)
{
// Query.Messages is an ObservableCollection
// So let's subscribe to it in order to do something with private messages received
item.Messages.CollectionChanged += Messages_CollectionChanged;
}
}
private static void Messages_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
// Explicitly using the QueryMessage type in the foreach
foreach (QueryMessage item in e.NewItems)
{
// Print private message
WriteLine($"<{item.User.Nick}> {item.Text}", ConsoleColor.Green);
}
}
private static void Channels_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
// Explicitly using the Channel type in the foreach
foreach (Channel item in e.NewItems)
{
item.Messages.CollectionChanged += ChannelMessages_CollectionChanged;
}
}
private static void ChannelMessages_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
// Explicitly using the ChannelMessage type in the foreach
foreach (ChannelMessage item in e.NewItems)
{
// Print channel message
WriteLine($"[{item.Channel.Name}] <{item.User.Nick}> {item.Text}", ConsoleColor.Yellow);
}
}
// Just a simple Console.WriteLine wrapper to allow us to change font color
public static void WriteLine(string value, ConsoleColor color = ConsoleColor.White)
{
var previousColor = Console.ForegroundColor;
Console.ForegroundColor = color;
Console.WriteLine(value);
Console.ForegroundColor = previousColor;
}
}
}