/*
* Gamers Own Instant Messenger
* Copyright (C) 2005-2006 Herbert Poul (kahless@sphene.net)
* http://goim.sphene.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package net.sphene.goim.components.lfs;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import galena.Kernel;
import galena.addins.modules.database.DB;
import net.sphene.goim.components.ExternalComponentManagerAddin;
import net.sphene.goim.components.lfs.LFSAddin.LFSHost;
import org.dom4j.Element;
import org.xmpp.component.Component;
import org.xmpp.component.ComponentException;
import org.xmpp.component.ComponentManager;
import org.xmpp.forms.DataForm;
import org.xmpp.forms.FormField;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
import org.xmpp.packet.Message;
import org.xmpp.packet.Packet;
import org.xmpp.packet.Presence;
public class LFSComponent implements Component {
public static final String SUBDOMAIN = "lfs";
ExternalComponentManagerAddin manager;
JID componentJID;
DB db;
LFSAddin parent;
Map<String, List<String>> subscriptions = new HashMap<String, List<String>>(); // (key
// =
// lfs
// username,
// List
// of
// jids)
public LFSComponent(ExternalComponentManagerAddin manager, DB db,
LFSAddin addin) {
this.manager = manager;
this.db = db;
this.parent = addin;
}
public String getName() {
return "Live For Speed Online Indicator";
}
public String getDescription() {
return "Allows you to get information about buddies racing in LFS if they don't use Jabber";
}
public void processPacket(Packet packet) {
if(packet instanceof IQ) {
IQ iq = (IQ)packet;
if(iq.getType() == IQ.Type.get || iq.getType() == IQ.Type.set) {
Element element = iq.getChildElement();
if(element.getName().equals("query")) {
IQ result = new IQ(IQ.Type.result,iq.getID());
result.setTo(iq.getFrom());
result.setFrom(iq.getTo());
Element childResult = result.setChildElement(element.getName(),element.getNamespaceURI());
if(element.getNamespaceURI().equals("http://jabber.org/protocol/disco#info")) {
// Element discoResult =
// result.setChildElement("query","http://jabber.org/protocol/disco#info");
Element identity = childResult.addElement("identity");
identity.addAttribute("category","gateway");
identity.addAttribute("type","lfs");
identity.addAttribute("name",getName());
Element feature = childResult.addElement("feature");
feature.addAttribute("var","http://jabber.org/protocol/disco");
feature = childResult.addElement("feature");
feature.addAttribute("var","jabber:iq:register");
feature = childResult.addElement("feature");
feature.addAttribute("var","jabber:iq:gateway");
manager.sendPacket(this,result);
} else if(element.getNamespaceURI().equals("http://jabber.org/protocol/disco#items")) {
// Element discoResult =
// result.setChildElement("query","http://jabber.org/protocol/disco#items");
} else if(element.getNamespaceURI().equals("jabber:iq:gateway")) {
if(iq.getType() == IQ.Type.get) {
Element desc = childResult.addElement("desc");
desc.setText("Enter the users LFS username");
childResult.addElement("prompt");
} else if(iq.getType() == IQ.Type.set) {
Element promptInput = element.element("prompt");
String jid = promptInput.getText() + "@" + componentJID.toString();
childResult.addElement("prompt").setText(jid);
childResult.addElement("jid").setText(jid); // JEP-0100
// says
// it
// should
// be
// <jid>xxx</jid>
// but
// the
// PyICQ
// returns
// <prompt>xxx</prompt>
}
} else if(element.getNamespaceURI().equals("jabber:iq:register")) {
Map<String, Object> registration = getRegistration(iq.getFrom());
if(iq.getType() == IQ.Type.get) {
DataForm form = new DataForm(DataForm.Type.form);
form.setTitle("Enter Your LFS Username");
form.addInstruction("Enter Your LFS Username");
FormField username = form.addField();
username.setVariable("username");
username.setLabel("LFS Username");
username.setType(FormField.Type.text_single);
username.setRequired(true);
username.setDescription("Your LFS Username");
childResult.add(form.getElement());
childResult.addElement("instructions").addText("Enter Your LFS Username");
Element username_element = childResult.addElement("username");
if(registration != null) {
username_element.setText((String) registration.get("username"));
username.addValue(registration.get("username"));
}
} else if(iq.getType() == IQ.Type.set) {
String username = null;
DataForm form = (DataForm)iq.getExtension(DataForm.ELEMENT_NAME,DataForm.NAMESPACE);
if(form != null) {
List<FormField> fields = form.getFields();
for(FormField field : fields) {
if(!field.getVariable().equals("username")) continue;
List<String> vals = field.getValues();
if(vals != null && vals.size() > 0)
username = vals.get(0);
}
}
if(username == null)
username = iq.getChildElement().element("username").getText();
if(username == null)
result.setType(IQ.Type.error);
else {
if(registration == null)
db.sendInsert(null,"goim_component_registrations","subdomain,jid,username,password",getSubdomain(),iq.getFrom().toBareJID(),username,"");
else
db.sendUpdate(null,"goim_component_registrations","username=?,password=?",new Object[]{username,""},"id=?",registration.get("id"));
Presence presence = new Presence(Presence.Type.subscribe);
presence.setTo(iq.getFrom());
presence.setFrom(componentJID);
manager.sendPacket(this,presence);
}
}
} else
result = null;
if(result != null)
manager.sendPacket(this,result);
}
}
} else if(packet instanceof Presence) {
Presence presence = (Presence)packet;
if(presence.getTo().equals(componentJID)) {
Kernel.debug(this,"Presence packet to: " + packet.getTo().toString() + " .. type: " + presence.getType(),3);
if(presence.getType() == null || presence.getType() == Presence.Type.probe) { // available
Presence reply = new Presence();
reply.setTo(presence.getFrom());
reply.setFrom(presence.getTo());
manager.sendPacket(this,reply);
} else if(presence.getType() == Presence.Type.subscribe) {
Presence reply = new Presence(Presence.Type.subscribed);
reply.setTo(presence.getFrom());
reply.setFrom(presence.getTo());
manager.sendPacket(this,reply);
}
} else {
if(presence.getType() == Presence.Type.subscribe) {
Presence reply = new Presence(Presence.Type.subscribed);
reply.setTo(presence.getFrom());
reply.setFrom(presence.getTo());
manager.sendPacket(this,reply);
addSubscription(presence.getFrom().toBareJID(),presence.getTo().getNode());
} else if(presence.getType() == null || presence.getType() == Presence.Type.probe) { // available
// Kernel.debug(this,"Available presence packet to: " +
// presence.getTo().toString(),2);
if(presence.getType() == Presence.Type.probe) {
Presence reply = new Presence(Presence.Type.unavailable);
reply.setTo(presence.getFrom());
reply.setFrom(presence.getTo());
manager.sendPacket(this,reply);
}
addSubscription(presence.getFrom().toBareJID(),presence.getTo().getNode());
}
}
} else if(packet instanceof Message) {
Message message = (Message)packet;
if(message.getBody().startsWith("show")) {
Message reply = new Message();
reply.setTo(message.getFrom());
reply.setFrom(message.getTo());
reply.setType(message.getType());
reply.setThread(message.getThread());
StringBuffer subs = new StringBuffer("Your Subscriptions:\n");
for(String lfsusername : subscriptions.keySet()) {
List<String> jids = subscriptions.get(lfsusername.toLowerCase());
if(jids == null) continue;
if(jids.contains(message.getFrom().toBareJID()))
subs.append("- ").append(lfsusername).append("\n");
}
reply.setBody(subs.toString());
manager.sendPacket(this,reply);
}
} else
Kernel.debug(this,"Received packet: " + packet.getClass().toString() + " " + packet.toXML(),2);
}
protected void addSubscription(String jid, String lfsusername) {
lfsusername = EscapingJEP0106.decode(lfsusername);
List<String> s = subscriptions.get(lfsusername.toLowerCase());
if (s == null)
subscriptions.put(lfsusername.toLowerCase(),
s = new ArrayList<String>());
if (!s.contains(jid))
s.add(jid);
LFSHost host = parent.getHostOf(lfsusername);
if (host != null) {
JID from = new JID(lfsusername, componentJID.getDomain(), null);
sendPresence(from, jid, lfsusername, host);
}
}
protected String getSubdomain() {
return SUBDOMAIN;
}
protected Map<String, Object> getRegistration(JID jid) {
List<Map<String, Object>> list = db
.getListOfMaps(
"SELECT * FROM goim_component_registrations WHERE subdomain = ? AND jid = ?",
getSubdomain(), jid.toBareJID());
if (list.size() < 1)
return null;
return list.get(0);
}
public void initialize(JID jid, ComponentManager componentManager)
throws ComponentException {
if (!jid.toString().startsWith(getSubdomain()))
componentJID = new JID(getSubdomain() + "." + jid);
else
componentJID = jid;
Kernel.debug(this, "Initialize with JID: " + jid.toString()
+ " custom: " + componentJID.toString(), 3);
}
public void start() {
Kernel.debug(this, "start()", 3);
}
public void shutdown() {
Kernel.debug(this, "debug()", 3);
}
public void sendPresence(JID from, String jid, String lfsusername,
LFSHost host) {
Presence presence = new Presence();
presence.setFrom(from);
presence.setTo(new JID(jid));
presence.setShow(Presence.Show.away);
String servername = host.name.replaceAll("\\^\\d", "");
presence.setStatus("Playing on server " + servername + " with "
+ host.nrofracers + " other racers. (Servername with colors: "
+ host.name + ")");
Element x = presence.addChildElement("x",
"http://goim.sphene.net/gameStatus");
x.addAttribute("game", "lfss2");
x.addAttribute("target", "127.0.0.1:100"); // We need to add a dummy
// target.
x.addAttribute("servername", host.name);
manager.sendPacket(this, presence);
}
public void joinedHost(String lfsusername, LFSHost host) {
List<String> jids = subscriptions.get(lfsusername.toLowerCase());
if (jids == null)
return;
JID from = new JID(lfsusername, componentJID.getDomain(), null);
for (String jid : jids) {
sendPresence(from, jid, lfsusername, host);
}
}
public void changedHost(String lfsusername, LFSHost oldHost, LFSHost host) {
joinedHost(lfsusername, host);
}
public void left(String lfsusername, LFSHost host) {
List<String> jids = subscriptions.get(lfsusername.toLowerCase());
if (jids == null)
return;
JID from = new JID(lfsusername, componentJID.getDomain(), null);
for (String jid : jids) {
Presence presence = new Presence(Presence.Type.unavailable);
presence.setFrom(from);
presence.setTo(new JID(jid));
manager.sendPacket(this, presence);
}
}
}