📄 notificationprocessor.java
字号:
/*
* @(#)NotificationProcessor.java
*
* Copyright (c) 2001-2002, JangHo Hwang
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the JangHo Hwang nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: NotificationProcessor.java,v 2.0 2004/12/21 16:15:08 chenzs Exp $
*/
package vitular.msnp;
//import java.lang.reflect.Method;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Hashtable;
import java.util.Enumeration; //Iterator --> 2004/5/30 ceze
import javax.microedition.io.HttpsConnection;
import javax.microedition.io.Connector;
import java.io.*;
//import javax.microedition.rms.*;
import vitular.msnp.entity.Callback;
import vitular.msnp.entity.CallbackListener;
import vitular.msnp.entity.MsnFriend;
import vitular.msnp.entity.Group;
import vitular.msnp.msg.OutgoingMessage;
import vitular.msnp.msg.IncomingMessage;
import vitular.msnp.msg.MimeMessage;
import vitular.msnp.msg.MimeUtility;
import vitular.msnp.util.StringUtil;
import vitular.msnp.util.MD5;
import vitular.msnp.util.BufferedReader;
/**
* 通告处理器
* msn首先登陆到通告服务器(Notification Server).通告服务器负责客户端的登陆验证;
* 聊天邀请;邀请接受;中转服务器的分配等通告信息的处理.
* Notification Server相当Msn服务器端的主控中心.因此mns每次只和一个Notification Server建立连接.
* <p>Title: MSNP Lib</p>
* <p>Description: Unija 版Msn协议</p>
* <p>Copyright: Copyright (c) 2004</p>
* <p>Company: Vitular</p>
* @author ceze
* @version 1.0
*/
public class NotificationProcessor
extends AbstractProcessor
implements UserStatus, CallbackListener {
private static final String DEFAULT_NOTIFICATION_SERVER =
"http://gateway.messenger.hotmail.com"; //207.46.104.20
private static final String DEFAULT_LOGIN_SERVER = "messenger.hotmail.com"; //207.46.104.20
private static final String DEFAULT_LOGIN_CMD = "Action=open&Server=NS&IP=";
int lastSerial = 0;
private String securityPackage = null;
private String status = null;
private MsnFriend ownerFriend = null;
private Thread callbackCleaner = null;
private Hashtable lockMap = new Hashtable();
private Hashtable sessionMap = new Hashtable();
private Hashtable callIdMap = new Hashtable();
public NotificationProcessor(MSNMessenger msn) {
this(msn, 0);
}
public NotificationProcessor(MSNMessenger msn, int trId) {
super(msn, DEFAULT_NOTIFICATION_SERVER, trId);
setServerName("NS");
setCallbackListener(this);
setRequestCommand(DEFAULT_LOGIN_CMD + DEFAULT_LOGIN_SERVER);
}
/**
* 网络出错异常发布
* @param e Throwable
*/
public void processError(Throwable e) {
// if (msn != null)
// msn.fireConnectFailEvent(msn.ERR_CONNECTION_FAIL, true);
System.err.println(this.getClass().getName() + ":");
e.printStackTrace();
}
/**
* 向服务器发送通讯协议认证
*/
public void init() throws IOException {
isProcessInit = true;
OutgoingMessage msg = new OutgoingMessage("VER");
markTransactionId(msg);
msg.add("MSNP10");
msg.add("MSNP11");
msg.add("MSNP9");
msg.add("MSNP8");
msg.add("CVRO");
msg.setBackProcess(Callback.getInstance(PROCESS_VER));
//创建连接
// makeConnection();
// httpConn.setRequestProperty(this.REQUEST_HEAD_CONTENT_LENGTH,"25");
// String.valueOf(msg.toString().length() + 2));//\uFFFD\uFFFD("\r\n")
sendMessage(msg);
}
/**
*
*/
public void processMessage(IncomingMessage msg) throws Exception {
String header = msg.getHeader();
if (header.equals("ILN")) {
String status = msg.get(0);
String login = msg.get(1);
String friendly = msg.get(2);
MsnFriend friend = msn.getBuddyGroup().getForwardList().get(login);
if (friend == null)
friend = new MsnFriend(login, friendly);
else
friend.setFriendlyName(friendly);
friend.setStatus(status);
msn.fireListOnlineEvent(friend);
}
else
if (header.equals("ADD")) {
String group = msg.get(0);
// \uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD \uFFFD\u07F0\uFFFD\uFFFD\uFFFD \uFFFD\uFFFD: NOTIFY\uFFFD\uFFFD\uFFFD\u0339\u01F7\uFFFD trId\uFFFD\uFFFD 0\uFFFD\uFFFD\uFFFD\u0334\uFFFD.
if (group.equals("RL") && msg.getTransactionId() == 0) {
this.lastSerial = msg.getInt(1);
String login = msg.get(2);
String friendly = msg.get(3);
// Serial \uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u03F0\uFFFD, \uFFFD\uFFFDο\uFFFD\uFFFD\uFFFD\u03B0\uFFFD; LocalCopy\uFFFD\uFFFD \uFFFD\uFFFD\uFFFD\uFFFD\u063E\uFFFD\uFFFD\u0474\uFFFD\uFFFD
MsnFriend friend = new MsnFriend(login, friendly);
BuddyList reverse = msn.getBuddyGroup().getReverseList();
reverse.add(friend);
msn.storeLocalCopy(lastSerial);
msn.fireWhoAddedMeEvent(friend);
}
}
else
if (header.equals("REM") && msg.getTransactionId() == 0) {
String group = msg.get(0);
if (group.equals("RL")) {
this.lastSerial = msg.getInt(1);
String login = msg.get(2);
BuddyList reverse = msn.getBuddyGroup().getReverseList();
reverse.remove(login);
msn.storeLocalCopy(lastSerial);
msn.fireWhoRemovedMeEvent(new MsnFriend(login, null));
}
}
else
if (header.equals("CHL")) {
MD5 md5 = new MD5();
String code = md5.getMD5ofStr(msg.get(0) + "Q1P7W2E4J9R8U3S5");
OutgoingMessage out = new OutgoingMessage("QRY");
markTransactionId(out);
out.add("msmsgs@msnmsgr.com");
out.add(32);
sendCHLResponse(out, code);
}
}
public void processNotifyMessage(IncomingMessage msg, BufferedReader in) throws
Exception {
super.processNotifyMessage(msg, in);
System.out.println("processNotifyMessage:\n" + msg.toString() + "\n");
String header = msg.getHeader();
if (header.equals("NLN")) {
String status = msg.get(0);
String login = msg.get(1);
String friendly = msg.get(2);
BuddyList fl = msn.getBuddyGroup().getForwardList();
MsnFriend friend = fl.get(login);
friend.setStatus(status);
friend.setFriendlyName(friendly);
msn.fireUserOnlineEvent(friend);
}
else
if (header.equals("FLN")) {
String login = msg.get(0);
msn.fireUserOfflineEvent(login);
}
else
if (header.equals("RNG")) {
//响应聊天\uFFFD\uFFFD\uFFFD\uFFFD
acceptRinging(msg);
}
else
if (header.equals("LSG")) {
doCollectGroup(msg);
}
else
if (header.equals("LST")) {
doCollectList(msg);
}
}
protected void filterMimeMessage(MimeMessage msg) {
if (msg.getKind() == MimeMessage.KIND_MAIL_NOTIFY) {
if (msg.hasProperty("Inbox-Unread"))
msn.fireNotifyUnreadMail(msg.getProperties(),
Integer.parseInt(msg.getProperty(
"Inbox-Unread")));
}
}
/**
* \uFFFD\uFFFD\u022D \uFFFD\u07B0\uFFFD Switchboard Server\uFFFD\uFFFD \uFFFD\uFFFD\uFFFD\uFFFD; \uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0474\uFFFD.
* \uFFFD\u02FE\u01BC\uFFFD Internal session hashmap\uFFFD\uFFFD \uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0334\uFFFD.
* 接受聊天\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD转向指定SwitchboardServer
*/
protected void acceptRinging(IncomingMessage msg) throws IOException {
String sessionId = msg.get(0);
String servIP = msg.getServerIP(1);
// String securityPackage = msg.get(2);
String cookie = msg.get(3);
// String destinLoginName = msg.get(4);
// String destinFriendlyName = msg.get(5);
// Throw calling friend information
// I need not :)
SwitchboardSession ss = new SwitchboardSession(msn, servIP, sessionId);
ss.setCookie(cookie);
ss.start();
}
public void processVER(IncomingMessage msg) throws Exception {
isProcessInit = false;
//System.out.println("processVER");//jj
OutgoingMessage out = new OutgoingMessage("CVR");
markTransactionId(out);
out.add("0x0804"); // What is it?
out.add("Window_XP"); // OS name
out.add("5.1"); // OS version
out.add("x86"); // OS architecture
out.add("MSNMSGR");
out.add("6.2.0133");
out.add("MSMSGS");
out.add(msn.getLoginName());
// out.setBackProcess(Callback.getInstance("processCVR", this.getClass()));
out.setBackProcess(Callback.getInstance(PROCESS_CVR));
sendMessage(out);
}
public void processCVR(IncomingMessage msg) throws Exception {
//System.out.println("processCVR");//jj
// Microsoft doesn't provide security package.
// this.securityPackage = msg.get(0);
this.securityPackage = "TWN"; // SSL based
OutgoingMessage out = new OutgoingMessage("USR");
markTransactionId(out);
out.add(this.securityPackage);
out.add("I");
out.add(msn.getLoginName());
// out.setBackProcess(Callback.getInstance("processAuth", this.getClass()));
out.setBackProcess(Callback.getInstance(PROCESS_AUTH));
sendMessage(out);
}
/**
* \uFFFD\u00FB\uFFFD\uFFFD\uFFFD\u00BC\uFFFD\uFFFD\u05A4
* @param msg IncomingMessage
* @throws Exception
*/
public void processAuth(IncomingMessage msg) throws Exception {
//System.out.println("processAuth");//jj
String header = msg.getHeader();
if (header.equals("XFR") &&
msg.get(0).equals("NS")) {
//改动 2004/5/30 ceze
String ip = msg.getServerIP(1);
setHostURL(DEFAULT_NOTIFICATION_SERVER);
setRequestCommand(DEFAULT_LOGIN_CMD + ip);
init();
return;
}
OutgoingMessage out = new OutgoingMessage("USR");
markTransactionId(out);
out.add(this.securityPackage);
out.add("S");
if (securityPackage.equals("MD5")) {
MD5 md5 = new MD5();
out.add(md5.getMD5ofStr(msg.get(2) + msn.getPassword()));
}
else
if (securityPackage.equals("TWN")) {
String tp = getTNP(msn.getLoginName(), msn.getPassword(), msg.get(2));
System.out.println("t&p:" + tp);
out.add(tp);
}
out.setBackProcess(Callback.getInstance(PROCESS_LOGON));
sendMessage(out);
}
public void processLogon(IncomingMessage msg) throws Exception {
// Authentication failed.
//System.out.println("processLogon");//jj
if (!msg.getHeader().equals("USR")) {
msn.fireLoginErrorEvent(msg.getHeader());
return;
}
Callback cb = Callback.getInstance(JUDGE_SERIAL);
OutgoingMessage out = new OutgoingMessage("SYN");
markTransactionId(out);
out.add(lastSerial);
out.setBackProcess(cb);
sendMessage(out);
msn.isLogged = true;
String s1 = msg.get(1);
String s2 = msg.get(2);
ownerFriend = new MsnFriend(s1, s2);
}
public void judgeSerial(IncomingMessage msg) throws IOException {
int serverSerial = msg.getInt(0);
if (serverSerial != lastSerial) {
this.lastSerial = serverSerial;
BuddyGroup bg = msn.getBuddyGroup();
bg.getForwardList().clear();
bg.getAllowList().clear();
bg.getBlockList().clear();
bg.getReverseList().clear();
}
setMyStatus(msn.getInitialStatus());
//发送登陆成功消息
msn.fireLoginCompleteEvent(ownerFriend);
}
/**
* 接收分组列表
*/
public void doCollectGroup(IncomingMessage msg) throws IOException {
System.out.println("doCollectGroup"); //jj
GroupList gl = msn.getBuddyGroup().getGroupList();
int gIndex = msg.getInt(0);
String gName = MimeUtility.getURLDecodedString(msg.get(1), "UTF-8");
Group group = new Group(gName, gIndex);
gl.addGroup(group);
}
/**
* 接收好友列表
* @param msg IncomingMessage
* @throws IOException
*/
public void doCollectList(IncomingMessage msg) throws IOException {
String hisLoginName = msg.get(0);
String hisFriendlyName = msg.get(1);
int accessId = msg.getInt(2);
int groupIndex = 0;
if (msg.size() > 3) {
String gis = msg.get(3);
if (gis.indexOf(',') != -1)
gis = gis.substring(0, gis.indexOf(','));
groupIndex = Integer.parseInt(gis);
}
MsnFriend friend = new MsnFriend(hisLoginName);
friend.setFriendlyName(hisFriendlyName);
friend.setGroupIndex(groupIndex);
BuddyGroup bg = msn.getBuddyGroup();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -