luacomponent.cpp

1
// g++ -Wall -O2 -pipe -march=i686 "%f" /usr/local/lib/libgloox.so /usr/lib/liblua5.1.so
2
#include </usr/local/include/gloox/gloox.h>
3
#include </usr/local/include/gloox/client.h>
4
#include </usr/local/include/gloox/clientbase.h>
5
#include </usr/local/include/gloox/messagehandler.h>
6
#include </usr/local/include/gloox/tag.h>
7
#include </usr/local/include/gloox/stanza.h>
8
#include </usr/local/include/gloox/connectionlistener.h>
9
#include </usr/local/include/gloox/presencehandler.h>
10
#include </usr/local/include/gloox/component.h>
11
 
12
extern "C" {
13
#include <lua.h>
14
#include <lualib.h>
15
#include <lauxlib.h>
16
}
17
 
18
using namespace gloox;
19
 
20
lua_State *L = NULL;
21
lua_State *calcL = NULL;
22
char BotName[26];
23
class Bot* theBot = NULL;
24
 
25
int lcJoinMUC(lua_State* L);
26
int lcSleep(lua_State* L);
27
int lcMemUsage(lua_State* L);
28
int lcSendPresence(lua_State* L);
29
int lcSendMessage(lua_State* L);
30
 
31
class Bot : public MessageHandler, ConnectionListener , PresenceHandler, LogHandler
32
{
33
 public:
34
   Bot()
35
   {
36
   	::theBot = this;
37
   	lua_getglobal(L, "BotPass");
38
	if(!lua_isstring(L, -1))
39
	{
40
		printf("Please, in the body of the script, set BotJID, BotPass, and BotName!\n");
41
		return;
42
	}
43
      // JID jid( lua_tostring(L, -3) );
44
      j = new Component ( "jabber:component:accept", "localhost", "xmoo", "secret", 5347);
45
 
46
      j->registerConnectionListener( this );
47
      j->registerMessageHandler( this );
48
      j->registerPresenceHandler( this );
49
      j->logInstance().registerLogHandler( LogLevelDebug, LogAreaAll, this );
50
      // j->setInitialPriority( 5 );
51
      // j->setAutoPresence( true );
52
      printf("Connecting...\n");
53
      j->connect();
54
   }
55
 
56
   virtual void handleMessage( Stanza *stanza, MessageSession *session )
57
   {
58
		if(stanza->findChildWithAttrib("xmlns","jabber:x:delay"))
59
		{
60
			printf("History message, ignoring.\n");
61
			return;
62
		}
63
		
64
		printf("Message.\n");
65
			    /* push functions and arguments */
66
		lua_getglobal(L, "onMessage");  /* function to be called */
67
		if(!lua_isfunction(L, -1))
68
		{
69
			printf("Unhandled message... please add an onMessage function to the script\n");
70
			return;
71
		}
72
		lua_newtable(L);
73
		lua_pushstring(L, stanza->body().c_str());
74
		lua_setfield(L,-2, "body");
75
		lua_pushstring(L, stanza->from().full().c_str());
76
		lua_setfield(L,-2, "fromFull");
77
		lua_pushstring(L, stanza->from().bare().c_str());
78
		lua_setfield(L,-2, "fromBare");
79
		lua_pushstring(L, stanza->to().full().c_str());
80
		lua_setfield(L,-2, "to");
81
		lua_pushnumber(L, stanza->subtype());
82
		lua_setfield(L,-2, "type");
83
	
84
		/* do the call (1 argument, 1 result) */
85
		if (lua_pcall(L, 1, 1, 0) != 0)
86
		{
87
			printf("Error running function `onMessage': %s",lua_tostring(L, -1));
88
			return;
89
		}
90
		if(lua_istable(L, -1))
91
		{
92
			Tag *t = new Tag( "message" );
93
			
94
			lua_getfield(L, -1, "type");
95
			t->addAttribute( "type", luaL_optlstring(L, -1, "chat", NULL) );
96
			lua_pop(L,1);
97
			lua_getfield(L, -1, "to");
98
			t->addAttribute( "to", luaL_optlstring(L, -1, stanza->from().bare().c_str(), NULL )); // 
99
			lua_pop(L,1);
100
			lua_getfield(L, -1, "from");
101
			t->addAttribute( "from", luaL_optlstring(L, -1, j->jid().full().c_str(), NULL ));
102
			lua_pop(L,1);
103
			lua_getfield(L, -1, "body");
104
			t->addChild( new Tag( "body", luaL_optlstring(L, -1, "", NULL) ) );
105
			lua_pop(L,1);
106
			j->send( t ); // Send it!
107
		}
108
	
109
		
110
	}
111
   
112
	virtual void onConnect()
113
	{
114
		// do something when the connection is established
115
	printf("Connecting...");
116
	if(L)
117
	{
118
		lua_pushinteger(L, StanzaMessageChat);
119
		lua_setglobal(L, "MSG_CHAT");
120
		lua_pushinteger(L, StanzaMessageGroupchat);
121
		lua_setglobal(L, "MSG_GROUPCHAT");
122
		lua_pushinteger(L, StanzaMessageNormal);
123
		lua_setglobal(L, "MSG_NORMAL");
124
		lua_pushinteger(L, StanzaMessageError);
125
		lua_setglobal(L, "MSG_ERROR");
126
		
127
		lua_pushinteger(L, StanzaPresenceError);
128
		lua_setglobal(L, "PRE_ERROR");
129
		lua_pushinteger(L, StanzaPresenceAvailable);
130
		lua_setglobal(L, "PRE_AVAILABLE");
131
		lua_pushinteger(L, StanzaPresenceUnavailable);
132
		lua_setglobal(L, "PRE_UNAVAILABLE");
133
 
134
		lua_register(L, "JoinMUC", lcJoinMUC);
135
		lua_register(L, "Sleep", lcSleep);
136
		lua_register(L, "MemUsage", lcMemUsage);
137
		lua_register(L, "SendPresence", lcSendPresence);
138
		lua_register(L, "SendMessage", lcSendMessage);
139
	}
140
	else
141
		printf("Lua not loaded?!\n");
142
	
143
	 printf("Connected.\n");
144
	 
145
	 		lua_getglobal(L, "onConnect");  /* function to be called */
146
		if(!lua_isfunction(L, -1))
147
		{
148
			printf("No onConnect() function found.\n");
149
			return;
150
		}
151
		
152
		/*Tag *t = new Tag( "presence" );
153
		t->addAttribute( "to", "test@conference.jabber.org/Betty" );
154
		t->addChild(new Tag( "status", "Betty!" ) );
155
		j->send( t ); */
156
	
157
		/* do the call (0 arguments, 0 results) */
158
		if (lua_pcall(L, 0, 0, 0) != 0)
159
			return; // error(L, "error running function `f': %s",lua_tostring(L, -1));
160
     
161
	}
162
	
163
	virtual void handlePresence( Stanza * stanza)
164
	{
165
				printf("Presence.\n");
166
			    /* push functions and arguments */
167
		lua_getglobal(L, "onPresence");  /* function to be called */
168
		if(!lua_isfunction(L, -1))
169
			return;
170
			
171
		lua_newtable(L);
172
		lua_pushstring(L, stanza->body().c_str());
173
		lua_setfield(L,-2, "body");
174
		lua_pushstring(L, stanza->from().full().c_str());
175
		lua_setfield(L,-2, "fromFull");
176
		lua_pushstring(L, stanza->from().bare().c_str());
177
		lua_setfield(L,-2, "fromBare");
178
		lua_pushstring(L, stanza->to().full().c_str());
179
		lua_setfield(L,-2, "to");
180
		lua_pushnumber(L, stanza->subtype());
181
		lua_setfield(L,-2, "ntype");
182
		lua_pushstring(L, stanza->findAttribute("type").c_str());
183
		lua_setfield(L,-2, "type");
184
		
185
		
186
	
187
		/* do the call (1 arguments, 0 results) */
188
		if (lua_pcall(L, 1, 0, 0) != 0)
189
		{
190
			printf("Error running function `onPresence': %s",lua_tostring(L, -1));
191
			return;
192
		}
193
		return;
194
	}
195
 
196
	virtual bool onTLSConnect( const CertInfo& info )
197
	{
198
		// decide whether you trust the certificate, examine the CertInfo structure
199
		// It's not like a bot is bothered with this :)
200
		return true; // if you trust it, otherwise return false
201
	}
202
	
203
	virtual void onDisconnect(gloox::ConnectionError e)
204
	{
205
		std::string msg;
206
		if (e == ConnStreamError)
207
		{
208
			
209
		}
210
		switch(e)
211
		{
212
			case ConnStreamError:
213
				msg = j->streamErrorText();
214
				break;
215
			case ConnIoError:
216
				msg = "An I/O error occured";
217
				break;
218
			default:
219
				msg = "Unknown error";
220
		}
221
		printf("Disconnected: %s\n", msg.c_str());
222
	}
223
	
224
	virtual void handleLog( LogLevel level, LogArea area, const std::string & message)
225
	{
226
		printf("Log: %s\n", message.c_str());
227
	}	
228
	
229
 public:
230
   Component* j;
231
};
232
 
