📄 messagehelper.java
字号:
* 本上也和系统消息差不多,先看小喇叭闪没闪,没闪就闪他,再看是不是第一条消息,是就
* 再闪tray icon
*
* @param packet
* 消息包
*/
public void putClusterNotification(ReceiveIMPacket packet) {
String clusterName;
Cluster c = ModelRegistry.getCluster(packet.header.sender);
if(c == null)
clusterName = String.valueOf(packet.externalId);
else
clusterName = c.name;
if(clusterName.equals(""))
clusterName = String.valueOf(packet.externalId);
// 保存到聊天记录
String sender = String.valueOf(packet.sender);
RecordEntry entry = new RecordEntry();
entry.type = IKeyConstants.SYSTEM;
entry.owner = 10000;
entry.sender = packet.header.sender;
entry.senderParent = packet.sender;
entry.receiver = main.getMyModel().qq;
entry.time = System.currentTimeMillis();
switch(packet.header.type) {
case QQ.QQ_RECV_IM_ADDED_TO_CLUSTER:
entry.subType = IKeyConstants.SUB_ADDED_TO_CLUSTER;
case QQ.QQ_RECV_IM_CREATE_CLUSTER:
entry.subType = IKeyConstants.SUB_CREATE_CLUSTER;
if(packet.clusterType == QQ.QQ_CLUSTER_TYPE_PERMANENT)
entry.message = NLS.bind(cluster_message_permanent_cluster_created, clusterName);
else
entry.message = NLS.bind(cluster_message_temporary_cluster_created, clusterName);
packet.message = entry.message;
break;
case QQ.QQ_RECV_IM_DELETED_FROM_CLUSTER:
entry.subType = IKeyConstants.SUB_DELETED_FROM_CLUSTER;
if(packet.sender == main.getMyModel().qq)
entry.message = NLS.bind(cluster_message_removed, clusterName);
else
entry.message = NLS.bind(cluster_message_exit, sender, clusterName);
packet.message = entry.message;
break;
case QQ.QQ_RECV_IM_REQUEST_JOIN_CLUSTER:
entry.subType = IKeyConstants.SUB_REQUEST_JOIN_CLUSTER;
entry.message = NLS.bind(cluster_message_request, new Object[] { sender, clusterName, packet.message });
packet.message = entry.message;
break;
case QQ.QQ_RECV_IM_APPROVE_JOIN_CLUSTER:
entry.subType = IKeyConstants.SUB_APPROVE_JOIN_CLUSTER;
entry.message = NLS.bind(cluster_message_approved, sender);
packet.message = entry.message;
break;
case QQ.QQ_RECV_IM_REJECT_JOIN_CLUSTER:
entry.subType = IKeyConstants.SUB_REJECT_JOIN_CLUSTER;
entry.message = NLS.bind(cluster_message_rejected, sender, packet.message);
packet.message = entry.message;
break;
case QQ.QQ_RECV_IM_CLUSTER_NOTIFICATION:
switch(packet.opCode) {
case QQ.QQ_CLUSTER_OP_SET_ADMIN:
entry.subType = IKeyConstants.SUB_CLUSTER_NOTIFICATION_SET_ADMIN;
entry.message = NLS.bind(cluster_message_admin_entitled, clusterName);
packet.message = entry.message;
break;
case QQ.QQ_CLUSTER_OP_UNSET_ADMIN:
entry.subType = IKeyConstants.SUB_CLUSTER_NOTIFICATION_UNSET_ADMIN;
entry.message = NLS.bind(cluster_message_admin_withdrawed, clusterName);
packet.message = entry.message;
break;
}
break;
default:
entry.subType = IKeyConstants.SUB_UNKNOWN;
entry.message = "";
packet.message = entry.message;
break;
}
main.getRecordManager().addRecord(entry);
// 调整动画状态
if(!main.getMessageQueue().hasNext())
main.getUIHelper().startBlinkImage(res.getImage(Resources.icoSysMsg));
if(!main.getMessageQueue().hasSystemMessage())
main.getUIHelper().startBlinkSystemMessageIcon();
main.getMessageQueue().putSystemMessage(packet);
// 播放声音
main.getSounder().play(LumaQQ.SYS_MSG_SOUND);
log.debug("一个系统消息被推入队列");
}
/**
* 处理延迟队列中的消息
*/
public void processPostponedIM() {
ReceiveIMPacket packet;
MessageQueue mq = main.getMessageQueue();
while((packet = (ReceiveIMPacket)mq.getPostponedMessage()) != null) {
log.debug("发现一条延迟消息,处理之");
switch(packet.header.type) {
case QQ.QQ_RECV_IM_CLUSTER:
case QQ.QQ_RECV_IM_TEMP_CLUSTER:
putClusterIM(packet);
break;
default:
putNormalIM(packet);
break;
}
}
}
/**
* 推入一个临时会话消息
*
* @param packet
*/
public void putTempSessionIM(ReceiveIMPacket packet) {
// 得到一些工具类
BlindHelper blindHelper = main.getBlindHelper();
OptionHelper options = main.getOptionHelper();
// 如果设置了拒绝临时会话消息,返回
if(options.isRejectTempSessionIM())
return;
// 如果现在是延迟处理
MessageQueue mq = main.getMessageQueue();
if(mq.isPostpone()) {
mq.postponeMessage(packet);
return;
}
// 得到发送者,如果不存在这个用户,添加到陌生人
User f = ModelRegistry.getUser(packet.tempSessionIM.sender);
boolean isStranger = false;
boolean blinkable = false;
if(f == null) {
isStranger = true;
f = new User();
f.qq = packet.tempSessionIM.sender;
f.nick = String.valueOf(f.qq);
f.displayName = f.nick;
main.getClient().getUserInfo(f.qq);
} else if(f.group.isBlackList()) {
log.debug("收到一个坏人来的消息,忽略");
return;
} else if(f.group.isCluster()) {
isStranger = true;
} else
blinkable = true;
// 保存到聊天记录中,使用当前时间
// 本来以前是使用包中的时间的,但是每个人的机器都不一样,所以往往记录就乱了
// 现在使用收到的时间,其实也有问题,对于那些留言就不太好判断时间了(没有太好的办法,不是没有办法)
RecordEntry entry = new RecordEntry();
entry.type = IKeyConstants.NORMAL;
entry.owner = packet.tempSessionIM.sender;
entry.sender = packet.tempSessionIM.sender;
entry.senderParent = 0;
entry.receiver = main.getMyModel().qq;
entry.time = System.currentTimeMillis();
entry.message = packet.tempSessionIM.message;
main.getRecordManager().addRecord(entry);
// 如果最近联系人功能是打开的,添加到最近联系人中
if(options.isEnableLatest() && (!isStranger || (isStranger && options.isKeepStrangerInLatest())))
blindHelper.updateLatest(f);
UIHelper uiHelper = main.getUIHelper();
// 从model得到好友的头像
Image head = HeadFactory.getOnlineHead(f);
// 检查这是否是第一个消息,如果是,则需要闪烁tray icon,同时还要
// 在tab上闪烁图标,还要在friend上跳动一个图标,如果不是,则
// 不需要闪动tray icon,但是其他两个还是要的。如果当前好友已经
// 有其他消息还没有读,则声音提示就免掉
if(!mq.hasNext())
uiHelper.startBlinkImage(HeadFactory.getOnlineSmallHead(f));
if(blinkable) {
blindHelper.startBlinkGroupImage(f.group, head);
blindHelper.startBlinkText(f.group);
if(!blindHelper.hasAnimation(f)) {
blindHelper.startBounceImage(f);
main.getSounder().play(LumaQQ.MSG_SOUND);
}
}
// 推入队列
mq.putMessage(packet);
}
/**
* 推入一条消息并更新各种图标的闪烁状态,这个方法会检查是否好友列表已经
* 得到,如果没有,推入延迟队列
*
* @param packet
* 消息包
*/
public void putNormalIM(ReceiveIMPacket packet) {
// 如果现在是延迟处理
MessageQueue mq = main.getMessageQueue();
if(mq.isPostpone()) {
mq.postponeMessage(packet);
return;
}
// 如果这个消息是分片消息,如果这个消息已经完成,则继续处理,否则推入分片缓冲
if(isFragment(packet.normalIM)) {
addFragment(packet.normalIM);
if(isMessageComplete(packet.normalIM.messageId)) {
packet.normalIM = getIntegratedNormalIM(packet.normalIM.messageId);
} else {
return;
}
} else {
packet.normalIM.message = NormalIMFormalizer.deformalize(packet.normalIM.messageBytes);
}
// 得到好友在model中的位置,但是有可能为null,因为也许这是用户的第一次登陆
// 其好友列表还没得到,但是这时候有消息来了,所有也无法闪烁图标了,对于
// 这种情况,需要特殊处理一下,基本的方法是把消息推入延迟处理队列
User f = ModelRegistry.getUser(packet.normalHeader.sender);
boolean iAmHisStranger = packet.header.type == QQ.QQ_RECV_IM_STRANGER;
boolean noSuchUser = f == null || f.group.isCluster();
boolean heIsMyStranger = noSuchUser || f.group.isStranger();
boolean heIsMyBlacklist = f != null && f.group.isBlackList();
if(heIsMyBlacklist || noSuchUser && iAmHisStranger) {
log.debug("收到一个坏人来的消息,忽略");
return;
}
// 检查陌生人消息设置
BlindHelper blindHelper = main.getBlindHelper();
OptionHelper options = main.getOptionHelper();
if(heIsMyStranger && options.isRejectStranger())
return;
// 如果不存在这个用户,添加到陌生人
if(noSuchUser) {
f = new User();
f.qq = packet.normalHeader.sender;
f.nick = String.valueOf(f.qq);
f.displayName = f.nick;
blindHelper.addUser(f, GroupType.STRANGER_GROUP);
main.getBlindHelper().refreshGroup(f.group);
main.getClient().getUserInfo(f.qq);
}
// 保存到聊天记录中,使用当前时间
// 本来以前是使用包中的时间的,但是每个人的机器都不一样,所以往往记录就乱了
// 现在使用收到的时间,其实也有问题,对于那些留言就不太好判断时间了(没有太好的办法,不是没有办法)
RecordEntry entry = new RecordEntry();
entry.type = IKeyConstants.NORMAL;
entry.owner = f.qq;
entry.sender = f.qq;
entry.senderParent = 0;
entry.receiver = main.getMyModel().qq;
entry.time = System.currentTimeMillis();
entry.message = packet.normalIM.message;
main.getRecordManager().addRecord(entry);
ShellRegistry shellRegistry = main.getShellRegistry();
UIHelper uiHelper = main.getUIHelper();
QQClient client = main.getClient();
boolean useTabIM = main.getOptionHelper().isUseTabIMWindow();
// 如果最近联系人功能是打开的,添加到最近联系人中
if(options.isEnableLatest() && (!heIsMyStranger || (heIsMyStranger && options.isKeepStrangerInLatest())))
blindHelper.updateLatest(f);
// 在这里要检查好友的发送消息状态,如果在这个时候,好友的发送消息窗口是打开的
// 并且与好友处于聊天模式中,那么就直接把这个消息推到这个窗口,而不需要再
// 闪烁图标了
if(!useTabIM && shellRegistry.hasSendIMWindow(f) && f.talkMode) {
// 得到发送消息窗口实例
SendIMWindow sms = shellRegistry.getSendIMWindow(f);
// 在把这条消息推入窗口之前,我们还需要检查是否之前还有这个好友的消息,这种情况是
// 可能的,发生在用户开始处于消息模式,后来处于聊天模式,而这之间有消息未读时
while(mq.hasMessage(f.qq)) {
ReceiveIMPacket p = (ReceiveIMPacket)mq.getMessage(f.qq);
sms.appendMessage(f, p.normalIM, p.normalHeader);
}
// 现在轮到把这条消息推入窗口中了
sms.appendMessage(f, packet.normalIM, packet.normalHeader);
// 停止跳动和闪烁头像
blindHelper.getViewer(f).stopAnimation(f);
blindHelper.resetGroupImageEffect(f.group);
uiHelper.resetTrayImageEffect();
// 如果聊天窗口当前不是active的,闪烁图标并播放声音提示用户有消息到来
if(!sms.isActive()) {
sms.startBlinkImage();
main.getSounder().play(LumaQQ.MSG_SOUND);
}
return;
} else if(useTabIM && shellRegistry.isSendIMTabWindowOpened()) {
// 推入消息
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -