/******************************************************************************* Jimm - Mobile Messaging - J2ME ICQ clone Copyright (C) 2003-04 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/RequestInfoAction.java Version: ###VERSION### Date: ###DATE### Author(s): Manuel Linsmayer *******************************************************************************/ // #sijapp cond.if protocols_ICQ is "true" # package protocol.icq.action; import jimm.comm.*; import jimm.*; import protocol.icq.IcqContact; import protocol.icq.packet.*; import jimm.modules.*; import jimm.search.*; public class RequestInfoAction extends IcqAction { // Receive timeout private static final int TIMEOUT = 10; // seconds /****************************************************************************/ private UserInfo strData; // Date of init private int packetCounter; private boolean done = false; // Constructor public RequestInfoAction(UserInfo data, IcqContact item) { super(); packetCounter = 0; strData = data; strData.uin = item.getUserId(); } public UserInfo getUserInfo() { return strData; } // Init action public void init() throws JimmException { // Send a CLI_METAREQINFO packet OutStream stream = new OutStream(); try { stream.writeWordLE(ToIcqSrvPacket.CLI_META_REQMOREINFO_TYPE); stream.writeDWordLE(Long.parseLong(strData.uin)); sendPacket(new ToIcqSrvPacket(0, getIcq().getUserId(), ToIcqSrvPacket.CLI_META_SUBCMD, new byte[0], stream.toByteArray())); } catch (Exception ignored) { requestNew(); } // Save date active(); } private void requestNew() throws JimmException { OutStream stream = new OutStream(); byte[] uin = strData.uin.getBytes(); stream.writeWordLE(ToIcqSrvPacket.CLI_META_REQUEST_FULL_INFO); stream.writeWordLE(30 + uin.length); stream.writeWordBE(0x05b9); stream.writeWordBE(ToIcqSrvPacket.CLI_META_REQUEST_FULL_INFO); stream.writeDWordBE(0x00000000); stream.writeDWordBE(0x00000000); stream.writeDWordBE(0x04e30000); stream.writeDWordBE(0x00020003); stream.writeDWordBE(0x00000001); stream.writeWordBE(4 + uin.length); stream.writeWordBE(0x0032); stream.writeWordBE(uin.length); stream.writeByteArray(uin); sendPacket(new ToIcqSrvPacket(0, getIcq().getUserId(), ToIcqSrvPacket.CLI_META_SUBCMD, new byte[0], stream.toByteArray())); } private String readAsciiz(ArrayReader stream) { int len = stream.getWordLE(); if (len == 0) { return ""; } byte[] buffer = stream.getArray(len); // TODO: check it return StringUtils.byteArrayToWinString(buffer, 0, buffer.length).trim(); } // Forwards received packet, returns true if packet was consumed public boolean forward(Packet packet) throws JimmException { boolean consumed = false; // Watch out for SRV_FROMICQSRV packet if (packet instanceof FromIcqSrvPacket) { FromIcqSrvPacket fromIcqSrvPacket = (FromIcqSrvPacket) packet; // Watch out for SRV_META packet if (fromIcqSrvPacket.getSubcommand() != FromIcqSrvPacket.SRV_META_SUBCMD) { return false; } // Get packet data ArrayReader stream = fromIcqSrvPacket.getReader(); // Watch out for SRV_METAGENERAL packet try { int type = stream.getWordLE(); stream.getByte(); // Success byte if (FromIcqSrvPacket.SRV_META_FULL_INFO == type) { stream.skip(5*2 + 21); processFillInfo(stream); return true; } switch (type) { case FromIcqSrvPacket.SRV_META_GENERAL_TYPE: // basic user information { strData.nick = readAsciiz(stream); // nickname strData.firstName = readAsciiz(stream); strData.lastName = readAsciiz(stream); strData.email = readAsciiz(stream); // email strData.homeCity = readAsciiz(stream); // home city strData.homeState = readAsciiz(stream); // home state strData.homePhones = readAsciiz(stream); // home phone strData.homeFax = readAsciiz(stream); // home fax strData.homeAddress = readAsciiz(stream); // home address strData.cellPhone = readAsciiz(stream); // cell phone packetCounter++; consumed = true; break; } case 0x00DC: // more user information { strData.age = stream.getWordLE(); strData.gender = (byte)stream.getByte(); strData.homePage = readAsciiz(stream); int year = stream.getWordLE(); int mon = stream.getByte(); int day = stream.getByte(); strData.birthDay = (year != 0) ? (day + "." + (mon < 10 ? "0" : "") + mon + "." + year) : null; packetCounter++; consumed = true; break; } case 0x00D2: // work user information { strData.workCity = readAsciiz(stream); strData.workState = readAsciiz(stream); strData.workPhone = readAsciiz(stream); strData.workFax = readAsciiz(stream); strData.workAddress = readAsciiz(stream); readAsciiz(stream); // work zip code stream.getWordLE(); // work country code strData.workCompany = readAsciiz(stream); // work company strData.workDepartment = readAsciiz(stream); // work department strData.workPosition = readAsciiz(stream); // work position packetCounter++; consumed = true; break; } case 0x00E6: // user about information { strData.about = readAsciiz(stream); // notes string packetCounter++; consumed = true; break; } case 0x00F0: // user interests information { StringBuilder sb = new StringBuilder(); int counter = stream.getByte(); for (int i = 0; i < counter; ++i) { stream.getWordLE(); String item = readAsciiz(stream); if (item.length() == 0) continue; if (sb.length() != 0) sb.append(", "); sb.append(item); } strData.interests = sb.toString(); packetCounter++; consumed = true; break; } } } catch (Exception e) { // #sijapp cond.if modules_DEBUGLOG is "true" # DebugLog.panic("Request Info action", e); // #sijapp cond.end# } if (packetCounter >= 5) { requestNew(); } // is completed? strData.setOptimalName(); strData.updateProfileView(); } return consumed; } private void processFillInfo(ArrayReader stream) { done = true; int len = stream.getWordBE(); int offset = stream.getOffset(); strData.nick = str(stream.getTlvData(0x0046, offset, len)); strData.firstName = str(stream.getTlvData(0x0064, offset, len)); strData.lastName = str(stream.getTlvData(0x006e, offset, len)); strData.gender = stream.getTlvData(0x0082, offset, len)[0]; strData.homePage = str(stream.getTlvData(0x00fa, offset, len)); strData.about = str(stream.getTlvData(0x0186, offset, len)); strData.homeState = getTvlData(0x0096, 0x0078, stream, offset, len); strData.homeCity = getTvlData(0x0096, 0x0064, stream, offset, len); strData.homeAddress = getTvlData(0x0096, 0x006e, stream, offset, len); if (StringUtils.isEmpty(strData.homeCity) && StringUtils.isEmpty(strData.homeAddress)) { strData.homeCity = getTvlData(0x00a0, 0x0064, stream, offset, len); strData.homeAddress = getTvlData(0x00a0, 0x006e, stream, offset, len); } strData.workState = getTvlData(0x0118, 0x00be, stream, offset, len); strData.workCity = getTvlData(0x0118, 0x00b4, stream, offset, len); strData.workDepartment = getTvlData(0x0118, 0x007D, stream, offset, len); strData.workCompany = getTvlData(0x0118, 0x006e, stream, offset, len); strData.workPosition = getTvlData(0x0118, 0x0064, stream, offset, len); strData.setOptimalName(); strData.updateProfileView(); /* stream.setOffset(offset); while (stream.isNotEnd()) { int type = stream.getTlvType(); byte[] data = stream.getTlv(); DebugLog.dump("type " + Integer.toHexString(type) + " " + StringConvertor.byteArray1251ToString(data, 0, data.length), data); } */ } private String getTvlData(int type, int subtype, ArrayReader stream, int offset, int len) { byte[] data = stream.getTlvData(type, offset, len); if (null == data) return null; if (0 == subtype) return str(data); ArrayReader sub = new ArrayReader(data, 2); int subLen = sub.getWordBE(); data = sub.getTlvData(subtype, 4, subLen); if (null == data) return null; return str(data); } private String str(byte[] data) { if (null == data) return null; return StringUtils.utf8beByteArrayToString(data, 0, data.length).trim(); } // Returns true if the action is completed public boolean isCompleted() { return done; } // Returns true if an error has occured public boolean isError() { return isNotActive(TIMEOUT); } } // #sijapp cond.end #