]> jfr.im git - irc/quakenet/newserv.git/blob - lua/lualocal.c
Add local user functions to lua.
[irc/quakenet/newserv.git] / lua / lualocal.c
1 #include <stdlib.h>
2
3 #include "../localuser/localuser.h"
4 #include "../lib/strlfunc.h"
5 #include "../core/schedule.h"
6 #include "../channel/channel.h"
7 #include "../localuser/localuserchannel.h"
8
9 #include "lua.h"
10 #include "luabot.h"
11 #include "lualocal.h"
12
13 void lua_localnickhandler(nick *target, int type, void **args);
14 void lua_reconnectlocal(void *arg);
15
16 static int lua_registerlocaluser(lua_State *ps) {
17 nick *np;
18 lua_list *l;
19 lua_localnick *ln;
20 char *nickname, *ident, *hostname, *realname, *account;
21 flag_t modes = 0;
22
23 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2) || !lua_isstring(ps, 3) || !lua_isstring(ps, 4) || !lua_isstring(ps, 5) || !lua_isstring(ps, 6) || !lua_isfunction(ps, 7))
24 return 0;
25
26 nickname = (char *)lua_tostring(ps, 1);
27 ident = (char *)lua_tostring(ps, 2);
28 hostname = (char *)lua_tostring(ps, 3);
29 realname = (char *)lua_tostring(ps, 4);
30 account = (char *)lua_tostring(ps, 5);
31
32 setflags(&modes, UMODE_ALL, (char *)lua_tostring(ps, 6), umodeflags, REJECT_NONE);
33
34 if(!lua_lineok(nickname) || !lua_lineok(ident) || !lua_lineok(hostname) || !lua_lineok(realname) || !lua_lineok(account))
35 return 0;
36
37 l = lua_listfromstate(ps);
38 if(!l)
39 return 0;
40
41 ln = (lua_localnick *)malloc(sizeof(lua_localnick));
42 if(!ln)
43 return 0;
44
45 ln->reconnect = NULL;
46
47 ln->nick = registerlocaluser(nickname, ident, hostname, realname, account, modes, &lua_localnickhandler);
48 if(!ln->nick) {
49 free(ln);
50 return 0;
51 }
52
53 ln->handler = luaL_ref(ps, LUA_REGISTRYINDEX);
54
55 ln->next = l->nicks;
56 l->nicks = ln;
57
58 lua_pushlong(ps, np->numeric);
59 return 1;
60 }
61
62 void lua_freelocalnick(lua_State *ps, lua_localnick *l, char *quitm) {
63 if(l->nick)
64 deregisterlocaluser(l->nick, quitm);
65
66 if(l->reconnect)
67 deleteschedule(l->reconnect, &lua_reconnectlocal, l);
68
69 luaL_unref(ps, LUA_REGISTRYINDEX, l->handler);
70
71 free(l);
72 }
73
74 int lua_getlocalnickbynick(nick *np, lua_list **rl, lua_localnick **rln) {
75 lua_list *l;
76 lua_localnick *ln;
77
78 for(l=lua_head;l;l=l->next)
79 for(ln=l->nicks;ln;ln=ln->next)
80 if(ln->nick == np) {
81 *rl = l;
82 *rln = ln;
83 return 1;
84 }
85
86 return 0;
87 }
88
89 static int lua_deregisterlocaluser(lua_State *ps) {
90 lua_list *l;
91 lua_localnick *l2, *lp = NULL;
92 long numeric;
93 char *quitm;
94
95 if(!lua_islong(ps, 1))
96 LUA_RETURN(ps, LUA_FAIL);
97
98 quitm = lua_isstring(ps, 2)?(char *)lua_tostring(ps, 2):"localuser unregistered.";
99
100 l = lua_listfromstate(ps);
101
102 for(l2=l->nicks;l2;lp=l2,l2=l2->next) {
103 if(l2->nick->numeric == numeric) {
104 lp->next = l2->next;
105 lua_freelocalnick(ps, l2, quitm);
106 LUA_RETURN(ps, LUA_OK);
107 }
108 }
109
110 LUA_RETURN(ps, LUA_FAIL);
111 }
112
113 void lua_deregisternicks(lua_list *l) {
114 struct lua_localnick *ln, *pn;
115
116 for(ln=l->nicks;ln;ln=pn) {
117 pn = ln->next;
118
119 lua_freelocalnick(l->l, ln, "Script unloaded.");
120 }
121
122 l->nicks = NULL;
123 }
124
125 /* todo */
126 void lua_localnickhandler(nick *target, int type, void **args) {
127 nick *np;
128 char *p;
129 lua_localnick *ln;
130 lua_list *l;
131
132 if(!lua_getlocalnickbynick(target, &l, &ln))
133 return;
134
135 switch(type) {
136 case LU_PRIVMSG:
137 np = (nick *)args[0];
138 p = (char *)args[1];
139
140 if(!np || !p)
141 return;
142
143 lua_vlpcall(l, ln, "irc_onmsg", "Ns", np, p);
144
145 break;
146
147 case LU_KILLED:
148 lua_vlpcall(l, ln, "irc_onkilled", "");
149
150 strlcpy(ln->nickname, target->nick, sizeof(ln->nickname));
151 strlcpy(ln->ident, target->ident, sizeof(ln->ident));
152 strlcpy(ln->hostname, target->host->name->content, sizeof(ln->hostname));
153 strlcpy(ln->realname, target->realname->name->content, sizeof(ln->realname));
154 strlcpy(ln->account, target->authname, sizeof(ln->account));
155
156 ln->umodes = target->umodes;
157 ln->nick = NULL;
158
159 ln->reconnect = scheduleoneshot(time(NULL) + 1, &lua_reconnectlocal, ln);
160
161 break;
162 }
163 }
164
165 void lua_reconnectlocal(void *arg) {
166 lua_list *l;
167 lua_localnick *ln = (lua_localnick *)arg;
168
169 ln->nick = registerlocaluser(ln->nickname, ln->ident, ln->hostname, ln->realname, ln->account, ln->umodes, &lua_localnickhandler);
170 if(!ln->nick) {
171 ln->reconnect = scheduleoneshot(time(NULL) + 1, &lua_reconnectlocal, ln);
172 return;
173 }
174
175 ln->reconnect = NULL;
176
177 if(lua_getlocalnickbynick(ln->nick, &l, &ln)) /* hacky! */
178 lua_vlpcall(l, ln, "irc_onkillreconnect", "");
179 }
180
181 static int lua_localjoin(lua_State *ps) {
182 nick *source;
183 channel *target;
184 char *chan;
185
186 if(!lua_islong(ps, 1) || !lua_isstring(ps, 2))
187 LUA_RETURN(ps, LUA_FAIL);
188
189 source = getnickbynumeric(lua_tolong(ps, 1));
190 if(!source)
191 LUA_RETURN(ps, LUA_FAIL);
192
193 chan = (char *)lua_tostring(ps, 2);
194
195 if(!lua_lineok(chan))
196 LUA_RETURN(ps, LUA_FAIL);
197
198 target = findchannel(chan);
199 if(target) {
200 localjoinchannel(source, target);
201 } else {
202 localcreatechannel(lua_nick, chan);
203 }
204
205 LUA_RETURN(ps, LUA_OK);
206 }
207
208 static int lua_localchanmsg(lua_State *ps) {
209 char *msg;
210 nick *source;
211 channel *target;
212
213 if(!lua_islong(ps, 1) || !lua_isstring(ps, 2) || !lua_isstring(ps, 3))
214 LUA_RETURN(ps, LUA_FAIL);
215
216 source = getnickbynumeric(lua_tolong(ps, 1));
217 if(!source)
218 LUA_RETURN(ps, LUA_FAIL);
219
220 target = findchannel((char *)lua_tostring(ps, 2));
221 if(!target)
222 LUA_RETURN(ps, LUA_FAIL);
223
224 msg = (char *)lua_tostring(ps, 3);
225
226 if(!lua_lineok(msg))
227 LUA_RETURN(ps, LUA_FAIL);
228
229 sendmessagetochannel(source, target, "%s", msg);
230
231 LUA_RETURN(ps, LUA_OK);
232 }
233
234 static int lua_localnotice(lua_State *ps) {
235 char *msg;
236 nick *source;
237 nick *target;
238
239 if(!lua_islong(ps, 1) || !lua_islong(ps, 2) || !lua_isstring(ps, 3))
240 LUA_RETURN(ps, LUA_FAIL);
241
242 source = getnickbynumeric(lua_tolong(ps, 1));
243 if(!source)
244 LUA_RETURN(ps, LUA_FAIL);
245
246 target = getnickbynumeric(lua_tolong(ps, 2));
247 if(!target)
248 LUA_RETURN(ps, LUA_FAIL);
249
250 msg = (char *)lua_tostring(ps, 3);
251
252 if(!lua_lineok(msg))
253 LUA_RETURN(ps, LUA_FAIL);
254
255 sendnoticetouser(source, target, "%s", msg);
256
257 LUA_RETURN(ps, LUA_OK);
258 }
259
260 void lua_registerlocalcommands(lua_State *l) {
261 lua_register(l, "irc_localregisteruser", lua_registerlocaluser);
262 lua_register(l, "irc_localderegisteruser", lua_deregisterlocaluser);
263 lua_register(l, "irc_localjoin", lua_localjoin);
264 lua_register(l, "irc_localchanmsg", lua_localchanmsg);
265 lua_register(l, "irc_localnotice", lua_localnotice);
266 }
267