oscarsession.java
来自「基于Jabber协议的即时消息服务器」· Java 代码 · 共 493 行 · 第 1/2 页
JAVA
493 行
/**
* $Revision$
* $Date$
*
* Copyright (C) 2006 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.wildfire.gateway.protocols.oscar;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import net.kano.joscar.ByteBlock;
import net.kano.joscar.net.ConnDescriptor;
import net.kano.joscar.flapcmd.SnacCommand;
import net.kano.joscar.snac.SnacRequest;
import net.kano.joscar.snac.SnacRequestListener;
import net.kano.joscar.snaccmd.ssi.CreateItemsCmd;
import net.kano.joscar.snaccmd.ssi.DeleteItemsCmd;
import net.kano.joscar.snaccmd.ssi.ModifyItemsCmd;
import net.kano.joscar.snaccmd.icbm.SendImIcbm;
import net.kano.joscar.snaccmd.conn.ServiceRequest;
import net.kano.joscar.snaccmd.loc.SetInfoCmd;
import net.kano.joscar.snaccmd.InfoData;
import net.kano.joscar.snaccmd.CapabilityBlock;
import net.kano.joscar.ssiitem.BuddyItem;
import net.kano.joscar.ssiitem.GroupItem;
import org.jivesoftware.util.Log;
import org.jivesoftware.wildfire.gateway.*;
import org.jivesoftware.wildfire.user.UserNotFoundException;
import org.jivesoftware.wildfire.roster.RosterItem;
import org.xmpp.packet.JID;
import org.xmpp.packet.Presence;
import org.xmpp.packet.Message;
import org.xmpp.packet.PacketError;
/**
* Represents an OSCAR session.
*
* This is the interface with which the base transport functionality will
* communicate with OSCAR (AIM/ICQ).
*
* Yeesh, this is the one I'm most familiar with and yet it's the ugliest.
* This needs some housecleaning.
*
* @author Daniel Henninger
*/
public class OSCARSession extends TransportSession {
/**
* Initialize a new session object for OSCAR
*
* @param registration The registration information to use during login.
* @param jid The JID associated with this session.
* @param transport The transport that created this session.
* @param priority Priority of this session.
*/
public OSCARSession(Registration registration, JID jid, OSCARTransport transport, Integer priority) {
super(registration, jid, transport, priority);
}
private BOSConnection bosConn = null;
private LoginConnection loginConn = null;
private Set<ServiceConnection> services = new HashSet<ServiceConnection>();
private PresenceType presenceType = null;
private String verboseStatus = null;
/**
* SSI tracking variables.
*/
private ConcurrentHashMap<String, BuddyItem> buddies = new ConcurrentHashMap<String,BuddyItem>();
private ConcurrentHashMap<Integer, GroupItem> groups = new ConcurrentHashMap<Integer,GroupItem>();
private ConcurrentHashMap<Integer,Integer> highestBuddyIdPerGroup = new ConcurrentHashMap<Integer,Integer>();
private Integer highestGroupId = -1;
public void logIn(PresenceType presenceType, String verboseStatus) {
if (!isLoggedIn()) {
setLoginStatus(TransportLoginStatus.LOGGING_IN);
loginConn = new LoginConnection(new ConnDescriptor("login.oscar.aol.com", 5190), this);
loginConn.connect();
this.presenceType = presenceType;
this.verboseStatus = verboseStatus;
}
else {
Log.warn(this.jid + " is already logged in");
}
}
public synchronized void logOut() {
if (isLoggedIn()) {
setLoginStatus(TransportLoginStatus.LOGGING_OUT);
if (loginConn != null) {
loginConn.disconnect();
loginConn = null;
}
if (bosConn != null) {
bosConn.disconnect();
bosConn = null;
}
for (ServiceConnection conn : getServiceConnections()) {
try {
conn.disconnect();
}
catch (Exception e) {
// Ignore.
}
try {
services.remove(conn);
}
catch (Exception e) {
// Ignore.
}
try {
snacMgr.unregister(conn);
}
catch (Exception e) {
// Ignore.
}
}
Presence p = new Presence(Presence.Type.unavailable);
p.setTo(getJID());
p.setFrom(getTransport().getJID());
getTransport().sendPacket(p);
setLoginStatus(TransportLoginStatus.LOGGED_OUT);
}
}
/**
* Finds the id number of a group specified or creates a new one and returns that id.
*
* @param groupName Name of the group we are looking for.
* @return Id number of the group.
*/
public Integer getGroupIdOrCreateNew(String groupName) {
for (GroupItem g : groups.values()) {
if (groupName.equalsIgnoreCase(g.getGroupName())) {
return g.getId();
}
}
// Group doesn't exist, lets create a new one.
Integer newGroupId = highestGroupId + 1;
GroupItem newGroup = new GroupItem(groupName, newGroupId);
request(new CreateItemsCmd(newGroup.toSsiItem()));
gotGroup(newGroup);
return newGroupId;
}
/**
* Synchronizes the list of groups a contact is a member of, updating nicknames in
* the process.
*
* @param contact Screen name/UIN of the contact.
* @param nickname Nickname of the contact (should not be null)
* @param grouplist List of groups the contact should be a member of.
*/
public void syncContactGroupsAndNickname(String contact, String nickname, List<String> grouplist) {
if (grouplist.isEmpty()) {
grouplist.add("Transport Buddies");
}
Log.debug("contact = "+contact+", grouplist = "+grouplist);
// First, lets take the known good list of groups and sync things up server side.
for (String group : grouplist) {
Integer groupId = getGroupIdOrCreateNew(group);
Integer newBuddyId = 1;
if (highestBuddyIdPerGroup.containsKey(groupId)) {
newBuddyId = highestBuddyIdPerGroup.get(groupId) + 1;
}
BuddyItem newBuddy = new BuddyItem(contact, groupId, newBuddyId);
newBuddy.setAlias(nickname);
request(new CreateItemsCmd(newBuddy.toSsiItem()));
gotBuddy(newBuddy);
}
// Now, lets clean up any groups this contact should no longer be a member of.
for (BuddyItem buddy : buddies.values()) {
if (buddy.getScreenname().equalsIgnoreCase(contact)) {
if (buddy.getGroupId() == 0) {
// Ok this group is the "main group", which we can cheerfully remove from.
// Log.debug("Removing "+buddy+" because of in main group");
// request(new DeleteItemsCmd(buddy.toSsiItem()));
// buddies.remove(""+buddy.getGroupId()+"."+buddy.getId());
}
else if (!groups.containsKey(buddy.getGroupId())) {
// Well this is odd, a group we don't know about? Nuke it.
// Log.debug("Removing "+buddy+" because of unknown group");
// request(new DeleteItemsCmd(buddy.toSsiItem()));
// buddies.remove(""+buddy.getGroupId()+"."+buddy.getId());
}
else if (!grouplist.contains(groups.get(buddy.getGroupId()).getGroupName())) {
// Log.debug("Removing "+buddy+" because not in list of groups");
// request(new DeleteItemsCmd(buddy.toSsiItem()));
// buddies.remove(""+buddy.getGroupId()+"."+buddy.getId());
}
else {
if (buddy.getAlias() == null || !buddy.getAlias().equals(nickname)) {
buddy.setAlias(nickname);
request(new ModifyItemsCmd(buddy.toSsiItem()));
}
}
}
}
}
/**
* @see org.jivesoftware.wildfire.gateway.TransportSession#addContact(org.jivesoftware.wildfire.roster.RosterItem)
*/
public void addContact(RosterItem item) {
String legacyId = getTransport().convertJIDToID(item.getJid());
String nickname = item.getNickname();
if (nickname == null || nickname.equals("")) {
nickname = legacyId;
}
// Syncing takes care of all the dirty work.
syncContactGroupsAndNickname(legacyId, nickname, item.getGroups());
}
/**
* @see org.jivesoftware.wildfire.gateway.TransportSession#removeContact(org.jivesoftware.wildfire.roster.RosterItem)
*/
public void removeContact(RosterItem item) {
// String legacyId = getTransport().convertJIDToID(item.getJid());
// for (BuddyItem i : buddies.values()) {
// if (i.getScreenname().equalsIgnoreCase(legacyId)) {
// request(new DeleteItemsCmd(i.toSsiItem()));
// buddies.remove(""+i.getGroupId()+"."+i.getId());
// }
// }
}
/**
* @see org.jivesoftware.wildfire.gateway.TransportSession#updateContact(org.jivesoftware.wildfire.roster.RosterItem)
*/
public void updateContact(RosterItem item) {
String legacyId = getTransport().convertJIDToID(item.getJid());
String nickname = item.getNickname();
if (nickname == null || nickname.equals("")) {
nickname = legacyId;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?