altered several year numbers from "2005" to "2006"
[reactos.git] / irc / TechBot / TechBot.Library / IrcService.cs
1 using System;
2 using System.Collections;
3 using System.Threading;
4 using TechBot.IRCLibrary;
5
6 namespace TechBot.Library
7 {
8 public class IrcService : IServiceOutput
9 {
10 private string hostname;
11 private int port;
12 private string channelnames;
13 private string botname;
14 private string password;
15 private string chmPath;
16 private string mainChm;
17 private string ntstatusXml;
18 private string winerrorXml;
19 private string hresultXml;
20 private string wmXml;
21 private string svnCommand;
22 private string bugUrl, WineBugUrl, SambaBugUrl;
23 private IrcClient client;
24 private ArrayList channels = new ArrayList(); /* IrcChannel */
25 private TechBotService service;
26 private bool isStopped = false;
27
28 public IrcService(string hostname,
29 int port,
30 string channelnames,
31 string botname,
32 string password,
33 string chmPath,
34 string mainChm,
35 string ntstatusXml,
36 string winerrorXml,
37 string hresultXml,
38 string wmXml,
39 string svnCommand,
40 string BugUrl,
41 string WineBugUrl,
42 string SambaBugUrl)
43 {
44 this.hostname = hostname;
45 this.port = port;
46 this.channelnames = channelnames;
47 this.botname = botname;
48 if (password == null || password.Trim() == "")
49 this.password = null;
50 else
51 this.password = password;
52 this.chmPath = chmPath;
53 this.mainChm = mainChm;
54 this.ntstatusXml = ntstatusXml;
55 this.winerrorXml = winerrorXml;
56 this.hresultXml = hresultXml;
57 this.wmXml = wmXml;
58 this.svnCommand = svnCommand;
59 this.bugUrl = BugUrl;
60 this.WineBugUrl = WineBugUrl;
61 this.SambaBugUrl = SambaBugUrl;
62 }
63
64 public void Run()
65 {
66 service = new TechBotService(this,
67 chmPath,
68 mainChm,
69 ntstatusXml,
70 winerrorXml,
71 hresultXml,
72 wmXml,
73 svnCommand,
74 bugUrl,
75 WineBugUrl,
76 SambaBugUrl);
77 service.Run();
78
79 client = new IrcClient();
80 client.Encoding = System.Text.Encoding.GetEncoding("iso-8859-1");
81 client.MessageReceived += new MessageReceivedHandler(client_MessageReceived);
82 client.ChannelUserDatabaseChanged += new ChannelUserDatabaseChangedHandler(client_ChannelUserDatabaseChanged);
83 System.Console.WriteLine(String.Format("Connecting to {0} port {1}",
84 hostname, port));
85 client.Connect(hostname, port);
86 System.Console.WriteLine("Connected...");
87 client.Register(botname, password, null);
88 System.Console.WriteLine(String.Format("Registered as {0}...", botname));
89 JoinChannels();
90
91 while (!isStopped)
92 {
93 Thread.Sleep(1000);
94 }
95
96 PartChannels();
97 client.Diconnect();
98 System.Console.WriteLine("Disconnected...");
99 }
100
101 public void Stop()
102 {
103 isStopped = true;
104 }
105
106 private void JoinChannels()
107 {
108 foreach (string channelname in channelnames.Split(new char[] { ';' }))
109 {
110 IrcChannel channel = client.JoinChannel(channelname);
111 channels.Add(channel);
112 System.Console.WriteLine(String.Format("Joined channel #{0}...",
113 channel.Name));
114 }
115 }
116
117 private void PartChannels()
118 {
119 foreach (IrcChannel channel in channels)
120 {
121 client.PartChannel(channel, "Caught in the bitstream...");
122 System.Console.WriteLine(String.Format("Parted channel #{0}...",
123 channel.Name));
124 }
125 }
126
127 private string GetMessageSource(MessageContext context)
128 {
129 if (context is ChannelMessageContext)
130 {
131 ChannelMessageContext channelContext = context as ChannelMessageContext;
132 return String.Format("#{0}",
133 channelContext.Channel.Name);
134 }
135 else if (context is UserMessageContext)
136 {
137 UserMessageContext userContext = context as UserMessageContext;
138 return userContext.User.Nickname;
139 }
140 else
141 {
142 throw new InvalidOperationException(String.Format("Unhandled message context '{0}'",
143 context.GetType()));
144 }
145 }
146
147 public void WriteLine(MessageContext context,
148 string message)
149 {
150 if (context is ChannelMessageContext)
151 {
152 ChannelMessageContext channelContext = context as ChannelMessageContext;
153 channelContext.Channel.Talk(message);
154 }
155 else if (context is UserMessageContext)
156 {
157 UserMessageContext userContext = context as UserMessageContext;
158 userContext.User.Talk(message);
159 }
160 else
161 {
162 throw new InvalidOperationException(String.Format("Unhandled message context '{0}'",
163 context.GetType()));
164 }
165 }
166
167 private void ExtractMessage(string parameters,
168 out string message)
169 {
170 int startIndex = parameters.IndexOf(':');
171 if (startIndex != -1)
172 {
173 message = parameters.Substring(startIndex + 1);
174 }
175 else
176 {
177 message = parameters;
178 }
179 }
180
181 private bool GetChannelName(IrcMessage message,
182 out string channelName)
183 {
184 if (message.Parameters == null || !message.Parameters.StartsWith("#"))
185 {
186 channelName = null;
187 return false;
188 }
189
190 int index = message.Parameters.IndexOf(' ');
191 if (index == -1)
192 index = message.Parameters.Length;
193 else
194 index = index - 1;
195 channelName = message.Parameters.Substring(1, index);
196 return true;
197 }
198
199 private bool GetTargetNickname(IrcMessage message,
200 out string nickname)
201 {
202 if (message.Parameters == null)
203 {
204 nickname = null;
205 return false;
206 }
207
208 int index = message.Parameters.IndexOf(' ');
209 if (index == -1)
210 index = message.Parameters.Length;
211 nickname = message.Parameters.Substring(0, index);
212 Console.WriteLine("nickname: " + nickname);
213 return true;
214 }
215
216 private bool ShouldAcceptMessage(IrcMessage message,
217 out MessageContext context)
218 {
219 if (message.Command.ToUpper().Equals("PRIVMSG"))
220 {
221 string channelName;
222 string nickname;
223 if (GetChannelName(message,
224 out channelName))
225 {
226 foreach (IrcChannel channel in channels)
227 {
228 if (String.Compare(channel.Name, channelName, true) == 0)
229 {
230 context = new ChannelMessageContext(channel);
231 return true;
232 }
233 }
234 }
235 else if (GetTargetNickname(message,
236 out nickname))
237 {
238 IrcUser targetUser = new IrcUser(client,
239 nickname);
240 if (String.Compare(targetUser.Nickname, botname, true) == 0)
241 {
242 IrcUser sourceUser = new IrcUser(client,
243 message.PrefixNickname);
244 context = new UserMessageContext(sourceUser);
245 return true;
246 }
247 }
248 }
249 context = null;
250 return false;
251 }
252
253 private void client_MessageReceived(IrcMessage message)
254 {
255 try
256 {
257 if (message.Command != null &&
258 message.Parameters != null)
259 {
260 string injectMessage;
261 ExtractMessage(message.Parameters,
262 out injectMessage);
263 MessageContext context;
264 if (ShouldAcceptMessage(message,
265 out context))
266 {
267 Console.WriteLine(String.Format("Injecting: {0} from {1}",
268 injectMessage,
269 GetMessageSource(context)));
270 service.InjectMessage(context,
271 injectMessage);
272 }
273 else
274 {
275 Console.WriteLine("Received: " + message.Line);
276 }
277 }
278 else
279 {
280 Console.WriteLine("Received: " + message.Line);
281 }
282 }
283 catch (Exception ex)
284 {
285 Console.WriteLine(String.Format("Exception: {0}", ex));
286 }
287 }
288
289 private void client_ChannelUserDatabaseChanged(IrcChannel channel)
290 {
291 }
292 }
293 }