233
 
234
int main( int argc, char* argv[] )
235
{
236
	L = lua_open();   /* opens Lua */
237
	if(L == NULL)
238
	{
239
		printf("Unable to initialize Lua.\n");
240
		exit(1);
241
	}
242
	else
243
	{
244
		
245
	}
246
	luaL_openlibs(L);
247
	if(luaL_dofile(L, "bot.lua"))
248
	{
249
		printf("Unable to load/run the bot file\n\t%s\n", lua_tostring(L, -1));
250
		exit(1);
251
	}
252
	else
253
		printf("File loaded successfully.\n");
254
	
255
	Bot b;
256
}
257
 
258
int lcJoinMUC(lua_State* L)
259
{
260
	printf("Joining MUC...\n");
261
	if(!lua_isstring(L,1))
262
	{
263
		printf("Ooops, not passed a string :(\n");
264
		return 0;
265
	}
266
	Tag *t = new Tag( "presence" );
267
	t->addAttribute( "to", lua_tostring(L, 1) );
268
	if (lua_isstring(L, 2))
269
		t->addAttribute( "type", lua_tostring(L, 2) );
270
	
271
	// t->addChild("status", "Betty!");
272
	t->addChild(new Tag( "status", "" ) );
273
	printf(t->xml().c_str() );
274
	theBot->j->send( t );
275
	// 
276
	printf("Conference (%s) joined.\n",lua_tostring(L, 1));
277
	return 0;
278
}
279
 
