* Now use config file value
[circ.git] / Circ.Backend.Cil / CilIrcChannel.cs
blob843dc37318c0dc2de9aebe85ef14e4fb52083066
1 #region License
2 /* Circ.Cil : Circ's Irc Library, main backend for Circ
3 * Copyright (C) 2007 LAVAL Jérémie
5 * This file is licensed under the terms of the LGPL.
7 * For the complete licence see the file COPYING.
8 */
9 #endregion
10 using System;
11 using System.Collections.Generic;
12 using Circ.Backend;
14 namespace Circ.Cil
16 public class CilIrcChannel: IrcChannel
18 IParser parser = DefaultParser.Instance;
19 // TODO: Maybe replace the List with a Dictionary for better performance since user are mainly manipulated
20 // with their nickname string
21 List<IrcUser> userList = new List<IrcUser>();
22 ChannelMessageBakery bakery;
24 internal CilIrcChannel(string channelName, IrcConnection conn)
25 : base(channelName, conn)
27 bakery = new ChannelMessageBakery(this);
28 InitBakery();
29 conn.MessageReceived += MessageReceivedParsing;
30 conn.SendRawMessage(Rfc.Join(channelName));
33 void InitBakery()
35 // TODO: turn this into static call using the sender arg
36 bakery.Message = delegate(IrcChannel sender, string[] args) {
37 Logger.Debug("Receiving message from " + sender.Name);
38 OnMessageReceived(new ChannelMessageEventArgs(args[0], args[1]));
41 bakery.NewUserList = delegate(IrcChannel sender, string[] users) {
42 Logger.Debug("Receiving users list from " + sender.Name);
43 AddInitialUsers(users);
46 bakery.Topic = delegate(IrcChannel sender, string topic) {
47 OnTopicUpdated(new TopicEventArgs(topic));
50 bakery.QuitOrPart = delegate(IrcChannel sender, string[] temp) {
51 Logger.Debug("An user has departed from " + sender.Name);
52 IrcUser usertemp = null;
53 if (temp[0] == null)
54 return;
55 if ((usertemp = GetUserByName(temp[0])) == null)
56 return;
57 this.userList.Remove(usertemp);
58 OnUserDisconnected(new UserQuitEventArgs(temp[1] ?? string.Empty, usertemp));
61 bakery.Join = delegate(IrcChannel sender, string[] infos) {
62 // Dont add ourself
63 if (infos[0].Equals(this.ParentConnection.Nick, StringComparison.Ordinal))
64 return;
66 bool halfOp = infos[0][0] == Rfc.HalfOpChar;
67 bool op = infos[0][0] == Rfc.OpChar || infos[0][0] == Rfc.NetworkOp;
69 IrcUser user = new CilIrcUser((halfOp || op) ? infos[0].Substring(1) : infos[0], infos[1],
70 this, op, halfOp);
71 this.userList.Add(user);
73 OnNewUserConnected(new UserEventArgs(user));
77 public override void SendMessage (string message)
79 ParentConnection.SendRawMessage(Rfc.PrivMsg(Name, message));
82 protected override void CloseChannel (string byeMessage)
84 ParentConnection.SendRawMessage(Rfc.Part(Name, byeMessage));
88 private void MessageReceivedParsing(object sender, MessageEventArgs e)
90 // Now evrything is handled via event
92 bakery.PostNewMessage(e.Message);
94 bool isAction = parser.RetrieveMessageType(e.Message) == MessageType.Action;
95 ActionType action = (isAction) ? parser.RetrieveAction(e.Message) : (ActionType)0;
97 try {
98 if ()
99 OnMessageReceived(new ChannelMessageEventArgs(parser.RetrieveAuthor(e.Message),
100 parser.RetrieveMessage(e.Message)));
101 else if (msgType == MessageType.Reply
102 && parser.RetrieveNumericalReply(e.Message) == Rfc.NamesReply && parser.RetrieveChannelTarget(e.Message) == this.Name)
103 AddInitialUsers(parser.RetrieveUsersList(e.Message));
104 else if (msgType == MessageType.Action && parser.RetrieveAction(e.Message) == ActionType.Join && parser.RetrieveChannelTarget(e.Message) == this.Name) {
105 string[] temp = parser.RetrieveJoinInformations(e.Message);
106 // Dont add ourself
107 if (temp[0].Equals(this.ParentConnection.Nick, StringComparison.Ordinal))
108 return;
110 IrcUser user = new CilIrcUser(temp[0], temp[1], this, false, temp[0][0] == Rfc.HalfOpChar);
111 this.userList.Add(user);
112 // TODO: handle op thing correctly
113 OnNewUserConnected(new UserEventArgs(user));
115 else if (msgType == MessageType.Action && parser.RetrieveAction(e.Message) == ActionType.Part && parser.RetrieveChannelTarget(e.Message) == this.Name) {
116 string[] temp = parser.RetrieveQuitInformations(e.Message);
117 IrcUser usertemp = null;
118 if (temp[0] == null)
119 return;
120 if ((usertemp = GetUserByName(temp[0])) == null)
121 return;
122 this.userList.Remove(usertemp);
123 OnUserDisconnected(new UserQuitEventArgs(temp[1] ?? string.Empty, usertemp));
125 else if (msgType == MessageType.Reply
126 && parser.RetrieveNumericalReply(e.Message) == Rfc.TopicReply && parser.RetrieveChannelTarget(e.Message) == this.Name)
127 OnTopicUpdated(new TopicEventArgs(parser.RetrieveTopic(e.Message)));
128 } catch (Exception ex) {
129 Logger.Error("A message has been dropped", ex);
135 private void AddInitialUsers(string[] names)
137 if (names == null)
138 throw new ArgumentNullException("names");
139 if (names.Length == 0)
140 throw new ArgumentException("names is empty");
142 userList.Clear();
144 // HACK: WTF ? IndexOutOfRange even with names.Length
145 for (int i = 0; i< names.Length - 1; i++) {
146 if (names[i][0] == Rfc.HalfOpChar)
147 userList.Add(new CilIrcUser(names[i], "foo", this, true, false));
148 else
149 userList.Add(new CilIrcUser(names[i], "foo", this, false, false));
152 OnNewUserList(new UserListEventArgs(userList.ToArray()));
155 private IrcUser GetUserByName(string userName)
157 IrcUser temp = null;
158 foreach (IrcUser user in userList) {
159 if (user.Nick == userName) {
160 temp = user;
161 break;
164 return temp;