summaryrefslogtreecommitdiffstats
path: root/Sluift
diff options
context:
space:
mode:
Diffstat (limited to 'Sluift')
-rw-r--r--Sluift/client_test.lua32
-rw-r--r--Sluift/linit.c40
-rw-r--r--Sluift/sluift.cpp114
3 files changed, 146 insertions, 40 deletions
diff --git a/Sluift/client_test.lua b/Sluift/client_test.lua
new file mode 100644
index 0000000..afb8147
--- /dev/null
+++ b/Sluift/client_test.lua
@@ -0,0 +1,32 @@
+require "sluift"
+
+--sluift.debug = true
+client1_jid = os.getenv("SWIFT_CLIENTTEST_JID") .. "/Client1"
+client2_jid = os.getenv("SWIFT_CLIENTTEST_JID") .. "/Client2"
+password = os.getenv("SWIFT_CLIENTTEST_PASS")
+
+print "Connecting client 1"
+client1 = sluift.connect(client1_jid, password)
+client1:send_presence("I'm here")
+
+print "Connecting client 2"
+client2 = sluift.connect(client2_jid, password)
+client2:send_presence("I'm here")
+
+print "Checking version of client 2 from client 1"
+client2:set_version({name = "Sluift Test", version = "1.0"})
+client2_version = client1:get_version(client2_jid)
+assert(client2_version["name"] == "Sluift Test")
+assert(client2_version["version"] == "1.0")
+
+print "Sending message from client 1 to client 2"
+client1:send_message(client2_jid, "Hello")
+received_message = client2:for_event(function(event)
+ if event["type"] == "message" and event["from"] == client1_jid then
+ return event["body"]
+ end
+ end)
+assert(received_message == "Hello")
+
+client1:disconnect()
+client2:disconnect()
diff --git a/Sluift/linit.c b/Sluift/linit.c
deleted file mode 100644
index 4cb4c26..0000000
--- a/Sluift/linit.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $
-** Initialization of libraries for lua.c
-** See Copyright Notice in lua.h
-*/
-
-
-#define linit_c
-#define LUA_LIB
-
-#include "lua.h"
-
-#include "lualib.h"
-#include "lauxlib.h"
-#include "sluift.h"
-
-
-static const luaL_Reg lualibs[] = {
- {"", luaopen_base},
- {LUA_LOADLIBNAME, luaopen_package},
- {LUA_TABLIBNAME, luaopen_table},
- {LUA_IOLIBNAME, luaopen_io},
- {LUA_OSLIBNAME, luaopen_os},
- {LUA_STRLIBNAME, luaopen_string},
- {LUA_MATHLIBNAME, luaopen_math},
- {LUA_DBLIBNAME, luaopen_debug},
- {"sluift", luaopen_sluift},
- {NULL, NULL}
-};
-
-
-LUALIB_API void luaL_openlibs (lua_State *L) {
- const luaL_Reg *lib = lualibs;
- for (; lib->func; lib++) {
- lua_pushcfunction(L, lib->func);
- lua_pushstring(L, lib->name);
- lua_call(L, 1, 0);
- }
-}
-
diff --git a/Sluift/sluift.cpp b/Sluift/sluift.cpp
index 5a9fbd5..895d90d 100644
--- a/Sluift/sluift.cpp
+++ b/Sluift/sluift.cpp
@@ -11,6 +11,7 @@ extern "C" {
#include <iostream>
#include <string>
+#include <deque>
#include <Swiften/Client/Client.h>
#include <Swiften/Client/ClientXMLTracer.h>
@@ -51,6 +52,8 @@ class SluiftClient {
SluiftClient(const JID& jid, const std::string& password, bool debug = false) : tracer(NULL) {
client = new Client(jid, password, &networkFactories);
client->setAlwaysTrustCertificates();
+ client->onMessageReceived.connect(boost::bind(&SluiftClient::handleIncomingEvent, this, _1));
+ client->onPresenceReceived.connect(boost::bind(&SluiftClient::handleIncomingEvent, this, _1));
if (debug) {
tracer = new ClientXMLTracer(client);
}
@@ -79,6 +82,10 @@ class SluiftClient {
client->sendMessage(message);
}
+ void sendPresence(const std::string& status) {
+ client->sendPresence(boost::make_shared<Presence>(status));
+ }
+
void disconnect() {
client->disconnect();
while (client->isActive()) {
@@ -86,6 +93,10 @@ class SluiftClient {
}
}
+ void setSoftwareVersion(const std::string& name, const std::string& version, const std::string& os) {
+ client->setSoftwareVersion(name, version, os);
+ }
+
boost::optional<SoftwareVersion> getSoftwareVersion(const JID& jid) {
GetSoftwareVersionRequest::ref request = GetSoftwareVersionRequest::create(jid, client->getIQRouter());
request->onResponse.connect(boost::bind(&SluiftClient::handleSoftwareVersionResponse, this, _1, _2));
@@ -98,7 +109,31 @@ class SluiftClient {
return softwareVersion;
}
+ Stanza::ref getNextEvent() {
+ if (client->isActive() && !pendingEvents.empty()) {
+ Stanza::ref event = pendingEvents.front();
+ pendingEvents.pop_front();
+ return event;
+ }
+ while (client->isActive() && pendingEvents.empty()) {
+ processEvents();
+ }
+ if (client->isActive()) {
+ assert(!pendingEvents.empty());
+ Stanza::ref event = pendingEvents.front();
+ pendingEvents.pop_front();
+ return event;
+ }
+ else {
+ return Stanza::ref();
+ }
+ }
+
private:
+ void handleIncomingEvent(Stanza::ref stanza) {
+ pendingEvents.push_back(stanza);
+ }
+
void processEvents() {
eventLoop.runUntilEvents();
}
@@ -120,6 +155,7 @@ class SluiftClient {
ClientXMLTracer* tracer;
boost::optional<SoftwareVersion> softwareVersion;
ErrorPayload::ref error;
+ std::deque<Stanza::ref> pendingEvents;
};
@@ -141,6 +177,19 @@ static int sluift_client_disconnect(lua_State *L) {
return 0;
}
+static int sluift_client_set_version(lua_State *L) {
+ SluiftClient* client = getClient(L);
+ luaL_checktype(L, 2, LUA_TTABLE);
+ lua_getfield(L, 2, "name");
+ const char* rawName = lua_tostring(L, -1);
+ lua_getfield(L, 2, "version");
+ const char* rawVersion = lua_tostring(L, -1);
+ lua_getfield(L, 2, "os");
+ const char* rawOS = lua_tostring(L, -1);
+ client->setSoftwareVersion(rawName ? rawName : "", rawVersion ? rawVersion : "", rawOS ? rawOS : "");
+ lua_pop(L, 3);
+ return 0;
+}
static int sluift_client_get_version(lua_State *L) {
SluiftClient* client = getClient(L);
@@ -167,6 +216,68 @@ static int sluift_client_send_message(lua_State *L) {
return 0;
}
+static int sluift_client_send_presence(lua_State *L) {
+ getClient(L)->sendPresence(std::string(luaL_checkstring(L, 2)));
+ return 0;
+}
+
+static int sluift_client_for_event (lua_State *L) {
+ SluiftClient* client = getClient(L);
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+ while (true) {
+ Stanza::ref event = client->getNextEvent();
+ if (!event) {
+ // We got disconnected
+ lua_pushnil(L);
+ lua_pushliteral(L, "disconnected");
+ return 2;
+ }
+ else {
+ // Push the function on the stack
+ lua_pushvalue(L, 2);
+
+ bool emitEvent = false;
+ if (Message::ref message = boost::dynamic_pointer_cast<Message>(event)) {
+ lua_createtable(L, 0, 3);
+ lua_pushliteral(L, "message");
+ lua_setfield(L, -2, "type");
+ lua_pushstring(L, message->getFrom().toString().c_str());
+ lua_setfield(L, -2, "from");
+ lua_pushstring(L, message->getBody().c_str());
+ lua_setfield(L, -2, "body");
+ emitEvent = true;
+ }
+ else if (Presence::ref presence = boost::dynamic_pointer_cast<Presence>(event)) {
+ lua_createtable(L, 0, 3);
+ lua_pushliteral(L, "presence");
+ lua_setfield(L, -2, "type");
+ lua_pushstring(L, presence->getFrom().toString().c_str());
+ lua_setfield(L, -2, "from");
+ lua_pushstring(L, presence->getStatus().c_str());
+ lua_setfield(L, -2, "status");
+ emitEvent = true;
+ }
+ else {
+ assert(false);
+ }
+ if (emitEvent) {
+ int oldTop = lua_gettop(L) - 2;
+ lua_call(L, 1, LUA_MULTRET);
+ int returnValues = lua_gettop(L) - oldTop;
+ if (returnValues > 0) {
+ lua_remove(L, -1 - returnValues);
+ return returnValues;
+ }
+ }
+ else {
+ // Remove the function from the stack again, since
+ // we're not calling the function
+ lua_pop(L, 1);
+ }
+ }
+ }
+}
+
static int sluift_client_gc (lua_State *L) {
SluiftClient* client = getClient(L);
delete client;
@@ -178,7 +289,10 @@ static const luaL_reg sluift_client_functions[] = {
{"is_connected", sluift_client_is_connected},
{"disconnect", sluift_client_disconnect},
{"send_message", sluift_client_send_message},
+ {"send_presence", sluift_client_send_presence},
+ {"set_version", sluift_client_set_version},
{"get_version", sluift_client_get_version},
+ {"for_event", sluift_client_for_event},
{"__gc", sluift_client_gc},
{NULL, NULL}
};