280
int lcLeaveMUC(lua_State* L)
281
{
282
	if(!lua_isstring(L,1))
283
	{
284
		printf("Ooops, not passed a string :(\n");
285
		return 0;
286
	}
287
	Tag *t = new Tag( "presence" );
288
	t->addAttribute( "to", lua_tostring(L, 1) );
289
	t->addAttribute( "type", "unavailable" );
290
	t->addChild(new Tag( "status", "" ) );
291
	theBot->j->send( t );
292
	printf("Conference (%s) joined.\n",lua_tostring(L, 1));
293
	return 0;
294
}
295
 
296
int lcSleep(lua_State* L)
297
{
298
	sleep((int)lua_tonumber(L, 1));
299
	return 0;
300
}	
301
 
302
int lcMemUsage(lua_State* L)
303
{
304
	lua_pushinteger(L, lua_gc(L, LUA_GCCOUNT, 0));
305
	return 1;
306
}
307
 
308
// function SendPresence(to, type, text[, from]);
309
int lcSendPresence(lua_State* L)
310
{
311
	if(!lua_isstring(L,1))
312
	{
313
		printf("Ooops, not passed a string :(\n");
314
		// lua_error(L, 
315
		return 0;
316
	}
317
	Tag *t = new Tag( "presence" );
318
	t->addAttribute( "to", lua_tostring(L, 1) );
319
	if (lua_isstring(L, 2))
320
		t->addAttribute( "type", lua_tostring(L, 2) );
321
	else
322
		t->addAttribute( "type", "available" );
323
	
324
	if (lua_isstring(L, 3))
325
		t->addChild(new Tag( "status", lua_tostring(L, 3) ) );	
326
	else
327
		t->addChild(new Tag( "status", "" ) );
328
	
329
	if (lua_isstring(L, 4))
330
		t->addAttribute( "from", lua_tostring(L, 4) );
331
	
332
	t->addChild(new Tag("x", "xmlns", "http://jabber.org/protocol/muc#user"));
333
			
334
	theBot->j->send( t );
335
	return 0;
336
}
337
 
338
int lcSendMessage(lua_State* L)
339
{
340
	if(!lua_isstring(L,1))
341
	{
342
		printf("Ooops, not passed a string :(\n");
343
		// lua_error(L, 
344
		return 0;
345
	}
346
	Tag *t = new Tag( "message" );
347
	t->addAttribute( "to", lua_tostring(L, 1) );
348
	
349
	if (lua_isstring(L, 2))
350
		t->addAttribute( "from", lua_tostring(L, 2) );
351
	
352
	if (lua_isstring(L, 3))
353
		t->addChild(new Tag( "body", lua_tostring(L, 3) ) );	
354
	else
355
		t->addChild(new Tag( "body", "" ) );
356
	
357
	if (lua_isstring(L, 4))
358
		t->addAttribute( "type", lua_tostring(L, 4) );
359
	else
360
		t->addAttribute( "type", "normal" );
361
	
362
			
363
	theBot->j->send( t );
364
	return 0;
365
}