001 #define IRCD_CMD_ADMIN  0
002 #define IRCD_CMD_AWAY   1
003 #define IRCD_CMD_CNOTICE        2
004 #define IRCD_CMD_CPRIVMSG       3
005 #define IRCD_CMD_CONNECT        4
006 #define IRCD_CMD_DIE    5
007 #define IRCD_CMD_ENCAP  6
008 #define IRCD_CMD_ERROR  7
009 #define IRCD_CMD_HELP   8
010 #define IRCD_CMD_INFO   9
011 #define IRCD_CMD_INVITE 10
012 #define IRCD_CMD_ISON   11
013 #define IRCD_CMD_JOIN   12
014 #define IRCD_CMD_KICK   13
015 #define IRCD_CMD_KILL   14
016 #define IRCD_CMD_KNOCK  15
017 #define IRCD_CMD_LINKS  16
018 #define IRCD_CMD_LIST   17
019 #define IRCD_CMD_LUSERS 18
020 #define IRCD_CMD_MODE   19
021 #define IRCD_CMD_MOTD   20
022 #define IRCD_CMD_NAMES  21
023 #define IRCD_CMD_NAMESX 22
024 #define IRCD_CMD_NICK   23
025 #define IRCD_CMD_NOTICE 24
026 #define IRCD_CMD_OPER   25
027 #define IRCD_CMD_PART   26
028 #define IRCD_CMD_PASS   27
029 #define IRCD_CMD_PING   28
030 #define IRCD_CMD_PONG   29
031 #define IRCD_CMD_PRIVMSG        30
032 #define IRCD_CMD_QUIT   31
033 #define IRCD_CMD_REHASH 32
034 #define IRCD_CMD_RESTART        33
035 #define IRCD_CMD_RULES  34
036 #define IRCD_CMD_SERVER 35
037 #define IRCD_CMD_SERVICE        36
038 #define IRCD_CMD_SERVLIST       37
039 #define IRCD_CMD_SQUERY 38
040 #define IRCD_CMD_SQUIT  39
041 #define IRCD_CMD_SETNAME        40
042 #define IRCD_CMD_SILENCE        41
043 #define IRCD_CMD_STATS  42
044 #define IRCD_CMD_SUMMON 43
045 #define IRCD_CMD_TIME   44
046 #define IRCD_CMD_TOPIC  45
047 #define IRCD_CMD_TRACE  46
048 #define IRCD_CMD_UHNAMES        47
049 #define IRCD_CMD_USER   48
050 #define IRCD_CMD_USERHOST       49
051 #define IRCD_CMD_USERIP 50
052 #define IRCD_CMD_USERS  51
053 #define IRCD_CMD_VERSION        52
054 #define IRCD_CMD_WALLOPS        53
055 #define IRCD_CMD_WATCH  54
056 #define IRCD_CMD_WHO    55
057 #define IRCD_CMD_WHOIS  56
058 #define IRCD_CMD_WHOWAS 57
059 #define IRCD_CMD_CAP 58
060 #define IRCD_CMD_TAGMSG 59
061 
062 #define IRCD_CMDS_MAX    60
063 
064 U8 **ircd_commands = CAlloc(sizeof(U64) * IRCD_CMDS_MAX);
065 
066 // Nroot additions
067 //https://ircv3.net/specs/extensions/capability-negotiation
068 ircd_commands[IRCD_CMD_CAP] = "CAP";
069 ircd_commands[IRCD_CMD_TAGMSG] = "TAGMSG";
070 // End of Nroot additions
071 ircd_commands[IRCD_CMD_ADMIN] = "ADMIN";
072 ircd_commands[IRCD_CMD_AWAY] = "AWAY";
073 ircd_commands[IRCD_CMD_CNOTICE] = "CNOTICE";
074 ircd_commands[IRCD_CMD_CPRIVMSG] = "CPRIVMSG";
075 ircd_commands[IRCD_CMD_CONNECT] = "CONNECT";
076 ircd_commands[IRCD_CMD_DIE] = "DIE";
077 ircd_commands[IRCD_CMD_ENCAP] = "ENCAP";
078 ircd_commands[IRCD_CMD_ERROR] = "ERROR";
079 ircd_commands[IRCD_CMD_HELP] = "HELP";
080 ircd_commands[IRCD_CMD_INFO] = "INFO";
081 ircd_commands[IRCD_CMD_INVITE] = "INVITE";
082 ircd_commands[IRCD_CMD_ISON] = "ISON";
083 ircd_commands[IRCD_CMD_JOIN] = "JOIN";
084 ircd_commands[IRCD_CMD_KICK] = "KICK";
085 ircd_commands[IRCD_CMD_KILL] = "KILL";
086 ircd_commands[IRCD_CMD_KNOCK] = "KNOCK";
087 ircd_commands[IRCD_CMD_LINKS] = "LINKS";
088 ircd_commands[IRCD_CMD_LIST] = "LIST";
089 ircd_commands[IRCD_CMD_LUSERS] = "LUSERS";
090 ircd_commands[IRCD_CMD_MODE] = "MODE";
091 ircd_commands[IRCD_CMD_MOTD] = "MOTD";
092 ircd_commands[IRCD_CMD_NAMES] = "NAMES";
093 ircd_commands[IRCD_CMD_NAMESX] = "NAMESX";
094 ircd_commands[IRCD_CMD_NICK] = "NICK";
095 ircd_commands[IRCD_CMD_NOTICE] = "NOTICE";
096 ircd_commands[IRCD_CMD_OPER] = "OPER";
097 ircd_commands[IRCD_CMD_PART] = "PART";
098 ircd_commands[IRCD_CMD_PASS] = "PASS";
099 ircd_commands[IRCD_CMD_PING] = "PING";
100 ircd_commands[IRCD_CMD_PONG] = "PONG";
101 ircd_commands[IRCD_CMD_PRIVMSG] = "PRIVMSG";
102 ircd_commands[IRCD_CMD_QUIT] = "QUIT";
103 ircd_commands[IRCD_CMD_REHASH] = "REHASH";
104 ircd_commands[IRCD_CMD_RESTART] = "RESTART";
105 ircd_commands[IRCD_CMD_RULES] = "RULES";
106 ircd_commands[IRCD_CMD_SERVER] = "SERVER";
107 ircd_commands[IRCD_CMD_SERVICE] = "SERVICE";
108 ircd_commands[IRCD_CMD_SERVLIST] = "SERVLIST";
109 ircd_commands[IRCD_CMD_SQUERY] = "SQUERY";
110 ircd_commands[IRCD_CMD_SQUIT] = "SQUIT";
111 ircd_commands[IRCD_CMD_SETNAME] = "SETNAME";
112 ircd_commands[IRCD_CMD_SILENCE] = "SILENCE";
113 ircd_commands[IRCD_CMD_STATS] = "STATS";
114 ircd_commands[IRCD_CMD_SUMMON] = "SUMMON";
115 ircd_commands[IRCD_CMD_TIME] = "TIME";
116 ircd_commands[IRCD_CMD_TOPIC] = "TOPIC";
117 ircd_commands[IRCD_CMD_TRACE] = "TRACE";
118 ircd_commands[IRCD_CMD_UHNAMES] = "UHNAMES";
119 ircd_commands[IRCD_CMD_USER] = "USER";
120 ircd_commands[IRCD_CMD_USERHOST] = "USERHOST";
121 ircd_commands[IRCD_CMD_USERIP] = "USERIP";
122 ircd_commands[IRCD_CMD_USERS] = "USERS";
123 ircd_commands[IRCD_CMD_VERSION] = "VERSION";
124 ircd_commands[IRCD_CMD_WALLOPS] = "WALLOPS";
125 ircd_commands[IRCD_CMD_WATCH] = "WATCH";
126 ircd_commands[IRCD_CMD_WHO] = "WHO";
127 ircd_commands[IRCD_CMD_WHOIS] = "WHOIS";
128 ircd_commands[IRCD_CMD_WHOWAS] = "WHOWAS";
129 
130 I64 IrcMatchCommand(U8 *str)
131 {
132   I64 i;
133   for (i=0; i<IRCD_CMDS_MAX; i++)
134     {
135     if (!StrICmp(str, ircd_commands[i])) return i;
136   }
137   return -1;
138 }
139 
140 U0 IrcPass(IrcClient *client,U8 *str) {
141   if(!str||client->account) return;
142   if(client->password[0]&&client->logged_in)
143     IrcAccountChangePassword(client,str);
144   StrCpy(client->password,str);
145 }
146 
147 U0 IrcCap(IrcClient *client,U8 *str) {
148 }
149 
150 U0 IrcParseCommand(IrcClient *client, U8 *str)
151 {
152 DbgPrint("%s\n",str);
153 //Skip message tags(For now)
154   if(*str=='@') {
155     Free(client->client_tags);
156     client->client_tags=IrcGetClientMsgs(str);
157    str=StrFirstOcc(str," ");
158    if(!str) return;
159    else str++;
160   }
161   U8 **argv;
162   I64 argc = NULL;
163   I64 cmd = -1;
164   argv = ParseArgs(str, &argc);
165   if (argc)
166     {
167     cmd = IrcMatchCommand(argv[0]);
168     switch (cmd)
169       {
170       case IRCD_CMD_NAMES:
171        if(argc==2) {
172          IrcClientNames(client, argv[1]);
173        }
174        break;
175       case IRCD_CMD_JOIN:
176         if (argc>=2) {
177           if(!client->logged_in&&0) {
178             IrcClientNotice(client,"Use /PASS password first to set a password/login(traffic is logged,use something dumb)");
179           } else if(argc==2) {
180             if(IrcChannelJoin(argv[1], client)) {
181               IrcClientTopic(client, argv[1]);
182               IrcClientNames(client, argv[1]);
183             }
184           } else if(argc==3) {
185             if(IrcChannelJoin(argv[1], client,argv[2])) {
186               IrcClientTopic(client, argv[1]);
187               IrcClientNames(client, argv[1]);
188             }
189           }
190         }
191         break;
192       case IRCD_CMD_KICK:
193         break; //TODO
194         if (argc>3&&StrOcc(str,':'))
195           {
196           IrcChannelKick(argv[1], client, argv[2], StrFirstOcc(str, ":")+1);
197         }
198         else
199           {
200           IrcChannelKick(argv[1], client, argv[2], argv[2]);
201         }
202         break;
203       case IRCD_CMD_MODE:
204         if (argc==3)
205           {
206           IrcChannelMode(argv[1], client, argv[2]);
207         }
208         if (argc==4)
209           {
210           IrcChannelMode(argv[1], client, argv[2], argv[3]);
211         }
212         break;
213       case IRCD_CMD_NICK:
214         if (argc==2)
215           {
216           IrcClientSetNick(client, argv[1]);
217           if(!client->logged_in&&client->nick_set&&client->password[0])
218             IrcAccountLogin(client,client->nick,client->password);
219         }
220         break;
221       case IRCD_CMD_PART:
222         if (argc==2)
223           {
224           IrcChannelPart(argv[1], client);
225         }
226 
227         if (argc>2&&StrOcc(str,':'))
228           {
229           IrcChannelPart(argv[1], client, StrFirstOcc(str, ":")+1);
230         }
231         break;
232       case IRCD_CMD_PING:
233         if (argc==2)
234           {
235           IrcClientPing(client, argv[1]);
236         }
237         break;
238       case IRCD_CMD_PRIVMSG:
239         if (argc>2&&StrOcc(str,':'))
240           {
241           if(!client->logged_in&&0) {
242             IrcClientNotice(client,"Use /PASS password first to set a password/login(traffic is logged,use something dumb)");
243           } else {
244             IrcClientPrivMsg(client, argv[1], StrFirstOcc(str, ":")+1);
245           }
246         }
247         break;
248       case IRCD_CMD_TAGMSG:
249         if(argc>=2) {
250           IrcClientTagMsg(client, argv[1]);
251         }
252         break;
253       case IRCD_CMD_QUIT:
254         if (argc==1)
255           {
256           IrcChannelsQuit(client);
257         }
258         if (argc>1&&StrOcc(str,':'))
259           {
260           IrcChannelsQuit(client, StrFirstOcc(str, ":")+1);
261         }
262         client->disconnected = TRUE;
263         break;
264       case IRCD_CMD_TOPIC:
265         if (argc>2&&StrOcc(str,':'))
266           {
267           IrcChannelTopic(argv[1], client, StrFirstOcc(str, ":")+1);
268         }
269         break;
270       case IRCD_CMD_USER:
271         if (argc>4&&StrOcc(str,':'))
272         {
273          IrcClientSetUser(client, argv[1], argv[2], argv[3], StrFirstOcc(str, ":")+1); // for now
274          IrcClientMotd(client);
275         }
276         IrcCap(client,"CAP LS 302");
277         break;
278       case IRCD_CMD_WHO:
279         if (argc==2)
280           {
281           IrcClientWho(client, argv[1]);
282         }
283         break;
284       case IRCD_CMD_PONG:
285         client->missed_pings--;
286         //???
287         if(client->missed_pings<0)
288            client->missed_pings=0;
289       case IRCD_CMD_LIST:
290         IrcList(client);
291         break;
292       case IRCD_CMD_CAP:
293 //        if(client->account) //Wait for a connection first
294           IrcCap(client,str);
295         break;
296       case IRCD_CMD_PASS:
297         IrcPass(client,argv[1]);
298         if(!client->logged_in&&client->password&&client->nick_set) 
299           IrcAccountLogin(client,client->nick,client->password);
300         else if(client->password&&client->nick_set)
301           IrcAccountChangePassword(client,argv[1]);
302         break;
303       default:
304         break;
305     }
306     FreeArgs(argc, argv);
307   }
308   client->idle = __GetTicks;
309 }