?? connectaction.java.svn-base
字號:
/******************************************************************************* Jimm - Mobile Messaging - J2ME ICQ clone Copyright (C) 2003-05 Jimm Project 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ******************************************************************************** File: src/jimm/comm/ConnectAction.java Version: ###VERSION### Date: ###DATE### Author(s): Manuel Linsmayer, Andreas Rossbacher *******************************************************************************/package jimm.comm;import java.util.*;import java.io.*;import jimm.ContactItem;import jimm.ContactListGroupItem;import jimm.ContactListItem;import jimm.ContactList;import jimm.JimmException;import jimm.Options;import jimm.MainThread;import jimm.util.ResourceBundle;import jimm.comm.connections.HTTPConnection;public class ConnectAction extends Action{ // Action states public static final int STATE_ERROR = -1; public static final int STATE_INIT_DONE = 0; public static final int STATE_AUTHKEY_REQUESTED = 1; public static final int STATE_CLI_IDENT_SENT = 2; public static final int STATE_CLI_DISCONNECT_SENT = 3; public static final int STATE_CLI_COOKIE_SENT = 4; public static final int STATE_CLI_WANT_CAPS_SENT = 5; public static final int STATE_CLI_CHECKROSTER_SENT = 6; public static final int STATE_CLI_STATUS_INFO_SENT = 7; public static final int STATE_CONNECTED = 8; public static final int STATE_MAX = 8; // CLI_SETICBM packet data public static final byte[] CLI_SETICBM_DATA = Util.explodeToBytes("0,0,0,0,0,0B,1F,40,3,E7,3,E7,0,0,0,0", ',', 16); // CLI_READY packet data public static final byte[] CLI_READY_DATA = Util.explodeToBytes ( "00,22,00,01,01,10,16,4f,"+ "00,01,00,04,01,10,16,4f,"+ "00,13,00,04,01,10,16,4f,"+ "00,02,00,01,01,10,16,4f,"+ "00,03,00,01,01,10,16,4f,"+ "00,15,00,01,01,10,16,4f,"+ "00,04,00,01,01,10,16,4f,"+ "00,06,00,01,01,10,16,4f,"+ "00,09,00,01,01,10,16,4f,"+ "00,0a,00,01,01,10,16,4f,"+ "00,0b,00,01,01,10,16,4f", ',', 16 ); public static final short[] FAMILIES_AND_VER_LIST = { 0x0022, 0x0001, 0x0001, 0x0004, 0x0013, 0x0004, 0x0002, 0x0001, 0x0003, 0x0001, 0x0015, 0x0001, 0x0004, 0x0001, 0x0006, 0x0001, 0x0009, 0x0001, 0x000a, 0x0001, 0x000b, 0x0001, }; // Timeout // #sijapp cond.if modules_PROXY is "true" # public static final int TIME_OUT = 30 * 1000; // #sijapp cond.end # public int TIMEOUT = 30 * 1000; // milliseconds /** *********************************************************************** */ // UIN private String uin; // Password private String password; // Server host private String srvHost; // Server port private String srvPort; // Action state private int state; // Last activity private long lastActivity; private boolean active; private boolean canceled_by_timeout; // Temporary variables private String server; private byte[] cookie; private boolean srvReplyRosterRcvd; // Constructor public ConnectAction(String uin, String password, String srvHost, String srvPort) { super(true, false); System.out.println("conn. act. srvHost="+srvHost); lastActivity = System.currentTimeMillis(); this.uin = uin; this.password = password; this.srvHost = srvHost; this.srvPort = srvPort; System.out.println("ConnectAction, this="+this); } // Returns the UID public String getUin() { return this.uin; } // Returns the password public String getPassword() { return this.password; } // Returns the server host public String getSrvHost() { return this.srvHost; } // Returns the server port public String getSrvPort() { return this.srvPort; } // Init action protected void init() throws JimmException { // #sijapp cond.if modules_PROXY is "true" # int retry = 1; try { retry = Integer.parseInt(Options.getString(Options.OPTION_AUTORETRY_COUNT)); retry = (retry > 0) ? retry : 1; } catch (NumberFormatException e) { retry = 1; } this.TIMEOUT = ConnectAction.TIME_OUT * retry; // #sijapp cond.end# // Check parameters if ((this.uin.length() == 0) || (this.password.length() == 0)) { this.state = ConnectAction.STATE_ERROR; throw (new JimmException(117, 0)); } // Open connection // #sijapp cond.if modules_PROXY is "true" # for (int i = 0; i < retry; i++) { // #sijapp cond.end# try { Icq.connect(this.srvHost + ":" + this.srvPort); // #sijapp cond.if modules_PROXY is "true" # break; // #sijapp cond.end # } catch (JimmException e) { // #sijapp cond.if modules_PROXY is "true" # if (i >= (retry - 1) || ((this.lastActivity + this.TIMEOUT) < System.currentTimeMillis())) { // #sijapp cond.end # this.state = ConnectAction.STATE_ERROR; throw (e); } // #sijapp cond.if modules_PROXY is "true" # else if ((this.lastActivity + this.TIMEOUT) > System.currentTimeMillis()) { Icq.c.notifyToDisconnect(); try { // Wait the given time Thread.sleep(2000); } catch (InterruptedException er) { // Do nothing } } } } // #sijapp cond.end # // Set STATE_INIT this.state = ConnectAction.STATE_INIT_DONE; // Update activity timestamp this.lastActivity = System.currentTimeMillis(); } private int getConnectionErrorCode (int errCode) { switch (errCode) { // Multiple logins case 0x0001: return 110; // Bad password case 0x0004: case 0x0005: return 111; // Non-existant UIN case 0x0007: case 0x0008: return 112; // Too many clients from same IP case 0x0015: case 0x0016: return 113; // Rate exceeded case 0x0018: case 0x001d: return 114; } return 100; } // Forwards received packet, returns true if packet has been consumed protected boolean forward(Packet packet) throws JimmException { // #sijapp cond.if modules_PROXY is "true" # int retry = 1; try { retry = Integer.parseInt(Options.getString(Options.OPTION_AUTORETRY_COUNT)); retry = (retry > 0) ? retry : 1; } catch (NumberFormatException e) { retry = 1; } // #sijapp cond.end # // Set activity flag this.active = true; // Catch JimmExceptions try { // Flag indicates whether packet has been consumed or not boolean consumed = false; // Watch out for STATE_INIT_DONE if (this.state == ConnectAction.STATE_INIT_DONE) { // Watch out for SRV_CLI_HELLO packet if (packet instanceof ConnectPacket) { ConnectPacket connectPacket = (ConnectPacket) packet; if (connectPacket.getType() == ConnectPacket.SRV_CLI_HELLO) { if (Options.getBoolean(Options.OPTION_MD5_LOGIN)) { Icq.c.sendPacket(new ConnectPacket()); byte[] buf = new byte[4 + this.uin.length()]; Util.putWord(buf, 0, 0x0001); Util.putWord(buf, 2, this.uin.length()); byte[] uinRaw = Util.stringToByteArray(this.uin); System.arraycopy(uinRaw, 0, buf, 4, uinRaw.length); Icq.c.sendPacket(new SnacPacket(0x0017, 0x0006, 0, new byte[0], buf)); } else { // Send a CLI_IDENT packet as reply ConnectPacket reply = new ConnectPacket(this.uin, this.password); Icq.c.sendPacket(reply); } // Move to next state this.state = !Options.getBoolean(Options.OPTION_MD5_LOGIN) ? ConnectAction.STATE_CLI_IDENT_SENT : STATE_AUTHKEY_REQUESTED; // Packet has been consumed consumed = true; } } } else if (state == STATE_AUTHKEY_REQUESTED) { if (packet instanceof SnacPacket) { SnacPacket snacPacket = (SnacPacket)packet; if ((snacPacket.getFamily() == 0x0017) && (snacPacket.getCommand() == 0x0007)) { byte[] rbuf = snacPacket.getData(); int len = Util.getWord(rbuf, 0); byte[] authkey = new byte[len]; System.arraycopy(rbuf, 2, authkey, 0, len); rbuf = null; byte[] buf = new byte[2 + 2 + this.uin.length() + 2 + 2 + 16]; int marker = 0; Util.putWord(buf, marker, 0x0001); marker += 2; Util.putWord(buf, marker, this.uin.length()); marker += 2; byte[] uinRaw = Util.stringToByteArray(this.uin); System.arraycopy(uinRaw, 0, buf, marker, uinRaw.length); marker += uinRaw.length; Util.putWord(buf, marker, 0x0025); marker += 2; Util.putWord(buf, marker, 0x0010); marker += 2; byte[] md5buf = new byte[authkey.length + this.password.length() + Util.AIM_MD5_STRING.length]; int md5marker = 0; System.arraycopy(authkey, 0, md5buf, md5marker, authkey.length); md5marker += authkey.length; byte[] passwordRaw = Util.stringToByteArray(this.password); System.arraycopy(passwordRaw, 0, md5buf, md5marker, passwordRaw.length); md5marker += passwordRaw.length; System.arraycopy(Util.AIM_MD5_STRING, 0, md5buf, md5marker, Util.AIM_MD5_STRING.length); byte[] hash = Util.calculateMD5(md5buf); System.arraycopy(hash, 0, buf, marker, 16); Icq.c.sendPacket(new SnacPacket(0x0017, 0x0002, 0, new byte[0], buf)); state = STATE_CLI_IDENT_SENT; } else { int errcode = -1; if ((snacPacket.getFamily() == 0x0017) && (snacPacket.getCommand() == 0x0003)) { byte[] buf = snacPacket.getData(); int marker = 0; while (marker < buf.length) { byte[] tlvData = Util.getTlv(buf, marker); int tlvType = Util.getWord(buf, marker); marker += 4 + tlvData.length; if (tlvType == 0x0008) { errcode = Util.getWord(tlvData, 0); } } } if (errcode != -1) { consumed = true; Icq.c.notifyToDisconnect(); this.state = ConnectAction.STATE_ERROR; int toThrow = getConnectionErrorCode (errcode); throw new JimmException(toThrow, errcode); } } } consumed = true; } // Watch out for STATE_CLI_IDENT_SENT else if (this.state == ConnectAction.STATE_CLI_IDENT_SENT) { int errcode = -1; if (Options.getBoolean(Options.OPTION_MD5_LOGIN)) { if (packet instanceof SnacPacket) { SnacPacket snacPacket = (SnacPacket)packet; if ((snacPacket.getFamily() == 0x0017) && (snacPacket.getCommand() == 0x0003)) { byte[] buf = snacPacket.getData(); int marker = 0; while (marker < buf.length) { byte[] tlvData = Util.getTlv(buf, marker); int tlvType = Util.getWord(buf, marker); marker += 4 + tlvData.length; switch (tlvType) { case 0x0008: errcode = Util.getWord(tlvData, 0); break; case 0x0005: this.server = Util.byteArrayToString(tlvData); break; case 0x0006: this.cookie = tlvData; break; } } } } else if (packet instanceof DisconnectPacket) { consumed = true; } } else { // watch out for channel 4 packet if (packet instanceof DisconnectPacket) { DisconnectPacket disconnectPacket = (DisconnectPacket) packet; // Watch out for SRV_COOKIE packet if (disconnectPacket.getType() == DisconnectPacket.TYPE_SRV_COOKIE) { // Save cookie this.cookie = disconnectPacket.getCookie(); this.server = disconnectPacket.getServer(); } // Watch out for SRV_GOODBYE packet else if (disconnectPacket.getType() == DisconnectPacket.TYPE_SRV_GOODBYE) errcode = disconnectPacket.getError(); consumed = true; } } if (errcode != -1) { consumed = true; Icq.c.notifyToDisconnect(); this.state = ConnectAction.STATE_ERROR; int toThrow = getConnectionErrorCode (errcode); throw new JimmException(toThrow, errcode); } if (consumed & (this.server != null) & (this.cookie != null)) { // Close connection (only if not HTTP Connection) if (!(Icq.c instanceof HTTPConnection)) { Icq.c.forceDisconnect(); Thread.yield(); try { Thread.sleep(1000); } catch (Exception e ) {} } // #sijapp cond.if target is "DEFAULT" | target is "MIDP2"# if (Options.getBoolean(Options.OPTION_SHADOW_CON)) try { // Wait the given time before starting the // new connection Thread.sleep(2000); } catch (InterruptedException e) {} // #sijapp cond.end# // Open connection // #sijapp cond.if modules_PROXY is "true" # for (int i = 0; i < retry; i++) { try { // #sijapp cond.end # Icq.c.connect(server); // #sijapp cond.if modules_PROXY is "true" # break; } catch (JimmException e) { if (i >= (retry - 1) || ((this.lastActivity + this.TIMEOUT) < System.currentTimeMillis())) { this.active = false; this.state = ConnectAction.STATE_ERROR; throw (e); } else if ((this.lastActivity + this.TIMEOUT) > System.currentTimeMillis()) { Icq.c.notifyToDisconnect(); try { // Wait the given time Thread.sleep(2000); } catch (InterruptedException er) { // Do nothing } } } } // #sijapp cond.end # // Move to next state
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -