package com.client.tok.tox; import com.client.tok.bean.ContactInfo; import com.client.tok.bean.ContactsKey; import com.client.tok.bean.ToxAddress; import com.client.tok.constant.MessageType; import com.client.tok.db.repository.InfoRepository; import com.client.tok.notification.NotifyManager; import com.client.tok.pagejump.GlobalParams; import com.client.tok.ui.chat2.timer.MsgTimer; import com.client.tok.ui.offlinecore.OfflineBuilder; import com.client.tok.utils.ByteUtil; import com.client.tok.utils.LogUtil; import com.client.tok.utils.StringUtils; import im.tox.proto.Core; import im.tox.tox4j.core.data.ToxFriendMessage; import im.tox.tox4j.core.data.ToxNickname; import io.reactivex.Observable; import io.reactivex.ObservableEmitter; import io.reactivex.ObservableOnSubscribe; import io.reactivex.schedulers.Schedulers; import java.util.ArrayList; import java.util.List; import static com.client.tok.tox.ToxCoreBase.SEND_MSG_FAIL; public class MsgHelper { private static String TAG = "MsgHelper"; public static void receiveMessage(ContactInfo friendInfo, String message, MessageType messageType, long messageId, long timeStamp) { InfoRepository infoRepo = State.infoRepo(); //black list:not receive message String senderKey = friendInfo.getKey().key; if (!infoRepo.isContactBlocked(senderKey)) { boolean chatActive = State.isChatActive(senderKey); String senderName = friendInfo.getDisplayName(); infoRepo.addMessage2(friendInfo.getKey(), friendInfo.getKey(), ToxNickname.unsafeFromValue(senderName.getBytes()), message, timeStamp, GlobalParams.SEND_SUCCESS, chatActive, messageType, messageId); if (!chatActive) { int unreadCount = infoRepo.totalUnreadCount(); NotifyManager.getInstance() .createMsgNotify(GlobalParams.CHAT_FRIEND, senderKey, senderName, message, unreadCount); } } } public static void sendFriendMessage(ContactsKey receiverKey, boolean onLine, String msg, MessageType msgType) { sendMessage(receiverKey, onLine, msg, msgType, true); } public static void sendGroupMessage(ContactsKey groupKey, String msg, MessageType msgType) { sendMessage(groupKey, false, msg, msgType, false); } private static void sendMessage(final ContactsKey receiverKey, final boolean onLine, final String msg, final MessageType msgType, final boolean isFriend) { final ToxManager manager = ToxManager.getManager(); final InfoRepository infoRepo = State.infoRepo(); for (final String splitMsg : splitMessage(msg)) { ContactsKey senderKey = manager.toxBase.getSelfKey(); ToxNickname senderName = manager.toxBase.getName(); final long dbId = infoRepo.addMessage(receiverKey, senderKey, senderName, splitMsg, GlobalParams.SEND_ING, true, msgType, -2);//can't -1 Observable.create(new ObservableOnSubscribe<Object>() { @Override public void subscribe(ObservableEmitter<Object> emitter) throws Exception { long id = 0; if (isFriend) { if (onLine) { id = manager.toxBase.friendSendMessage(receiverKey, ToxFriendMessage.unsafeFromValue(splitMsg.getBytes()), MessageType.toToxMessageType(msgType)); } else { id = manager.toxBase.generateUniqueId(receiverKey); ContactsKey botKey = new ToxAddress(GlobalParams.OFFLINE_BOT_TOK_ID).getKey(); //ignore the id LogUtil.i(TAG, "botKey:" + botKey.getKey() + ",offlineMsgId:" + id); manager.toxBase.friendSendMessageOffline(botKey, OfflineBuilder.offlineMsgSend(id, receiverKey.getKey(), splitMsg)); } } if (id > 0) { infoRepo.setMessageSending(id, dbId); MsgTimer.startTimer(id); } else { infoRepo.setMessageFailByDbId(dbId); } emitter.onComplete(); } }).subscribeOn(Schedulers.io()).subscribe(); } } public static int sendBackgroundCmd(String receiveKey, byte[] msgBytes, MessageType msgType) { if (!StringUtils.isEmpty(receiveKey) && msgBytes != null && msgBytes.length > 0) { final ToxManager manager = ToxManager.getManager(); try { return manager.toxBase.friendSendMessage(new ContactsKey(receiveKey), ToxFriendMessage.unsafeFromValue(msgBytes), MessageType.toToxMessageType(msgType)); } catch (Exception e) { e.printStackTrace(); } } return SEND_MSG_FAIL; } public static int sendOfflineCmd(String receiveKey, Core.FriendMessageOffline offlineInfo) { if (!StringUtils.isEmpty(receiveKey) && offlineInfo != null) { final ToxManager manager = ToxManager.getManager(); try { return manager.toxBase.friendSendMessageOffline(new ContactsKey(receiveKey), offlineInfo); } catch (Exception e) { e.printStackTrace(); } } return SEND_MSG_FAIL; } private static List<String> splitMessage(String msg) { List<String> result = new ArrayList<>(); try { int currSplitPos = 0; byte[] msgBytes = msg.getBytes("UTF-8"); while (msgBytes.length - currSplitPos > GlobalParams.MAX_MESSAGE_LENGTH) { int pos = currSplitPos + GlobalParams.MAX_MESSAGE_LENGTH; while ((msgBytes[pos] & 0xc0) == 0x80) { pos--; } String str = new String(ByteUtil.byteSplit(msgBytes, currSplitPos, pos)); result.add(str); currSplitPos = pos; } if (msgBytes.length - currSplitPos > 0) { result.add(new String(ByteUtil.byteSplit(msgBytes, currSplitPos))); } } catch (Exception e) { e.printStackTrace(); } return result; } }