package edu.tufts.vue.collab.im;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.StringTokenizer;
import java.util.Timer;
import java.util.TimerTask;
import java.util.TreeMap;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import edu.tufts.vue.collab.im.*;
import edu.tufts.vue.collab.im.security.SecureSession;
import edu.tufts.vue.collab.im.security.SecureSessionException;
import sun.net.ProgressSource.State;
import tufts.vue.VueResources;
import tufts.vue.VueUtil;
import net.kano.joscar.ByteBlock;
import net.kano.joscar.FileWritable;
import net.kano.joscar.OscarTools;
import net.kano.joscar.flap.ClientFlapConn;
import net.kano.joscar.flapcmd.SnacCommand;
import net.kano.joscar.net.ClientConnListener;
import net.kano.joscar.rv.RvSession;
import net.kano.joscar.rvcmd.InvitationMessage;
import net.kano.joscar.rvcmd.RvConnectionInfo;
import net.kano.joscar.rvcmd.chatinvite.ChatInvitationRvCmd;
import net.kano.joscar.rvcmd.directim.DirectIMReqRvCmd;
import net.kano.joscar.rvcmd.getfile.GetFileReqRvCmd;
import net.kano.joscar.rvcmd.sendbl.SendBuddyListGroup;
import net.kano.joscar.rvcmd.sendbl.SendBuddyListRvCmd;
import net.kano.joscar.rvcmd.sendfile.FileSendBlock;
import net.kano.joscar.rvcmd.sendfile.FileSendReqRvCmd;
import net.kano.joscar.rvcmd.trillcrypt.TrillianCryptReqRvCmd;
import net.kano.joscar.rvcmd.voice.VoiceReqRvCmd;
import net.kano.joscar.snac.ClientSnacProcessor;
import net.kano.joscar.snac.SnacRequest;
import net.kano.joscar.snac.SnacRequestListener;
import net.kano.joscar.snaccmd.DefaultClientFactoryList;
import net.kano.joscar.snaccmd.DirInfo;
import net.kano.joscar.snaccmd.ExtraInfoBlock;
import net.kano.joscar.snaccmd.ExtraInfoData;
import net.kano.joscar.snaccmd.FullRoomInfo;
import net.kano.joscar.snaccmd.FullUserInfo;
import net.kano.joscar.snaccmd.MiniRoomInfo;
import net.kano.joscar.snaccmd.acct.AcctInfoRequest;
import net.kano.joscar.snaccmd.acct.AcctModCmd;
import net.kano.joscar.snaccmd.acct.ConfirmAcctCmd;
import net.kano.joscar.snaccmd.chat.ChatMsg;
import net.kano.joscar.snaccmd.conn.ServiceRequest;
import net.kano.joscar.snaccmd.conn.SetExtraInfoCmd;
import net.kano.joscar.snaccmd.icbm.InstantMessage;
import net.kano.joscar.snaccmd.icbm.OldIconHashInfo;
import net.kano.joscar.snaccmd.icbm.SendImIcbm;
import net.kano.joscar.snaccmd.icon.UploadIconCmd;
import net.kano.joscar.snaccmd.invite.InviteFriendCmd;
import net.kano.joscar.snaccmd.loc.GetDirInfoCmd;
import net.kano.joscar.snaccmd.loc.GetInfoCmd;
import net.kano.joscar.snaccmd.loc.SetDirInfoCmd;
import net.kano.joscar.snaccmd.loc.SetInterestsCmd;
import net.kano.joscar.snaccmd.rooms.ExchangeInfoReq;
import net.kano.joscar.snaccmd.rooms.JoinRoomCmd;
import net.kano.joscar.snaccmd.rooms.RoomRightsRequest;
import net.kano.joscar.snaccmd.search.InterestListReq;
import net.kano.joscar.snaccmd.search.SearchBuddiesCmd;
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.ssi.SsiItem;
import net.kano.joscar.ssiitem.BuddyItem;
import net.kano.joscar.ssiitem.DenyItem;
import net.kano.joscar.ssiitem.GroupItem;
import net.kano.joscar.ssiitem.IconItem;
import net.kano.joscar.ssiitem.PermitItem;
import net.kano.joscar.ssiitem.PrivacyItem;
import net.kano.joscar.ssiitem.RootItem;
import net.kano.joscar.ssiitem.VisibilityItem;
public class VUEAim {
protected LoginConn loginConn = null;
protected static final int DEFAULT_SERVICE_PORT = 5190;
protected DefaultClientFactoryList factoryList
= new DefaultClientFactoryList();
protected ClientFlapConn loginFlapConn = null, mainConn = null;
protected ClientSnacProcessor loginSnacProcessor = null;
protected List serviceConns = new ArrayList();
protected String sn = null;
protected String pass = null;
protected boolean ignoreIMs = false;
protected boolean requireApproval = true;
protected boolean assignColors = false;
protected boolean forceNodeWidth = false;
protected boolean makeTables = false;
protected boolean keepAt100 =false;
protected BosFlapConn bosConn = null;
protected Set services = new HashSet();
protected Map chats = new HashMap();
private ClientConnListener connListener = null;
private SecureSession secureSession = SecureSession.getInstance();
public VUEAim(String username, String password)
{
ConsoleHandler handler = new ConsoleHandler();
handler.setLevel(Level.OFF);
Logger logger = Logger.getLogger("net.kano.joscar");
logger.addHandler(handler);
logger.setLevel(Level.OFF);
this.sn = username;
this.pass = password;
}
public void connect()
{
if (loginConn == null)
loginConn = new LoginConn("login.oscar.aol.com", DEFAULT_SERVICE_PORT, this);
loginConn.connect();
//connected = true;
}
public void disconnect()
{
if (loginConn !=null)
{
loginConn.disconnect();
bosConn.disconnect();
}
}
public void addConnectionListener(ClientConnListener c)
{
connListener =c ;
}
public void startBosConn(String server, int port, ByteBlock cookie) {
bosConn = new BosFlapConn(server, port, this, cookie);
// new BosFlapConn()
if (connListener !=null)
bosConn.addConnListener(connListener);
bosConn.connect();
}
public void registerSnacFamilies(BasicConn conn) {
snacMgr.register(conn);
}
public void connectToService(int snacFamily, String host, ByteBlock cookie) {
ServiceConn conn = new ServiceConn(host, DEFAULT_SERVICE_PORT, this,
cookie, snacFamily);
conn.connect();
}
public void serviceFailed(ServiceConn conn)
{
}
public void serviceConnected(ServiceConn conn) {
services.add(conn);
}
public void serviceReady(ServiceConn conn) {
snacMgr.dequeueSnacs(conn);
}
public void serviceDied(ServiceConn conn) {
services.remove(conn);
snacMgr.unregister(conn);
}
void joinChat(int exchange, String roomname) {
FullRoomInfo roomInfo
= new FullRoomInfo(exchange, roomname, "us-ascii", "en");
handleRequest(new SnacRequest(new JoinRoomCmd(roomInfo), null));
}
public void connectToChat(FullRoomInfo roomInfo, String host,
ByteBlock cookie) {
ChatConn conn = new ChatConn(host, DEFAULT_SERVICE_PORT, this, cookie,
roomInfo);
conn.addChatListener(new MyChatConnListener());
conn.connect();
}
public ChatConn getChatConn(String name) {
return (ChatConn) chats.get(OscarTools.normalize(name));
}
protected SnacManager snacMgr = new SnacManager(new PendingSnacListener() {
public void dequeueSnacs(SnacRequest[] pending) {
System.out.println("dequeuing " + pending.length + " snacs");
for (int i = 0; i < pending.length; i++) {
handleRequest(pending[i]);
}
}
});
public synchronized void handleRequest(SnacRequest request) {
int family = request.getCommand().getFamily();
if (snacMgr.isPending(family)) {
snacMgr.addRequest(request);
return;
}
BasicConn conn = snacMgr.getConn(family);
if (conn != null) {
conn.sendRequest(request);
} else {
// it's time to request a service
if (!(request.getCommand() instanceof ServiceRequest)) {
System.out.println("requesting " + Integer.toHexString(family)
+ " service.");
snacMgr.setPending(family, true);
snacMgr.addRequest(request);
request(new ServiceRequest(family));
} else {
System.out.println("eep! can't find a service redirector " +
"server.");
}
}
}
public SnacRequest request(SnacCommand cmd) {
return request(cmd, null);
}
private SnacRequest request(SnacCommand cmd, SnacRequestListener listener) {
SnacRequest req = new SnacRequest(cmd, listener);
handleRequest(req);
return req;
}
protected SortedMap cmdMap = new TreeMap();
OldIconHashInfo oldIconInfo;
File iconFile = null;
{ if (false) {
try {
ClassLoader classLoader = getClass().getClassLoader();
URL iconResource = classLoader.getResource("images/beck.gif");
String ext = iconResource.toExternalForm();
System.out.println("ext: " + ext);
URI uri = new URI(ext);
iconFile = new File(uri);
oldIconInfo = new OldIconHashInfo(iconFile);
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}
protected static byte[] hashIcon(String filename) throws IOException {
FileInputStream in = new FileInputStream(filename);
try {
byte[] block = new byte[1024];
MessageDigest md;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
for (;;) {
int count = in.read(block);
if (count == -1) break;
md.update(block, 0, count);
}
return md.digest();
} finally {
in.close();
}
}
private String aimexp = "the60s";
public void sendIM(String nick, String text) {
request(new SendImIcbm(nick, text));
}
public SecureSession getSecureSession() { return secureSession; }
private class MyChatConnListener implements ChatConnListener {
public void connFailed(ChatConn conn, Object reason) { }
public void connected(ChatConn conn) { }
public void joined(ChatConn conn, FullUserInfo[] members) {
String name = conn.getRoomInfo().getName();
chats.put(OscarTools.normalize(name), conn);
System.out.println("*** Joined "
+ conn.getRoomInfo().getRoomName() + ", members:");
for (int i = 0; i < members.length; i++) {
System.out.println(" " + members[i].getScreenname());
}
}
public void left(ChatConn conn, Object reason) {
String name = conn.getRoomInfo().getName();
chats.remove(OscarTools.normalize(name));
System.out.println("*** Left "
+ conn.getRoomInfo().getRoomName());
}
public void usersJoined(ChatConn conn, FullUserInfo[] members) {
for (int i = 0; i < members.length; i++) {
System.out.println("*** " + members[i].getScreenname()
+ " joined " + conn.getRoomInfo().getRoomName());
}
}
public void usersLeft(ChatConn conn, FullUserInfo[] members) {
for (int i = 0; i < members.length; i++) {
System.out.println("*** " + members[i].getScreenname()
+ " left " + conn.getRoomInfo().getRoomName());
}
}
public void gotMsg(ChatConn conn, FullUserInfo sender,
ChatMsg msg) {
String msgStr = msg.getMessage();
String ct = msg.getContentType();
if (msgStr == null && ct.equals("application/pkcs7-mime")) {
ByteBlock msgData = msg.getMessageData();
try {
msgStr = secureSession.parseChatMessage(conn.getRoomName(),
sender.getScreenname(), msgData);
} catch (SecureSessionException e) {
e.printStackTrace();
}
}
//System.out.println("<" + sender.getScreenname()
// + ":#" + conn.getRoomInfo().getRoomName() + "> "
// + );
}
}
public String getScreenname() {
return this.sn;
}
public void loginFailed(String reason) {
String message = VueResources.getString("im.login.error.message") + " : " + reason;
VueUtil.alert(message, VueResources.getString("im.login.error.title"));
}
public String getPassword() {
return this.pass;
}
public void setScreennameFormat(String screenname) {
sn = screenname;
}
public boolean isConnected() {
if (bosConn !=null)
{
return bosConn.getState().toString().equals(State.CONNECTED.toString());
}
else
return false;
}
public void ignoreIMs(boolean b) {
ignoreIMs = b;
}
public void requireApprovalToCollaborate(boolean b) {
requireApproval = b;
}
public void resetApprovalList() {
bosConn.resetApprovedContributors();
}
public void assignColorsToContributors(boolean selected) {
assignColors = selected;
}
public void forceUniformNodeWidth(boolean selected) {
forceNodeWidth = selected;
}
public void forceNodesIntoTable(boolean selected) {
makeTables = selected;
}
public void keepMapAtOneToOne(boolean selected) {
keepAt100 = selected;
}
}