├── src ├── Person.java ├── com │ └── tencent │ │ └── mobileqq │ │ └── data │ │ ├── MarkFaceMessage.java │ │ └── MessageForReplyText.java ├── MarkFaceMessage.java ├── QEmotion.java ├── PokeMessage.java ├── VoiceMessage.java ├── PictureMessage.java ├── Message.java ├── MessageWrapper.java ├── ReplyLink.java ├── MixedMessage.java ├── Voice.java ├── MarkFace.java ├── ReplyMessage.java ├── TextMessage.java ├── MiscMessageHandle.java ├── RichMsgHandle.proto ├── ForwardMessage.java ├── FriendManager.java ├── GlobalValues.java ├── Picture.java ├── MessageStack.java ├── Main.java ├── RawMessage.java └── res │ └── face_config.json ├── LICENSE └── README.md /src/Person.java: -------------------------------------------------------------------------------- 1 | public class Person { 2 | public final String uin; 3 | public final String nickName; 4 | 5 | public Person(String uin, String nickName) { 6 | this.uin = uin; 7 | this.nickName = nickName; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/com/tencent/mobileqq/data/MarkFaceMessage.java: -------------------------------------------------------------------------------- 1 | package com.tencent.mobileqq.data; 2 | 3 | import java.io.Serializable; 4 | 5 | public class MarkFaceMessage implements Serializable { 6 | public static final long serialVersionUID = 102222; 7 | public String faceName; 8 | public int dwTabID; 9 | public byte[] sbufID; 10 | public int imageHeight; 11 | public int imageWidth; 12 | } 13 | -------------------------------------------------------------------------------- /src/MarkFaceMessage.java: -------------------------------------------------------------------------------- 1 | public class MarkFaceMessage extends Message { 2 | public MarkFace markFace; 3 | 4 | public MarkFaceMessage(Person sender, long time, long uniseq, long msgUid, byte[] data) { 5 | super(sender, time, uniseq, msgUid); 6 | markFace = new MarkFace(data); 7 | } 8 | 9 | @Override 10 | public String toString() { 11 | return "" + sender.nickName + "(" + sender.uin + "):" + markFace; 12 | } 13 | 14 | @Override 15 | public String printToHtml() { 16 | return GlobalValues.HtmlFormattingText.MARKFACE_MESSAGE_HTML.replace("{MARKFACE_MESSAGE_CONTENT}", markFace.toString()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/com/tencent/mobileqq/data/MessageForReplyText.java: -------------------------------------------------------------------------------- 1 | package com.tencent.mobileqq.data; 2 | 3 | import java.io.Serializable; 4 | 5 | public class MessageForReplyText { 6 | public class SourceMsgInfo implements Serializable { 7 | public static final long serialVersionUID = 1; 8 | private byte[] mSourceMessageByte; 9 | public long mSourceMsgSenderUin; 10 | public long mSourceMsgSeq; 11 | public String mSourceMsgText; 12 | public int mSourceMsgTime; 13 | public long mSourceMsgToUin; 14 | public String mSourceMsgTroopName; 15 | public int mSourceSummaryFlag = 1; 16 | public int mType = 0; 17 | public int oriMsgType; 18 | public long origUid; 19 | public int replyPicHeight; 20 | public int replyPicWidth; 21 | private long uniseq = 0; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/QEmotion.java: -------------------------------------------------------------------------------- 1 | public class QEmotion { 2 | private final String QSid; 3 | private final String QDes; 4 | private final String IQLid; 5 | private final String AQLid; 6 | private final String EMCode; 7 | 8 | public QEmotion() { 9 | QSid = "9999"; 10 | QDes = "未知表情"; 11 | IQLid = "9999"; 12 | AQLid = "9999"; 13 | EMCode = "9999"; 14 | } 15 | 16 | public QEmotion(String AQLid) { 17 | QSid = AQLid; 18 | QDes = "未知表情"; 19 | IQLid = AQLid; 20 | this.AQLid = AQLid; 21 | EMCode = AQLid; 22 | } 23 | 24 | public String getQSid() { 25 | return QSid; 26 | } 27 | 28 | public String getQDes() { 29 | return QDes; 30 | } 31 | 32 | public String getIQLid() { 33 | return IQLid; 34 | } 35 | 36 | public String getAQLid() { 37 | return AQLid; 38 | } 39 | 40 | public String getEMCode() { 41 | return EMCode; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/PokeMessage.java: -------------------------------------------------------------------------------- 1 | import com.google.gson.JsonParser; 2 | import com.google.gson.JsonSyntaxException; 3 | 4 | public class PokeMessage extends Message { 5 | private final String pokeJson; 6 | 7 | public PokeMessage(Person sender, long time, long uniseq, long msgUid, String pokeJson) { 8 | super(sender, time, uniseq, msgUid); 9 | this.pokeJson = pokeJson; 10 | } 11 | 12 | @Override 13 | public String toString() { 14 | return "" + sender.nickName + "(" + sender.uin + "):" + printToHtml(); 15 | } 16 | 17 | @Override 18 | public String printToHtml() { 19 | try { 20 | return GlobalValues.HtmlFormattingText.POKE_MESSAGE_HTML.replace("{POKE_MESSAGE_CONTENT}", new JsonParser().parse(pokeJson).getAsJsonObject().get("msg").getAsString()); 21 | } catch (JsonSyntaxException e) { 22 | return GlobalValues.HtmlFormattingText.POKE_MESSAGE_HTML.replace("{POKE_MESSAGE_CONTENT}", "[戳一戳]"); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/VoiceMessage.java: -------------------------------------------------------------------------------- 1 | import com.google.protobuf.InvalidProtocolBufferException; 2 | 3 | public class VoiceMessage extends Message { 4 | public Voice voice; 5 | 6 | public VoiceMessage(Person sender, long time, long uniseq, long msgUid, byte[] data) { 7 | super(sender, time, uniseq, msgUid); 8 | try { 9 | voice = new Voice(RichMsgHandle.PttRec.parseFrom(data)); 10 | } catch (InvalidProtocolBufferException e) { 11 | //this should not happen too 12 | voice = new Voice(); 13 | e.printStackTrace(); 14 | } 15 | } 16 | 17 | @Override 18 | public String toString() { 19 | return "" + sender.nickName + "(" + sender.uin + "):" + voice; 20 | } 21 | 22 | @Override 23 | public String printToHtml() { 24 | return GlobalValues.HtmlFormattingText.VOICE_MESSAGE_HTML.replace("{VOICE_MESSAGE_CONTENT}", voice.toString()); 25 | } 26 | 27 | @Override 28 | public String getExternalOperationCmdline() { 29 | return voice.getExternalOperationCmdline(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/PictureMessage.java: -------------------------------------------------------------------------------- 1 | import com.google.protobuf.InvalidProtocolBufferException; 2 | 3 | public class PictureMessage extends Message { 4 | public Picture picture; 5 | 6 | public PictureMessage(Person sender, long time, long uniseq, long msgUid, byte[] data) { 7 | super(sender, time, uniseq, msgUid); 8 | try { 9 | picture = new Picture(RichMsgHandle.PicRec.parseFrom(data)); 10 | } catch (InvalidProtocolBufferException e) { 11 | //this should not happen 12 | picture = new Picture(); 13 | e.printStackTrace(); 14 | } 15 | } 16 | 17 | @Override 18 | public String toString() { 19 | return "" + sender.nickName + "(" + sender.uin + "):" + picture; 20 | } 21 | 22 | @Override 23 | public String printToHtml() { 24 | return GlobalValues.HtmlFormattingText.PICTURE_MESSAGE_HTML.replace("{PICTURE_MESSAGE_CONTENT}", picture.toString()); 25 | } 26 | 27 | @Override 28 | public String getExternalOperationCmdline() { 29 | return picture.getExternalOperationCmdline(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 ZhangJun2017 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/Message.java: -------------------------------------------------------------------------------- 1 | import java.util.Comparator; 2 | 3 | public abstract class Message { 4 | public final Person sender; 5 | public final long time; 6 | public final long uniseq; 7 | public final long msgUid; 8 | 9 | public Message(Person sender, long time, long uniseq, long msgUid) { 10 | this.sender = sender; 11 | this.time = time; 12 | this.uniseq = uniseq; 13 | this.msgUid = msgUid; 14 | } 15 | 16 | @Override 17 | public abstract String toString(); 18 | //return "[" + time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + "]" + sender.nickName + "(" + sender.uin + "):"; 19 | 20 | public void printToConsole() { 21 | System.out.println(this); 22 | } 23 | 24 | public abstract String printToHtml(); 25 | 26 | public String getExternalOperationCmdline() { 27 | return ""; 28 | } 29 | } 30 | 31 | class SequenceOrderedComparator implements Comparator { 32 | public int compare(Message o1, Message o2) { 33 | if (o1.time > o2.time) { 34 | return 1; 35 | } else if (o1.time < o2.time) { 36 | return -1; 37 | } else { 38 | if (o1.uniseq > o2.uniseq) { 39 | return 1; 40 | } else return -1; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/MessageWrapper.java: -------------------------------------------------------------------------------- 1 | import com.google.gson.Gson; 2 | import com.google.gson.JsonParser; 3 | import com.google.gson.reflect.TypeToken; 4 | import com.google.gson.stream.JsonReader; 5 | 6 | import java.io.InputStreamReader; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class MessageWrapper { 11 | public MessageStack messages; 12 | public final Person host; 13 | public final Person opposite; 14 | 15 | public MessageWrapper(MessageStack messages, Person host, Person opposite) { 16 | this.messages = messages; 17 | this.host = host; 18 | this.opposite = opposite; 19 | } 20 | 21 | public String printToHtml() { 22 | StringBuilder htmlBuilder = new StringBuilder(); 23 | String htmlTitle = GlobalValues.HtmlFormattingText.HTML_TITLE.replace("{HOST_NICKNAME}", host.nickName).replace("{HOST_UIN}", host.uin).replace("{OPPOSITE_NICKNAME}", opposite.nickName).replace("{OPPOSITE_UIN}", opposite.uin); 24 | htmlBuilder.append(GlobalValues.HtmlFormattingText.HTML_FILE_HEADER.replace("{HTML_TITLE}", htmlTitle)); 25 | ArrayList emotionConfig = new Gson().fromJson(new JsonParser().parse(new JsonReader(new InputStreamReader(Main.class.getResourceAsStream("face_config.json")))).getAsJsonObject().get("sysface").getAsJsonArray(), new TypeToken>() { 26 | }.getType()); 27 | htmlBuilder.append(messages.replaceEmotion(messages.printToHtml(host), emotionConfig)); 28 | htmlBuilder.append(GlobalValues.HtmlFormattingText.HTML_FILE_FOOTER); 29 | return htmlBuilder.toString(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QQChatHistoryExporter 2 | 手机QQ聊天记录导出,在现有项目基础上增加对语音消息和转发聊天记录的支持,不支持群聊导出,下载 3 | [本体](https://github.com/ZhangJun2017/QQChatHistoryExporter/releases/download/v1.2/QQChatHistoryExporter_v1.2.jar) [附加包](https://github.com/ZhangJun2017/QQChatHistoryExporter/releases/download/v1.1/QQChatHistoryExporter_v1.1_extra.zip) 4 | ,需要Java环境 5 | 6 | ## 使用方法 7 | * 通过root或者其他途径取得 8 | >数据库文件 9 | >``` 10 | >/data/data/com.tencent.mobileqq/databases/QQ号.db 11 | >/data/data/com.tencent.mobileqq/databases/slowtable_QQ号.db 12 | >``` 13 | > 14 | >密钥 15 | >``` 16 | >/data/data/com.tencent.mobileqq/files/kc 17 | >``` 18 | 19 | * 如果需要导出图片 20 | >将此文件夹复制到资源目录下 21 | >``` 22 | >内置储存/Android/data/com.tencent.mobileqq/Tencent/MobileQQ/chatpic 23 | >``` 24 | 25 | * 如果需要导出语音 26 | >将此文件夹复制到资源目录下 27 | >``` 28 | >内置储存/Android/data/com.tencent.mobileqq/Tencent/MobileQQ/QQ号/ptt 29 | >``` 30 | >并解压附加包内的 `silk_v3_decoder.exe` `ffmpeg.exe` 到资源目录下 31 | 32 | * 在命令提示符内执行 `java -Dfile.encoding=UTF-8 -jar 本体jar路径` 33 | 34 | * 填入`数据库路径`,`资源路径`,`输出路径`,`密钥文件的内容`,`自己的QQ号`和`导出对象的QQ号` 35 | 36 | * 等待导出。将自动复制图片、转发的聊天记录和语音消息,意外中断的话可以手动再次执行输出目录下的 `exop.bat` 37 | 38 | * 如果需要显示QQ自带表情 39 | >解压附加包内的 `emotion` 文件夹到输出目录下 `assets` 文件夹内 40 | 41 | ## 说明 42 | 导出的文件以 `QQ号.html` 命名,迁移时也要一并包括 `assets` 文件夹 43 | 44 | *** 45 | **感谢 [Yiyiyimu/QQ-History-Backup](https://github.com/Yiyiyimu/QQ-History-Backup) 及其所基于的项目,本项目核心部分和附加包内QQ自带表情资源完全来自该项目** 46 | 47 | **感谢 [kn007/silk-v3-decoder](https://github.com/kn007/silk-v3-decoder) 和 [FFmpeg/FFmpeg](https://github.com/FFmpeg/FFmpeg) ,附加包内解码语音消息所需的可执行文件 `silk_v3_decoder.exe` `ffmpeg.exe` 来自这两个项目** 48 | -------------------------------------------------------------------------------- /src/ReplyLink.java: -------------------------------------------------------------------------------- 1 | import com.tencent.mobileqq.data.MessageForReplyText; 2 | 3 | import java.io.ByteArrayInputStream; 4 | import java.io.IOException; 5 | import java.io.ObjectInputStream; 6 | 7 | public class ReplyLink { 8 | public long mSourceMsgSenderUin; 9 | public String mSourceMsgText; 10 | public long mSourceMsgTime; 11 | public long origUid; 12 | public String replyToName; 13 | 14 | public ReplyLink(byte[] data, FriendManager friendManager) { 15 | try { 16 | MessageForReplyText.SourceMsgInfo sourceMsgInfo = (MessageForReplyText.SourceMsgInfo) new ObjectInputStream(new ByteArrayInputStream(data)).readObject(); 17 | mSourceMsgSenderUin = sourceMsgInfo.mSourceMsgSenderUin; 18 | mSourceMsgText = sourceMsgInfo.mSourceMsgText; 19 | mSourceMsgTime = sourceMsgInfo.mSourceMsgTime; 20 | origUid = sourceMsgInfo.origUid; 21 | replyToName = friendManager.getPersonByUinPrefill(String.valueOf(mSourceMsgSenderUin)).nickName; 22 | } catch (IOException | ClassNotFoundException e) { 23 | mSourceMsgSenderUin = -1; 24 | mSourceMsgText = ""; 25 | mSourceMsgTime = 0; 26 | origUid = -1; 27 | replyToName = "未知"; 28 | e.printStackTrace(); 29 | } 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return GlobalValues.HtmlFormattingText.REPLY_LINK_HTML.replace("{LINK_MSGUID}", String.valueOf(origUid)).replace("{REPLY_LINK_TITLE}", "回复 #" + origUid + " 的消息").replace("{SOURCE_MSG_INFO}", replyToName + " " + MessageStack.generalTimeFormat(mSourceMsgTime)).replace("{SOURCE_MSG_BRIEF}", TextMessage.escapeHtml(mSourceMsgText)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/MixedMessage.java: -------------------------------------------------------------------------------- 1 | import com.google.protobuf.InvalidProtocolBufferException; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class MixedMessage extends Message { 7 | private List elemList; 8 | 9 | public MixedMessage(Person sender, long time, long uniseq, long msgUid, byte[] data) { 10 | super(sender, time, uniseq, msgUid); 11 | try { 12 | elemList = RichMsgHandle.Msg.parseFrom(data).getElemsList(); 13 | } catch (InvalidProtocolBufferException e) { 14 | elemList = new ArrayList<>(); 15 | e.printStackTrace(); 16 | } 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return "" + sender.nickName + "(" + sender.uin + "):" + printToHtml(); 22 | } 23 | 24 | @Override 25 | public String printToHtml() { 26 | StringBuilder stringBuilder = new StringBuilder(); 27 | for (RichMsgHandle.Elem elem : elemList) { 28 | if (elem.hasPicMsg()) { 29 | stringBuilder.append(new Picture(elem.getPicMsg()).toString()); 30 | } else { 31 | stringBuilder.append(TextMessage.escapeHtml(elem.getTextMsg())); 32 | } 33 | } 34 | return GlobalValues.HtmlFormattingText.MIXED_MESSAGE_HTML.replace("{MIXED_MESSAGE_CONTENT}", stringBuilder.toString()); 35 | } 36 | 37 | @Override 38 | public String getExternalOperationCmdline() { 39 | StringBuilder stringBuilder = new StringBuilder(); 40 | for (RichMsgHandle.Elem elem : elemList) { 41 | if (elem.hasPicMsg()) { 42 | stringBuilder.append(new Picture(elem.getPicMsg()).getExternalOperationCmdline()); 43 | } 44 | } 45 | return stringBuilder.toString(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Voice.java: -------------------------------------------------------------------------------- 1 | public class Voice { 2 | public String localPath; 3 | public String sttText; 4 | public int voiceLength; 5 | public String filePath = ""; 6 | public String fileName; 7 | private RichMsgHandle.PttRec parser = null; 8 | 9 | public Voice() { 10 | localPath = ""; 11 | sttText = "无效语音消息"; 12 | } 13 | 14 | public Voice(RichMsgHandle.PttRec parser) { 15 | this.parser = parser; 16 | localPath = parser.getLocalPath(); 17 | sttText = parser.getSttText(); 18 | voiceLength = parser.getVoiceLength(); 19 | String[] pathArr = localPath.split("/"); 20 | for (int i = pathArr.length - 2; i >= 0; i--) { 21 | if (pathArr[i].equals("ptt")) { 22 | for (int j = i + 1; j < pathArr.length - 1; j++) { 23 | filePath += pathArr[j] + "\\"; 24 | } 25 | fileName = pathArr[pathArr.length - 1].substring(0, pathArr[pathArr.length - 1].length() - 4); 26 | filePath += fileName; 27 | i = -1; 28 | } 29 | } 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return GlobalValues.HtmlFormattingText.VOICE_HTML.replace("{VOICE_SRC}", GlobalValues.AssetsPath.VOICE_PATH + fileName + ".mp3").replace("{VOICE_TITLE}", "时长 " + voiceLength + "秒 的语音消息").replace("{STT_TEXT}", sttText); 35 | } 36 | 37 | public String getExternalOperationCmdline() { 38 | return "copy /Y \"\\ptt\\" + filePath + ".slk\" \"" + System.getProperty("java.io.tmpdir") + "\\" + fileName + ".slk\" >nul\r\n" + " \"" + System.getProperty("java.io.tmpdir") + "\\" + fileName + ".slk\" \"" + System.getProperty("java.io.tmpdir") + "\\" + fileName + ".pcm" + "\" -quiet>nul\r\n" + " -loglevel quiet -y -f s16le -ar 24000 -ac 1 -i \"" + System.getProperty("java.io.tmpdir") + "\\" + fileName + ".pcm" + "\" -ar 24000 -b:a 320k \"" + System.getProperty("java.io.tmpdir") + "\\" + fileName + ".mp3\" >nul\r\n" + "move /Y \"" + System.getProperty("java.io.tmpdir") + "\\" + fileName + ".mp3" + "\" \"\\voice\\" + fileName + ".mp3" + "\" >nul\r\n" + "del \"" + System.getProperty("java.io.tmpdir") + "\\" + fileName + ".slk\" \"" + System.getProperty("java.io.tmpdir") + "\\" + fileName + ".pcm\" >nul\r\n"; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/MarkFace.java: -------------------------------------------------------------------------------- 1 | import com.tencent.mobileqq.data.MarkFaceMessage; 2 | 3 | import java.io.ByteArrayInputStream; 4 | import java.io.IOException; 5 | import java.io.ObjectInputStream; 6 | 7 | public class MarkFace { 8 | public String faceName; 9 | public int dwTabID; 10 | public byte[] sbufID; 11 | public int imageHeight; 12 | public int imageWidth; 13 | public String url; 14 | 15 | public MarkFace(byte[] data) { 16 | try { 17 | MarkFaceMessage markFaceMessage = (MarkFaceMessage) new ObjectInputStream(new ByteArrayInputStream(data)).readObject(); 18 | faceName = markFaceMessage.faceName; 19 | dwTabID = markFaceMessage.dwTabID; 20 | sbufID = markFaceMessage.sbufID; 21 | imageHeight = markFaceMessage.imageHeight; 22 | imageWidth = markFaceMessage.imageWidth; 23 | try { 24 | url = "https://i.gtimg.cn/club/item/parcel/item/" + toHexString(sbufID).substring(0, 2) + "/" + toHexString(sbufID) + "/" + imageWidth + "x" + imageHeight + ".png"; 25 | } catch (StringIndexOutOfBoundsException e) { 26 | //reply to some specific messages in PCQQ using markface will lead to invalid markface message 27 | faceName = "[表情]" + markFaceMessage.faceName; 28 | dwTabID = markFaceMessage.dwTabID; 29 | url = ""; 30 | e.printStackTrace(); 31 | } 32 | } catch (ClassNotFoundException | IOException e) { 33 | faceName = "[表情]" + hanziExtract(new String(data)); 34 | dwTabID = -1; 35 | url = ""; 36 | e.printStackTrace(); 37 | } 38 | } 39 | 40 | public static String hanziExtract(String str) { 41 | return str.replaceAll("[^\u4e00-\u9fa5]", ""); 42 | } 43 | 44 | public static String toHexString(byte[] arr) { 45 | StringBuffer toReturn = new StringBuffer(); 46 | for (byte b : arr) { 47 | String byteHex = "00" + Integer.toHexString(b & 0xff); 48 | toReturn.append(byteHex.substring(byteHex.length() - 2)); 49 | } 50 | return toReturn.toString(); 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | return GlobalValues.HtmlFormattingText.MARKFACE_HTML.replace("{MARKFACE_SRC}", url).replace("{MARKFACE_ALT}", faceName).replace("{MARKFACE_TITLE}", dwTabID + " -> " + faceName); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/ReplyMessage.java: -------------------------------------------------------------------------------- 1 | import com.google.gson.JsonElement; 2 | import com.google.gson.JsonParser; 3 | import com.google.gson.JsonSyntaxException; 4 | 5 | public class ReplyMessage extends Message { 6 | public final String content; 7 | public final String extStr; 8 | public ReplyLink replyLink; 9 | 10 | public ReplyMessage(Person sender, long time, long uniseq, long msgUid, String content, String extStr, FriendManager friendManager) { 11 | super(sender, time, uniseq, msgUid); 12 | this.content = content; 13 | this.extStr = extStr; 14 | this.replyLink = new ReplyLink(RawMessage.hexStringToByteArray(sourceMsgInfoExtract(extStr)), friendManager); 15 | } 16 | 17 | public static String sourceMsgInfoParse(String json) { 18 | //ideal situation 19 | try { 20 | JsonElement sens_msg_source_msg_info; 21 | sens_msg_source_msg_info = new JsonParser().parse(json).getAsJsonObject().get("sens_msg_source_msg_info"); 22 | if (sens_msg_source_msg_info == null) { 23 | return ""; 24 | } else { 25 | return sens_msg_source_msg_info.toString(); 26 | } 27 | } catch (JsonSyntaxException | IllegalStateException e) { 28 | e.printStackTrace(); 29 | return ""; 30 | } 31 | } 32 | 33 | public static String sourceMsgInfoExtract(String json) { 34 | if (json == null) { 35 | return ""; 36 | } 37 | String[] jsonSplit = json.split(","); 38 | if (jsonSplit.length >= 1) { 39 | for (int i = 0; i < jsonSplit.length; i++) { 40 | if (jsonSplit[i].contains("sens_msg_source_msg_info")) { 41 | String[] jsonFieldSplit = jsonSplit[i].split("\""); 42 | if (jsonFieldSplit.length >= 4 && jsonFieldSplit[3].contains("ACED")) { 43 | return jsonFieldSplit[3]; 44 | } 45 | } 46 | } 47 | } 48 | return ""; 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return "" + sender.nickName + "(" + sender.uin + "):" + replyLink + " <- " + content; 54 | } 55 | 56 | @Override 57 | public String printToHtml() { 58 | return GlobalValues.HtmlFormattingText.REPLY_MESSAGE_HTML.replace("{REPLY_LINK}", replyLink.toString()).replace("{REPLY_MESSAGE_CONTENT}", TextMessage.escapeHtml(content)); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/TextMessage.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class TextMessage extends Message { 4 | public final String content; 5 | 6 | public TextMessage(Person sender, long time, long uniseq, long msgUid, String content) { 7 | super(sender, time, uniseq, msgUid); 8 | this.content = content; 9 | } 10 | 11 | public static String escapeHtml(String toEscape) { 12 | if (!toEscape.contains("\u0014")) { 13 | toEscape = toEscape.replace("&", "&"); 14 | toEscape = toEscape.replace("\"", """); 15 | toEscape = toEscape.replace("'", "'"); 16 | toEscape = toEscape.replace(" ", " "); 17 | toEscape = toEscape.replace("<", "<"); 18 | toEscape = toEscape.replace(">", ">"); 19 | toEscape = toEscape.replace("\n", "
"); 20 | return toEscape; 21 | } else { 22 | ArrayList markIndex = new ArrayList<>(); 23 | StringBuilder toReturn = new StringBuilder(""); 24 | for (int i = 0; i < toEscape.length(); i++) { 25 | if (toEscape.charAt(i) == '\u0014' && !markIndex.contains(i - 1)) { //sometimes there are two consecutive \u0014 26 | markIndex.add(i); 27 | } 28 | } 29 | toReturn.append(escapeHtml(toEscape.substring(0, markIndex.get(0)))); //handle first \u0014 separately 30 | for (int i = 0; i < markIndex.size() - 1; i++) { 31 | toReturn.append(toEscape.substring(markIndex.get(i), markIndex.get(i) + 2)); 32 | toReturn.append(escapeHtml(toEscape.substring(markIndex.get(i) + 2, markIndex.get(i + 1)))); 33 | } 34 | if (markIndex.get(markIndex.size() - 1) == toEscape.length() - 1) { //handle last \u0014 separately 35 | //seems like there's a standalone \u0014 appear at the end of the message.... 36 | toReturn.append('\u0014'); 37 | toReturn.append((char) 9999); 38 | } else { 39 | //normal case 40 | toReturn.append(toEscape.substring(markIndex.get(markIndex.size() - 1), markIndex.get(markIndex.size() - 1) + 2)); 41 | toReturn.append(escapeHtml(toEscape.substring(markIndex.get(markIndex.size() - 1) + 2, toEscape.length()))); 42 | } 43 | return toReturn.toString(); 44 | } 45 | } 46 | 47 | @Override 48 | public String toString() { 49 | return "" + sender.nickName + "(" + sender.uin + "):" + content; 50 | } 51 | 52 | @Override 53 | public String printToHtml() { 54 | return GlobalValues.HtmlFormattingText.TEXT_MESSAGE_HTML.replace("{TEXT_MESSAGE_CONTENT}", escapeHtml(content)); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/MiscMessageHandle.java: -------------------------------------------------------------------------------- 1 | import com.google.protobuf.InvalidProtocolBufferException; 2 | 3 | public class MiscMessageHandle { 4 | public static Message parse(Person sender, long time, long uniseq, long msgUid, String msgtype, byte[] msgData) { 5 | String msgStr = new String(msgData); 6 | String[] msgArr; 7 | Person system = new Person("10000", "系统提示"); 8 | Message toReturn; 9 | switch (msgtype) { 10 | case "-2009": 11 | msgArr = msgStr.split("\\|"); 12 | if (msgArr.length >= 4) { 13 | toReturn = new TextMessage(sender, time, uniseq, msgUid, (msgArr[3].equals("0") ? "[语音通话]" : msgArr[3].equals("1") ? "[视频通话]" : "[通话]") + msgArr[0].substring(1)); 14 | } else { 15 | toReturn = new TextMessage(sender, time, uniseq, msgUid, "[通话]"); 16 | } 17 | break; 18 | case "-5008": 19 | toReturn = new TextMessage(sender, time, uniseq, msgUid, "[分享卡片]"); 20 | break; 21 | case "-2005": 22 | msgArr = msgStr.split("\\|"); 23 | toReturn = new TextMessage(sender, time, uniseq, msgUid, "[文件]大小:" + (msgArr.length == 5 ? msgArr[1] + "字节" : "未知") + ",本地路径:" + (msgStr.startsWith("\u0016") ? msgArr[0].substring(1) : "未知")); 24 | break; 25 | case "-3008": 26 | toReturn = new TextMessage(system, time, uniseq, msgUid, "对方已成功接收文件 \"" + msgStr + "\""); 27 | break; 28 | case "-2022": 29 | try { 30 | RichMsgHandle.ShortVideo shortVideo = RichMsgHandle.ShortVideo.parseFrom(msgData); 31 | toReturn = new TextMessage(sender, time, uniseq, msgUid, "[短视频]大小:" + shortVideo.getFileSize() + "字节,本地路径:" + shortVideo.getLocalPath()); 32 | } catch (InvalidProtocolBufferException e) { 33 | toReturn = new TextMessage(sender, time, uniseq, msgUid, "[短视频]解析失败"); 34 | } 35 | break; 36 | case "-5040": 37 | try { 38 | RichMsgHandle.Tip tip = RichMsgHandle.Tip.parseFrom(msgData); 39 | toReturn = new TextMessage(system, time, uniseq, msgUid, tip.getTip() + (tip.getRecallInfo().getRecallDetail().equals("") ? "" : "(" + tip.getRecallInfo().getRecallDetail() + ")")); 40 | } catch (InvalidProtocolBufferException e) { 41 | toReturn = new TextMessage(system, time, uniseq, msgUid, "解析失败"); 42 | } 43 | break; 44 | default: 45 | toReturn = new TextMessage(sender, time, uniseq, msgUid, "不支持的消息类型:" + msgtype); 46 | break; 47 | } 48 | return toReturn; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/RichMsgHandle.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | message ForwardExtra { 4 | int32 forward_orgId = 1; 5 | string forward_orgUin = 2; 6 | int32 forward_orgUinType = 3; 7 | string forward_orgUrl = 4; 8 | string forward_thumbPath = 5; 9 | int32 forward_orgFileSizeType = 6; 10 | } 11 | 12 | message PicRec { 13 | string localPath = 1; 14 | uint64 size = 2; 15 | uint32 type = 3; 16 | bool isRead = 4; 17 | string uuid = 5; 18 | string md5 = 6; 19 | string serverStorageSource = 7; 20 | string thumbMsgUrl = 8; 21 | string bigMsgUrl = 9; 22 | string rawMsgUrl = 10; 23 | int32 fileSizeFlag = 11; 24 | int32 uiOperatorFlag = 12; 25 | ForwardExtra fowardInfo = 13; 26 | int32 version = 15; 27 | int32 isReport = 16; 28 | uint64 groupFileID = 17; 29 | string localUUID = 18; 30 | int32 preDownState = 19; 31 | int32 preDownNetwork = 20; 32 | int32 previewed = 21; 33 | uint32 uint32_thumb_width = 22; 34 | uint32 uint32_thumb_height = 23; 35 | uint32 uint32_width = 24; 36 | uint32 uint32_height = 25; 37 | uint32 uint32_image_type = 26 ; 38 | uint32 uint32_show_len = 27; 39 | uint32 uint32_download_len = 28; 40 | uint32 uint32_current_len = 29; 41 | uint32 notPredownloadReason = 30; 42 | bool enableEnc = 31; 43 | string bigthumbMsgUrl = 32; 44 | bytes bytes_pb_reserved = 33; 45 | bool bool_story_pic_send_to_recent = 34; 46 | } 47 | 48 | message MessageInfo { 49 | string info = 8; 50 | } 51 | 52 | message PttRec { 53 | string localPath = 1; 54 | uint64 size = 2; 55 | uint32 type = 3; 56 | bool isRead = 4; 57 | string uuid = 5; 58 | string md5 = 6; 59 | string serverStorageSource = 7; 60 | int32 version = 8; 61 | int32 isReport = 9; 62 | int32 pttFlag = 10; 63 | uint64 groupFileID = 11; 64 | string sttText = 12; 65 | int32 longPttVipFlag = 13; 66 | bool expandStt = 14; 67 | string group_file_key = 15; 68 | uint64 msgRecTime = 16; 69 | uint64 msgTime = 17; 70 | uint32 voiceType = 18; 71 | uint32 voiceLength = 19; 72 | uint32 voiceChangeFlag = 20; 73 | string directUrl = 21; 74 | uint32 busiType = 22; 75 | string fullLocalPath = 23; 76 | uint64 extFlag = 24; 77 | uint32 redpack_type = 25; 78 | uint32 autototext_voice = 26; 79 | } 80 | 81 | message MarketFaceRec { 82 | bytes bytes_face_name = 1; 83 | uint32 uint32_item_type = 2; 84 | uint32 uint32_face_info = 3; 85 | bytes bytes_face_id = 4; 86 | uint32 uint32_tab_id = 5; 87 | uint32 uint32_sub_type = 6; 88 | bytes bytes_key = 7; 89 | bytes bytes_param = 8; 90 | uint32 uint32_media_type = 9; 91 | uint32 uint32_image_width = 10; 92 | uint32 uint32_image_height = 11; 93 | } 94 | 95 | message ShortVideo { 96 | string localPath = 3; 97 | uint32 fileSize = 6; 98 | } 99 | 100 | message Tip { 101 | string tip = 5; 102 | RecallInfo recallInfo = 9; 103 | } 104 | 105 | message RecallInfo { 106 | string RecallDetail = 8; 107 | } 108 | 109 | message Elem { 110 | string textMsg = 1; 111 | PicRec picMsg = 2; 112 | MarketFaceRec markfaceMsg = 3; 113 | string sourceMsgInfo = 4; 114 | } 115 | 116 | message Msg { 117 | repeated Elem elems = 1; 118 | } 119 | -------------------------------------------------------------------------------- /src/ForwardMessage.java: -------------------------------------------------------------------------------- 1 | import java.io.IOException; 2 | import java.nio.charset.StandardCharsets; 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | 6 | public class ForwardMessage extends Message { 7 | public final long msgseq; 8 | public MessageStack messages = new MessageStack(); 9 | public static final Person unknown = new Person("未知", "未知"); 10 | public Person host = unknown; 11 | public Person opposite = unknown; 12 | public static final TextMessage invalidForwardMessageNotice = new TextMessage(new Person("", ""), 0, 0, 0, "无效的转发消息"); 13 | 14 | public ForwardMessage(Person sender, long time, long uniseq, long msgseq, long msgUid, String key, FriendManager friendManager, HashMap> multiMsgList, byte[] msgData, boolean isNestedMultiMsg) { 15 | super(sender, time, uniseq, msgUid); 16 | this.msgseq = msgseq; 17 | if (!multiMsgList.containsKey(String.valueOf(uniseq))) { 18 | messages.add(invalidForwardMessageNotice); 19 | messages.add(new TextMessage(new Person("", ""), 0, 1, 0, RawMessage.decryptString(msgData, key))); 20 | return; 21 | } 22 | for (RawMessage message : multiMsgList.get(String.valueOf(uniseq))) { 23 | if (isNestedMultiMsg) { 24 | message.msgseq = String.valueOf(msgseq); 25 | /* force messages in nested forward message to inherit msgseq 26 | in order to handle sender nickname properly,since these names 27 | are stacked only in the top forward message's name map */ 28 | } 29 | Message toAdd = message.parse(key, friendManager, multiMsgList, true); 30 | messages.add(toAdd); 31 | if (host == unknown || opposite == unknown) { 32 | if (message.selfuin.equals(message.senderuin)) { 33 | host = toAdd.sender; 34 | } else { 35 | opposite = toAdd.sender; 36 | } 37 | } 38 | } 39 | } 40 | 41 | public static boolean isForwardMessage(byte[] msgData) { 42 | return new String(msgData, StandardCharsets.UTF_8).contains("viewMultiMsg"); 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return "" + sender.nickName + "(" + sender.uin + "):" + printToHtml(); 48 | } 49 | 50 | @Override 51 | public String printToHtml() { 52 | return GlobalValues.HtmlFormattingText.FORWARD_MESSAGE_HTML.replace("{FORWARD_MESSAGE_HTML_URL}", GlobalValues.AssetsPath.HTML_FILE_PATH + uniseq + ".html").replace("{FORWARD_MESSAGE_COUNT}", String.valueOf(messages.messages.size())); 53 | } 54 | 55 | @Override 56 | public String getExternalOperationCmdline() { 57 | try { 58 | Main.writeFile(new MessageWrapper(messages, host, opposite).printToHtml(), System.getProperty("java.io.tmpdir") + "\\" + uniseq + ".html"); 59 | } catch (IOException e) { 60 | System.err.println("写出转发的聊天记录失败"); 61 | e.printStackTrace(); 62 | } 63 | return messages.getExternalOperationCmdline() + "move /Y \"" + System.getProperty("java.io.tmpdir") + "\\" + uniseq + ".html" + "\" \"\\html\\" + uniseq + ".html" + "\" >nul\r\n"; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/FriendManager.java: -------------------------------------------------------------------------------- 1 | import java.sql.ResultSet; 2 | import java.sql.SQLException; 3 | import java.util.HashMap; 4 | 5 | public class FriendManager { 6 | public HashMap friendNameMap; 7 | public HashMap friendRemarkMap; 8 | public HashMap> friendMapMultiMsg; 9 | public boolean isMultiMsgMode; 10 | public String multiMsgUniseq; 11 | 12 | public FriendManager() { 13 | friendNameMap = new HashMap<>(); 14 | friendRemarkMap = new HashMap<>(); 15 | friendMapMultiMsg = new HashMap<>(); 16 | isMultiMsgMode = false; 17 | multiMsgUniseq = ""; 18 | } 19 | 20 | public Person getPersonByUinPrefill(String uin) { 21 | if (isMultiMsgMode) { 22 | return getPersonByUinMultiMsg(uin, multiMsgUniseq); 23 | } else { 24 | return getPersonByUin(uin); 25 | } 26 | } 27 | 28 | public Person getPersonByUinMultiMsg(String uin, String uniseq) { 29 | if (!getNameByUinMultiMsg(uin, uniseq).equals("")) { 30 | return new Person(uin, getNameByUinMultiMsg(uin, uniseq)); 31 | } else if (!getNameByUin(uin).equals("")) { 32 | return new Person(uin, getNameByUin(uin)); 33 | } else { 34 | return new Person(uin, uin); 35 | } 36 | } 37 | 38 | public String getNameByUinMultiMsg(String uin, String uniseq) { 39 | if (friendMapMultiMsg.containsKey(uniseq)) { 40 | if (friendMapMultiMsg.get(uniseq).containsKey(uin)) { 41 | return friendMapMultiMsg.get(uniseq).get(uin); 42 | } 43 | } 44 | return ""; 45 | } 46 | 47 | public Person getPersonByUin(String uin) { 48 | if (!getRemarkIfExistByUin(uin).equals("")) { 49 | return new Person(uin, getRemarkIfExistByUin(uin)); 50 | } else { 51 | return new Person(uin, uin); 52 | } 53 | } 54 | 55 | public String getRemarkIfExistByUin(String uin) { 56 | if (!getRemarkByUin(uin).equals("")) { 57 | return getRemarkByUin(uin); 58 | } else { 59 | return getNameByUin(uin); 60 | } 61 | } 62 | 63 | public String getNameByUin(String uin) { 64 | return friendNameMap.getOrDefault(uin, ""); 65 | } 66 | 67 | public String getRemarkByUin(String uin) { 68 | return friendRemarkMap.getOrDefault(uin, ""); 69 | } 70 | 71 | public void fetchFriends(ResultSet rs, String key) throws SQLException { 72 | while (rs.next()) { 73 | String uin = RawMessage.decryptChar(rs.getString("uin"), key); 74 | friendNameMap.put(uin, RawMessage.decryptChar(rs.getString("name"), key)); 75 | friendRemarkMap.put(uin, RawMessage.decryptChar(rs.getString("remark"), key)); 76 | } 77 | } 78 | 79 | public void fetchMultiMsgFriends(ResultSet rs, String key) throws SQLException { 80 | while (rs.next()) { 81 | String uin = RawMessage.decryptChar(rs.getString("uin"), key); 82 | String nick = RawMessage.decryptChar(rs.getString("nick"), key); 83 | String uniseq = rs.getString("uniseq"); 84 | friendMapMultiMsg.putIfAbsent(uniseq, new HashMap<>()); 85 | friendMapMultiMsg.get(uniseq).put(uin, nick); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/GlobalValues.java: -------------------------------------------------------------------------------- 1 | public class GlobalValues { 2 | public static class HtmlFormattingText { 3 | //HTML 4 | public static final String HTML_FILE_HEADER = "{HTML_TITLE}\n"; 5 | public static final String HTML_FILE_FOOTER = ""; 6 | public static final String HTML_TITLE = "{HOST_NICKNAME}({HOST_UIN}) 与 {OPPOSITE_NICKNAME}({OPPOSITE_UIN}) 的聊天记录"; 7 | public static final String CSS_CONTENT = "html{scroll-behavior:smooth;}.message-received .message-head{color:blue;}.message-sent .message-head{color:green;}.message-received,.message-sent{padding-bottom:10px;}.message-content{padding-left:8px;}.message-head{font-size:14px;}.picture-message span img,.mixed-message span img{cursor:zoom-in;}.emotion{width:28px;height:28px;}.markface{width:150px;height:150px;}.reply-link{width:fit-content;padding:10px;font-size:14px;border-left:6px solid #2196F3;background-color:#ddffff;}.reply-message a{color:#00000099;text-decoration:none;}"; 8 | public static final String ROUTER_HTML_CONTENT = "请等待重定向..."; 9 | //Message 10 | public static final String MESSAGE_SENT_HTML = "
{MESSAGE_HEADER}
{MESSAGE_CONTENT}
\n"; 11 | public static final String MESSAGE_RECEIVED_HTML = "
{MESSAGE_HEADER}
{MESSAGE_CONTENT}
\n"; 12 | public static final String TEXT_MESSAGE_HTML = "
{TEXT_MESSAGE_CONTENT}
"; 13 | public static final String EMOTION_HTML = "\"{EMOTION_ALT}\""; 14 | public static final String PICTURE_MESSAGE_HTML = "
{PICTURE_MESSAGE_CONTENT}
"; 15 | public static final String PICTURE_HTML = "\"{PICTURE_ALT}\""; 16 | public static final String MIXED_MESSAGE_HTML = "
{MIXED_MESSAGE_CONTENT}
"; 17 | public static final String POKE_MESSAGE_HTML = "
{POKE_MESSAGE_CONTENT}
"; 18 | public static final String FORWARD_MESSAGE_HTML = ""; 19 | public static final String VOICE_MESSAGE_HTML = "
{VOICE_MESSAGE_CONTENT}
"; 20 | public static final String VOICE_HTML = "{STT_TEXT}
"; 21 | public static final String MARKFACE_MESSAGE_HTML = "
{MARKFACE_MESSAGE_CONTENT}
"; 22 | public static final String MARKFACE_HTML = "\"{MARKFACE_ALT}\""; 23 | public static final String REPLY_MESSAGE_HTML = "
{REPLY_LINK}{REPLY_MESSAGE_CONTENT}
"; 24 | public static final String REPLY_LINK_HTML = ""; 25 | } 26 | 27 | public static class BatchFormattingText { 28 | public static final String BATCH_FILE_BODY = "@echo off\r\ntitle 请等待外部操作...\r\n{BATCH_FILE_BODY}\r\necho 完成"; 29 | } 30 | 31 | public static class AssetsPath { 32 | //HTML formatting only,other usages may lead to unexpected behavior.... 33 | public static final String PICTURE_PATH = "./../img/"; 34 | public static final String CSS_FILE_PATH = "./../css/main.css"; 35 | public static final String EMOTION_PATH = "./../emotion/"; 36 | public static final String MAIN_HTML_FILE_PATH = "./assets/html/"; 37 | public static final String HTML_FILE_PATH = "./"; 38 | public static final String VOICE_PATH = "./../voice/"; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Picture.java: -------------------------------------------------------------------------------- 1 | public class Picture { 2 | public String md5; 3 | public String localPath; 4 | public String fileName; 5 | public String width; 6 | public String height; 7 | private RichMsgHandle.PicRec parser = null; 8 | 9 | public Picture() { 10 | localPath = "[图片未解析]"; 11 | fileName = "Cache_" + Long.toHexString(0); 12 | width = "auto"; 13 | height = "auto"; 14 | } 15 | 16 | public Picture(RichMsgHandle.PicRec parser) { 17 | this.parser = parser; 18 | md5 = parser.getMd5(); 19 | localPath = parser.getLocalPath(); 20 | printOptimize(); 21 | String CRC64Value = String.valueOf(CRC64.crc64Long(("chatimg:" + md5))); 22 | fileName = "Cache_" + (CRC64Value.startsWith("-") ? "-" : "") + Long.toHexString(Long.valueOf(CRC64Value.replace("-", ""))); 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return GlobalValues.HtmlFormattingText.PICTURE_HTML.replace("{PICTURE_SRC}", GlobalValues.AssetsPath.PICTURE_PATH + fileName).replace("{PICTURE_ALT}", "[图片]").replace("{PICTURE_TITLE}", localPath).replace("{PICTURE_WIDTH}", width).replace("{PICTURE_HEIGHT}", height); 28 | } 29 | 30 | public String getExternalOperationCmdline() { 31 | return "copy /Y \"\\chatpic\\chatimg\\" + fileName.substring(fileName.length() - 3) + "\\" + fileName + "\" \"\\img\\" + fileName + "\" >nul\r\n"; 32 | } 33 | 34 | private void printOptimize() { 35 | int mode = 0; 36 | switch (mode) { 37 | case 0: { 38 | int tempWidth = parser.getUint32Width(); 39 | int tempHeight = parser.getUint32Height(); 40 | if (tempWidth == 0 || tempHeight == 0) { 41 | if (tempWidth == tempHeight) { 42 | // :( 43 | width = "auto"; 44 | height = "144"; 45 | } else { 46 | width = tempWidth == 0 ? "auto" : "144"; 47 | height = tempHeight == 0 ? "auto" : "144"; 48 | } 49 | } else { 50 | int shorterSide = Math.min(tempWidth, tempHeight); 51 | if (shorterSide <= 72) { 52 | width = String.valueOf(tempWidth); 53 | height = String.valueOf(tempHeight); 54 | } else if (shorterSide < 720) { 55 | width = tempWidth == shorterSide ? "72" : "auto"; 56 | height = tempHeight == shorterSide ? "72" : "auto"; 57 | } else { 58 | width = tempWidth == shorterSide ? "144" : "auto"; 59 | height = tempHeight == shorterSide ? "144" : "auto"; 60 | } 61 | } 62 | //muddy but it works.... 63 | break; 64 | } 65 | case 1: { 66 | int tempWidth = parser.getUint32ThumbWidth(); 67 | int tempHeight = parser.getUint32ThumbHeight(); 68 | width = tempWidth == 0 ? "auto" : String.valueOf(tempWidth); 69 | height = tempHeight == 0 ? "auto" : String.valueOf(tempHeight); 70 | break; 71 | } 72 | } 73 | } 74 | } 75 | 76 | //copied from http://www.java2s.com/example/java/security/a-function-that-returns-a-64bit-crc-for-string.html 77 | class CRC64 { 78 | private static final long[] CRCTable = new long[256]; 79 | private static final long POLY64REV = 0x95AC9329AC4BC9B5L; 80 | private static final long INITIALCRC = 0xFFFFFFFFFFFFFFFFL; 81 | private static boolean init = false; 82 | 83 | /** 84 | * A function that returns a 64-bit crc for string 85 | * 86 | * @param in input string 87 | * @return 64-bit crc value 88 | */ 89 | public static final long crc64Long(String in) { 90 | if (in == null || in.length() == 0) { 91 | return 0; 92 | } 93 | long crc = INITIALCRC, part; 94 | if (!init) { 95 | for (int i = 0; i < 256; i++) { 96 | part = i; 97 | for (int j = 0; j < 8; j++) { 98 | int value = ((int) part & 1); 99 | if (value != 0) { 100 | part = (part >> 1) ^ POLY64REV; 101 | } else { 102 | part >>= 1; 103 | } 104 | } 105 | CRCTable[i] = part; 106 | } 107 | init = true; 108 | } 109 | int length = in.length(); 110 | for (int k = 0; k < length; ++k) { 111 | char c = in.charAt(k); 112 | crc = CRCTable[(((int) crc) ^ c) & 0xff] ^ (crc >> 8); 113 | } 114 | return crc; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/MessageStack.java: -------------------------------------------------------------------------------- 1 | import java.sql.ResultSet; 2 | import java.sql.SQLException; 3 | import java.time.Instant; 4 | import java.time.LocalDateTime; 5 | import java.time.ZoneOffset; 6 | import java.time.format.DateTimeFormatter; 7 | import java.util.ArrayList; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | 11 | public class MessageStack { 12 | public final ArrayList messages; 13 | 14 | public MessageStack() { 15 | messages = new ArrayList<>(); 16 | } 17 | 18 | public void add(Message message) { 19 | messages.add(message); 20 | } 21 | 22 | public String getExternalOperationCmdline() { 23 | StringBuilder stringBuilder = new StringBuilder(); 24 | messages.forEach(messages -> stringBuilder.append(messages.getExternalOperationCmdline())); 25 | return stringBuilder.toString(); 26 | } 27 | 28 | public String printToHtml(Person host) { 29 | StringBuilder stringBuilder = new StringBuilder(); 30 | messages.sort(new SequenceOrderedComparator()); 31 | messages.forEach(message -> { 32 | String toAppend; 33 | if (message.sender.uin.equals(host.uin)) { 34 | toAppend = GlobalValues.HtmlFormattingText.MESSAGE_SENT_HTML; 35 | } else { 36 | toAppend = GlobalValues.HtmlFormattingText.MESSAGE_RECEIVED_HTML; 37 | } 38 | toAppend = toAppend.replace("{MESSAGE_HEADER}", message.sender.nickName + " " + generalTimeFormat(message.time)); 39 | toAppend = toAppend.replace("{MESSAGE_CONTENT}", message.printToHtml()); 40 | toAppend = toAppend.replace("{MSGUID}", String.valueOf(message.msgUid)); 41 | stringBuilder.append(toAppend); 42 | }); 43 | return stringBuilder.toString(); 44 | } 45 | 46 | public static String generalTimeFormat(long time) { 47 | return LocalDateTime.ofInstant(Instant.ofEpochSecond(time), ZoneOffset.of("+8")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); 48 | } 49 | 50 | public String replaceEmotion(String message, List configList) { 51 | HashMap configMap = new HashMap<>(); 52 | for (QEmotion emotion : configList) { 53 | configMap.put(emotion.getAQLid(), emotion); 54 | } 55 | StringBuffer messageBuffer = new StringBuffer(message); 56 | for (int i = 0; i < messageBuffer.length(); i++) { 57 | if (messageBuffer.charAt(i) == '\u0014') { 58 | QEmotion emotion = configMap.getOrDefault(String.valueOf(messageBuffer.codePointAt(i + 1)), new QEmotion(String.valueOf(i + 1))); 59 | messageBuffer.insert(i + 2, GlobalValues.HtmlFormattingText.EMOTION_HTML.replace("{EMOTION_SRC}", GlobalValues.AssetsPath.EMOTION_PATH + "s" + emotion.getQSid() + ".png").replace("{EMOTION_ALT}", emotion.getQDes()).replace("{EMOTION_TITLE}", emotion.getAQLid() + " -> " + emotion.getQDes())); 60 | messageBuffer.delete(i, i + 2); 61 | } 62 | } 63 | return messageBuffer.toString(); 64 | } 65 | 66 | public static MessageStack join(MessageStack stack1, MessageStack stack2) { 67 | MessageStack toReturn = new MessageStack(); 68 | toReturn.messages.addAll(stack1.messages); 69 | toReturn.messages.addAll(stack2.messages); 70 | return toReturn; 71 | } 72 | 73 | public static MessageStack process(ResultSet messageList, ResultSet messageListSlowTable, HashMap> multiMessageList, FriendManager friendManager, String key) throws SQLException { 74 | return MessageStack.join(MessageStack.parse(messageList, multiMessageList, friendManager, key), MessageStack.parse(messageListSlowTable, multiMessageList, friendManager, key)); 75 | } 76 | 77 | public static MessageStack parse(ResultSet messageList, HashMap> multiMessageList, FriendManager friendManager, String key) throws SQLException { 78 | MessageStack toReturn = new MessageStack(); 79 | if (messageList == null) { 80 | return toReturn; 81 | } 82 | while (messageList.next()) { 83 | toReturn.add(new RawMessage(messageList).parse(key, friendManager, multiMessageList, false)); 84 | } 85 | return toReturn; 86 | } 87 | 88 | public static HashMap> parseMultiMsg(ResultSet rs) throws SQLException { 89 | HashMap> toReturn = new HashMap<>(); 90 | while (rs.next()) { 91 | RawMessage message = new RawMessage(rs); 92 | toReturn.putIfAbsent(message.msgseq, new ArrayList<>()); 93 | toReturn.get(message.msgseq).add(message); 94 | } 95 | return toReturn; 96 | } 97 | 98 | public void printToConsole() { 99 | messages.sort(new SequenceOrderedComparator()); 100 | messages.forEach(message -> System.out.println("[" + generalTimeFormat(message.time) + "]" + message)); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileOutputStream; 3 | import java.io.IOException; 4 | import java.io.UnsupportedEncodingException; 5 | import java.math.BigInteger; 6 | import java.security.MessageDigest; 7 | import java.security.NoSuchAlgorithmException; 8 | import java.sql.*; 9 | import java.util.Scanner; 10 | 11 | public class Main { 12 | public static void main(String[] args) { 13 | Scanner scanner = new Scanner(System.in); 14 | System.out.print("数据库文件所在路径:"); 15 | String sourceDir = scanner.nextLine().replace("/", "\\"); 16 | System.out.print("外置资源所在路径:"); 17 | String assetDir = scanner.nextLine().replace("/", "\\"); 18 | System.out.print("输出路径:"); 19 | String destDir = scanner.nextLine().replace("/", "\\"); 20 | prepareOutput(destDir); 21 | System.out.print("密钥:"); 22 | String key = scanner.nextLine(); 23 | System.out.print("自己的QQ号:"); 24 | String uinSelf = scanner.nextLine(); 25 | System.out.print("对方的QQ号:"); 26 | String uinOpposite = scanner.nextLine(); 27 | System.out.println("请等待..."); 28 | String dbFileName = uinSelf + ".db"; 29 | String dbSlowTableFileName = "slowtable_" + dbFileName; 30 | final String DB_URL = "jdbc:sqlite:" + sourceDir + "\\" + dbFileName; 31 | final String DB_URL_slowtable = "jdbc:sqlite:" + sourceDir + "\\" + dbSlowTableFileName; 32 | try { 33 | String targetMD5 = new BigInteger(1, MessageDigest.getInstance("md5").digest(uinOpposite.getBytes())).toString(16).toUpperCase(); 34 | targetMD5 = "00000000000000000000000000000000" + targetMD5; 35 | targetMD5 = targetMD5.substring(targetMD5.length() - 32); 36 | Connection connection = DriverManager.getConnection(DB_URL); 37 | Connection connectionSlowTable = DriverManager.getConnection(DB_URL_slowtable); 38 | Statement statement = connection.createStatement(); 39 | FriendManager friendManager = new FriendManager(); 40 | friendManager.fetchFriends(statement.executeQuery("SELECT uin,name,remark FROM Friends"), key); 41 | friendManager.fetchMultiMsgFriends(statement.executeQuery("SELECT uin,nick,uniseq FROM MultiMsgNick"), key); 42 | ResultSet multiMessageList = connection.createStatement().executeQuery("SELECT * FROM mr_multimessage"); 43 | ResultSet messageList = connection.createStatement().executeQuery("SELECT * FROM mr_friend__New".replace("", targetMD5)); 44 | ResultSet messageListSlowTable = null; 45 | try { 46 | messageListSlowTable = connectionSlowTable.createStatement().executeQuery("SELECT * FROM mr_friend__New".replace("", targetMD5)); 47 | } catch (SQLException e) { 48 | //slowtable.db might not have that table since the regular database is enough to store messages 49 | } 50 | MessageStack topMessageStack = MessageStack.process(messageList, messageListSlowTable, MessageStack.parseMultiMsg(multiMessageList), friendManager, key); 51 | writeFile(GlobalValues.HtmlFormattingText.ROUTER_HTML_CONTENT.replace("{MAIN_HTML_FILE_URL}", GlobalValues.AssetsPath.MAIN_HTML_FILE_PATH + uinOpposite + ".html"), destDir + "\\" + uinOpposite + ".html"); 52 | writeFile(new MessageWrapper(topMessageStack, friendManager.getPersonByUin(uinSelf), friendManager.getPersonByUin(uinOpposite)).printToHtml(), destDir + "\\assets\\html\\" + uinOpposite + ".html"); 53 | writeFile(GlobalValues.HtmlFormattingText.CSS_CONTENT, destDir + "\\assets\\css\\main.css"); 54 | writeBatchFile(GlobalValues.BatchFormattingText.BATCH_FILE_BODY.replace("{BATCH_FILE_BODY}", topMessageStack.getExternalOperationCmdline().replace("", assetDir).replace("", destDir + "\\assets").replace("", "\"" + assetDir + "\\silk_v3_decoder.exe\"").replace("", "\"" + assetDir + "\\ffmpeg.exe\"")), destDir + "\\exop.bat"); 55 | Runtime.getRuntime().exec("cmd.exe /c start cmd.exe /c " + destDir + "\\exop.bat"); //show a dialog to user 56 | } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { 57 | System.err.println("未知错误"); 58 | e.printStackTrace(); 59 | } catch (SQLException e) { 60 | System.err.println("数据库异常"); 61 | e.printStackTrace(); 62 | } catch (IOException e) { 63 | System.err.println("文件写出失败"); 64 | e.printStackTrace(); 65 | } 66 | } 67 | 68 | static void prepareOutput(String destPath) { 69 | String[] paths = new String[]{"\\", "\\assets\\css", "\\assets\\html", "\\assets\\img", "\\assets\\voice"}; 70 | for (String path : paths) { 71 | File destDir = new File(destPath + path); 72 | if (!destDir.exists()) { 73 | destDir.mkdirs(); 74 | } 75 | } 76 | } 77 | 78 | static void writeFile(String content, String path) throws IOException { 79 | FileOutputStream fileOutputStream = new FileOutputStream(path, false); 80 | fileOutputStream.write(content.getBytes("UTF-8")); 81 | fileOutputStream.flush(); 82 | fileOutputStream.close(); 83 | } 84 | 85 | static void writeBatchFile(String content, String path) throws IOException { 86 | FileOutputStream fileOutputStream = new FileOutputStream(path, false); 87 | fileOutputStream.write(content.getBytes("GB2312")); 88 | fileOutputStream.flush(); 89 | fileOutputStream.close(); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/RawMessage.java: -------------------------------------------------------------------------------- 1 | import java.nio.charset.StandardCharsets; 2 | import java.sql.ResultSet; 3 | import java.sql.SQLException; 4 | import java.util.ArrayList; 5 | import java.util.HashMap; 6 | 7 | public class RawMessage { 8 | public byte[] msgData; 9 | public String msgseq; 10 | public String msgtype; 11 | public String selfuin; 12 | public String senderuin; 13 | public String time; 14 | public String uniseq; 15 | public byte[] extStr; 16 | public String msgUid; 17 | 18 | public RawMessage(ResultSet rs) { 19 | try { 20 | msgData = rs.getBytes("msgData"); 21 | msgseq = rs.getString("msgseq"); 22 | msgtype = rs.getString("msgtype"); 23 | senderuin = rs.getString("senderuin"); 24 | selfuin = rs.getString("selfuin"); 25 | time = rs.getString("time"); 26 | uniseq = rs.getString("uniseq"); 27 | extStr = rs.getBytes("extStr"); 28 | msgUid = rs.getString("msgUid"); 29 | } catch (SQLException e) { 30 | System.err.println("读取消息时出现问题"); 31 | e.printStackTrace(); 32 | } 33 | } 34 | 35 | public RawMessage(byte[] msgData, String msgseq, String msgtype, String selfuin, String senderuin, String time, String uniseq, byte[] extStr, String msgUid) { 36 | this.msgData = msgData; 37 | this.msgseq = msgseq; 38 | this.msgtype = msgtype; 39 | this.selfuin = selfuin; 40 | this.senderuin = senderuin; 41 | this.time = time; 42 | this.uniseq = uniseq; 43 | this.extStr = extStr; 44 | this.msgUid = msgUid; 45 | } 46 | 47 | public Message parse(String key, FriendManager friendManager, HashMap> rawMultiMsgList, boolean isMultiMsg) { 48 | long time = Long.valueOf(this.time); 49 | long uniseq = Long.valueOf(this.uniseq); 50 | long msgseq = Long.valueOf(this.msgseq); 51 | long msgUid = Long.valueOf(this.msgUid); 52 | String senderuin = decryptChar(this.senderuin, key); 53 | friendManager.isMultiMsgMode = isMultiMsg; 54 | friendManager.multiMsgUniseq = this.msgseq; 55 | Person sender = friendManager.getPersonByUinPrefill(senderuin); 56 | Message toReturn; 57 | switch (msgtype) { 58 | case "-1000": 59 | case "-1051": 60 | toReturn = new TextMessage(sender, time, uniseq, msgUid, decryptString(msgData, key)); 61 | break; 62 | case "-1049": 63 | toReturn = new ReplyMessage(sender, time, uniseq, msgUid, decryptString(msgData, key), decryptString(extStr, key), friendManager); 64 | break; 65 | case "-2000": 66 | toReturn = new PictureMessage(sender, time, uniseq, msgUid, decryptProtobuf(msgData, key)); 67 | break; 68 | case "-1035": 69 | toReturn = new MixedMessage(sender, time, uniseq, msgUid, decryptProtobuf(msgData, key)); 70 | break; 71 | case "-5012": 72 | case "-5018": 73 | toReturn = new PokeMessage(sender, time, uniseq, msgUid, decryptString(msgData, key)); 74 | break; 75 | case "-2011": 76 | if (ForwardMessage.isForwardMessage(decryptProtobuf(msgData, key))) { 77 | toReturn = new ForwardMessage(sender, time, uniseq, msgseq, msgUid, key, friendManager, rawMultiMsgList, msgData, isMultiMsg); 78 | } else { 79 | toReturn = new TextMessage(sender, time, uniseq, msgUid, "[分享消息]"); 80 | } 81 | break; 82 | case "-2002": 83 | toReturn = new VoiceMessage(sender, time, uniseq, msgUid, decryptProtobuf(msgData, key)); 84 | break; 85 | case "-2007": 86 | toReturn = new MarkFaceMessage(sender, time, uniseq, msgUid, decryptProtobuf(msgData, key)); 87 | break; 88 | default: 89 | toReturn = MiscMessageHandle.parse(sender, time, uniseq, msgUid, msgtype, decryptProtobuf(msgData, key)); 90 | break; 91 | } 92 | return toReturn; 93 | } 94 | 95 | public static String decryptChar(String data, String key) { 96 | if (data == null) { 97 | return ""; 98 | } else { 99 | char[] keyArr = key.toCharArray(); 100 | char[] dataArr = data.toCharArray(); 101 | String dataStr = ""; 102 | for (int i = 0; i < data.length(); i++) { 103 | dataStr += Character.toString((char) (dataArr[i] ^ keyArr[i % keyArr.length])); 104 | } 105 | return dataStr; 106 | } 107 | } 108 | 109 | public static String decryptString(byte[] data, String key) { 110 | if (data == null) { 111 | return ""; 112 | } else { 113 | char[] keyArr = key.toCharArray(); 114 | byte[] dataByte = new byte[data.length]; 115 | for (int i = 0; i < data.length; i++) { 116 | dataByte[i] = (byte) (data[i] ^ keyArr[i % keyArr.length]); 117 | } 118 | return new String(dataByte, StandardCharsets.UTF_8); 119 | } 120 | } 121 | 122 | public static byte[] decryptProtobuf(byte[] data, String key) { 123 | if (data == null) { 124 | return new byte[0]; 125 | } else { 126 | char[] keyArr = key.toCharArray(); 127 | byte[] dataByte = new byte[data.length]; 128 | for (int i = 0; i < data.length; i++) { 129 | dataByte[i] = (byte) (data[i] ^ keyArr[i % keyArr.length]); 130 | } 131 | return dataByte; 132 | } 133 | } 134 | 135 | //copied from https://stackoverflow.com/questions/140131/convert-a-string-representation-of-a-hex-dump-to-a-byte-array-using-java/140861#140861 136 | public static byte[] hexStringToByteArray(String s) { 137 | int len = s.length(); 138 | byte[] data = new byte[len / 2]; 139 | for (int i = 0; i < len; i += 2) { 140 | data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 141 | + Character.digit(s.charAt(i + 1), 16)); 142 | } 143 | return data; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/res/face_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "sysface": [ 3 | { 4 | "QSid": "14", 5 | "QDes": "/微笑", 6 | "IQLid": "23", 7 | "AQLid": "23", 8 | "EMCode": "100" 9 | }, 10 | { 11 | "QSid": "1", 12 | "QDes": "/撇嘴", 13 | "IQLid": "40", 14 | "AQLid": "40", 15 | "EMCode": "101" 16 | }, 17 | { 18 | "QSid": "2", 19 | "QDes": "/色", 20 | "IQLid": "19", 21 | "AQLid": "19", 22 | "EMCode": "102" 23 | }, 24 | { 25 | "QSid": "3", 26 | "QDes": "/发呆", 27 | "IQLid": "43", 28 | "AQLid": "43", 29 | "EMCode": "103" 30 | }, 31 | { 32 | "QSid": "4", 33 | "QDes": "/得意", 34 | "IQLid": "21", 35 | "AQLid": "21", 36 | "EMCode": "104" 37 | }, 38 | { 39 | "QSid": "6", 40 | "QDes": "/害羞", 41 | "IQLid": "20", 42 | "AQLid": "20", 43 | "EMCode": "106" 44 | }, 45 | { 46 | "QSid": "7", 47 | "QDes": "/闭嘴", 48 | "IQLid": "104", 49 | "AQLid": "106", 50 | "EMCode": "107" 51 | }, 52 | { 53 | "QSid": "8", 54 | "QDes": "/睡", 55 | "IQLid": "35", 56 | "AQLid": "35", 57 | "QHide": "1", 58 | "EMCode": "108" 59 | }, 60 | { 61 | "QSid": "9", 62 | "QDes": "/大哭", 63 | "IQLid": "10", 64 | "AQLid": "10", 65 | "EMCode": "109" 66 | }, 67 | { 68 | "QSid": "5", 69 | "QDes": "/流泪", 70 | "IQLid": "9", 71 | "AQLid": "9", 72 | "EMCode": "105", 73 | "AniStickerType": 1, 74 | "AniStickerPackId": "1", 75 | "AniStickerId": "16" 76 | }, 77 | { 78 | "QSid": "10", 79 | "QDes": "/尴尬", 80 | "IQLid": "25", 81 | "AQLid": "25", 82 | "EMCode": "110" 83 | }, 84 | { 85 | "QSid": "11", 86 | "QDes": "/发怒", 87 | "IQLid": "24", 88 | "AQLid": "24", 89 | "EMCode": "111" 90 | }, 91 | { 92 | "QSid": "12", 93 | "QDes": "/调皮", 94 | "IQLid": "1", 95 | "AQLid": "1", 96 | "EMCode": "112" 97 | }, 98 | { 99 | "QSid": "13", 100 | "QDes": "/呲牙", 101 | "IQLid": "0", 102 | "AQLid": "0", 103 | "EMCode": "113" 104 | }, 105 | { 106 | "QSid": "0", 107 | "QDes": "/惊讶", 108 | "IQLid": "33", 109 | "AQLid": "33", 110 | "EMCode": "114" 111 | }, 112 | { 113 | "QSid": "15", 114 | "QDes": "/难过", 115 | "IQLid": "32", 116 | "AQLid": "32", 117 | "EMCode": "115" 118 | }, 119 | { 120 | "QSid": "16", 121 | "QDes": "/酷", 122 | "IQLid": "12", 123 | "AQLid": "12", 124 | "QHide": "1", 125 | "EMCode": "116" 126 | }, 127 | { 128 | "QSid": "96", 129 | "QDes": "/冷汗", 130 | "IQLid": "27", 131 | "AQLid": "27", 132 | "EMCode": "117" 133 | }, 134 | { 135 | "QSid": "18", 136 | "QDes": "/抓狂", 137 | "IQLid": "13", 138 | "AQLid": "13", 139 | "EMCode": "118" 140 | }, 141 | { 142 | "QSid": "19", 143 | "QDes": "/吐", 144 | "IQLid": "22", 145 | "AQLid": "22", 146 | "EMCode": "119" 147 | }, 148 | { 149 | "QSid": "20", 150 | "QDes": "/偷笑", 151 | "IQLid": "3", 152 | "AQLid": "3", 153 | "EMCode": "120" 154 | }, 155 | { 156 | "QSid": "21", 157 | "QDes": "/可爱", 158 | "IQLid": "18", 159 | "AQLid": "18", 160 | "EMCode": "121" 161 | }, 162 | { 163 | "QSid": "22", 164 | "QDes": "/白眼", 165 | "IQLid": "30", 166 | "AQLid": "30", 167 | "EMCode": "122" 168 | }, 169 | { 170 | "QSid": "23", 171 | "QDes": "/傲慢", 172 | "IQLid": "31", 173 | "AQLid": "31", 174 | "EMCode": "123" 175 | }, 176 | { 177 | "QSid": "24", 178 | "QDes": "/饥饿", 179 | "IQLid": "79", 180 | "AQLid": "81", 181 | "EMCode": "124" 182 | }, 183 | { 184 | "QSid": "25", 185 | "QDes": "/困", 186 | "IQLid": "80", 187 | "AQLid": "82", 188 | "EMCode": "125" 189 | }, 190 | { 191 | "QSid": "26", 192 | "QDes": "/惊恐", 193 | "IQLid": "26", 194 | "AQLid": "26", 195 | "EMCode": "126" 196 | }, 197 | { 198 | "QSid": "27", 199 | "QDes": "/流汗", 200 | "IQLid": "2", 201 | "AQLid": "2", 202 | "EMCode": "127" 203 | }, 204 | { 205 | "QSid": "28", 206 | "QDes": "/憨笑", 207 | "IQLid": "37", 208 | "AQLid": "37", 209 | "EMCode": "128" 210 | }, 211 | { 212 | "QSid": "29", 213 | "QDes": "/悠闲", 214 | "IQLid": "50", 215 | "AQLid": "50", 216 | "QHide": "1", 217 | "EMCode": "129" 218 | }, 219 | { 220 | "QSid": "30", 221 | "QDes": "/奋斗", 222 | "IQLid": "42", 223 | "AQLid": "42", 224 | "EMCode": "130" 225 | }, 226 | { 227 | "QSid": "31", 228 | "QDes": "/咒骂", 229 | "IQLid": "81", 230 | "AQLid": "83", 231 | "EMCode": "131" 232 | }, 233 | { 234 | "QSid": "32", 235 | "QDes": "/疑问", 236 | "IQLid": "34", 237 | "AQLid": "34", 238 | "EMCode": "132" 239 | }, 240 | { 241 | "QSid": "33", 242 | "QDes": "/嘘", 243 | "IQLid": "11", 244 | "AQLid": "11", 245 | "QHide": "1", 246 | "EMCode": "133" 247 | }, 248 | { 249 | "QSid": "34", 250 | "QDes": "/晕", 251 | "IQLid": "49", 252 | "AQLid": "49", 253 | "EMCode": "134" 254 | }, 255 | { 256 | "QSid": "35", 257 | "QDes": "/折磨", 258 | "IQLid": "82", 259 | "AQLid": "84", 260 | "EMCode": "135" 261 | }, 262 | { 263 | "QSid": "36", 264 | "QDes": "/衰", 265 | "isStatic": "1", 266 | "IQLid": "39", 267 | "AQLid": "39", 268 | "EMCode": "136" 269 | }, 270 | { 271 | "QSid": "37", 272 | "QDes": "/骷髅", 273 | "isStatic": "1", 274 | "IQLid": "76", 275 | "AQLid": "78", 276 | "QHide": "1", 277 | "EMCode": "137" 278 | }, 279 | { 280 | "QSid": "38", 281 | "QDes": "/敲打", 282 | "IQLid": "5", 283 | "AQLid": "5", 284 | "EMCode": "138" 285 | }, 286 | { 287 | "QSid": "39", 288 | "QDes": "/再见", 289 | "IQLid": "4", 290 | "AQLid": "4", 291 | "EMCode": "139" 292 | }, 293 | { 294 | "QSid": "97", 295 | "QDes": "/擦汗", 296 | "IQLid": "6", 297 | "AQLid": "6", 298 | "EMCode": "140" 299 | }, 300 | { 301 | "QSid": "98", 302 | "QDes": "/抠鼻", 303 | "IQLid": "83", 304 | "AQLid": "85", 305 | "EMCode": "141" 306 | }, 307 | { 308 | "QSid": "99", 309 | "QDes": "/鼓掌", 310 | "IQLid": "84", 311 | "AQLid": "86", 312 | "EMCode": "142" 313 | }, 314 | { 315 | "QSid": "100", 316 | "QDes": "/糗大了", 317 | "IQLid": "85", 318 | "AQLid": "87", 319 | "EMCode": "143" 320 | }, 321 | { 322 | "QSid": "101", 323 | "QDes": "/坏笑", 324 | "IQLid": "46", 325 | "AQLid": "46", 326 | "EMCode": "144" 327 | }, 328 | { 329 | "QSid": "102", 330 | "QDes": "/左哼哼", 331 | "IQLid": "86", 332 | "AQLid": "88", 333 | "EMCode": "145" 334 | }, 335 | { 336 | "QSid": "103", 337 | "QDes": "/右哼哼", 338 | "IQLid": "44", 339 | "AQLid": "44", 340 | "EMCode": "146" 341 | }, 342 | { 343 | "QSid": "104", 344 | "QDes": "/哈欠", 345 | "IQLid": "87", 346 | "AQLid": "89", 347 | "EMCode": "147" 348 | }, 349 | { 350 | "QSid": "105", 351 | "QDes": "/鄙视", 352 | "IQLid": "48", 353 | "AQLid": "48", 354 | "EMCode": "148" 355 | }, 356 | { 357 | "QSid": "106", 358 | "QDes": "/委屈", 359 | "IQLid": "14", 360 | "AQLid": "14", 361 | "EMCode": "149" 362 | }, 363 | { 364 | "QSid": "107", 365 | "QDes": "/快哭了", 366 | "IQLid": "88", 367 | "AQLid": "90", 368 | "EMCode": "150" 369 | }, 370 | { 371 | "QSid": "108", 372 | "QDes": "/阴险", 373 | "IQLid": "41", 374 | "AQLid": "41", 375 | "EMCode": "151" 376 | }, 377 | { 378 | "QSid": "305", 379 | "QDes": "/右亲亲", 380 | "IQLid": "305", 381 | "AQLid": "305", 382 | "EMCode": "10305" 383 | }, 384 | { 385 | "QSid": "109", 386 | "QDes": "/左亲亲", 387 | "IQLid": "36", 388 | "AQLid": "36", 389 | "EMCode": "152" 390 | }, 391 | { 392 | "QSid": "110", 393 | "QDes": "/吓", 394 | "IQLid": "89", 395 | "AQLid": "91", 396 | "QHide": "1", 397 | "EMCode": "153" 398 | }, 399 | { 400 | "QSid": "111", 401 | "QDes": "/可怜", 402 | "IQLid": "51", 403 | "AQLid": "51", 404 | "EMCode": "154" 405 | }, 406 | { 407 | "QSid": "172", 408 | "QDes": "/眨眼睛", 409 | "IQLid": "142", 410 | "AQLid": "164", 411 | "EMCode": "242" 412 | }, 413 | { 414 | "QSid": "182", 415 | "QDes": "/笑哭", 416 | "IQLid": "152", 417 | "AQLid": "174", 418 | "EMCode": "252" 419 | }, 420 | { 421 | "QSid": "179", 422 | "QDes": "/doge", 423 | "IQLid": "149", 424 | "AQLid": "171", 425 | "EMCode": "249" 426 | }, 427 | { 428 | "QSid": "173", 429 | "QDes": "/泪奔", 430 | "IQLid": "143", 431 | "AQLid": "165", 432 | "EMCode": "243" 433 | }, 434 | { 435 | "QSid": "174", 436 | "QDes": "/无奈", 437 | "IQLid": "144", 438 | "AQLid": "166", 439 | "EMCode": "244" 440 | }, 441 | { 442 | "QSid": "212", 443 | "QDes": "/托腮", 444 | "IQLid": "182", 445 | "AQLid": "161", 446 | "EMCode": "282" 447 | }, 448 | { 449 | "QSid": "175", 450 | "QDes": "/卖萌", 451 | "IQLid": "145", 452 | "AQLid": "167", 453 | "EMCode": "245" 454 | }, 455 | { 456 | "QSid": "178", 457 | "QDes": "/斜眼笑", 458 | "IQLid": "148", 459 | "AQLid": "170", 460 | "EMCode": "248" 461 | }, 462 | { 463 | "QSid": "177", 464 | "QDes": "/喷血", 465 | "IQLid": "147", 466 | "AQLid": "169", 467 | "EMCode": "247" 468 | }, 469 | { 470 | "QSid": "180", 471 | "QDes": "/惊喜", 472 | "IQLid": "150", 473 | "AQLid": "172", 474 | "QHide": "1", 475 | "EMCode": "250" 476 | }, 477 | { 478 | "QSid": "181", 479 | "QDes": "/骚扰", 480 | "IQLid": "151", 481 | "AQLid": "173", 482 | "EMCode": "251" 483 | }, 484 | { 485 | "QSid": "176", 486 | "QDes": "/小纠结", 487 | "IQLid": "146", 488 | "AQLid": "168", 489 | "EMCode": "246" 490 | }, 491 | { 492 | "QSid": "183", 493 | "QDes": "/我最美", 494 | "IQLid": "153", 495 | "AQLid": "175", 496 | "EMCode": "253" 497 | }, 498 | { 499 | "QSid": "245", 500 | "QDes": "/加油必胜", 501 | "IQLid": "245", 502 | "AQLid": "217", 503 | "QHide": "1", 504 | "EMCode": "202001" 505 | }, 506 | { 507 | "QSid": "246", 508 | "QDes": "/加油抱抱", 509 | "IQLid": "246", 510 | "AQLid": "218", 511 | "EMCode": "202002" 512 | }, 513 | { 514 | "QSid": "247", 515 | "QDes": "/口罩护体", 516 | "isStatic": "1", 517 | "IQLid": "247", 518 | "AQLid": "219", 519 | "QHide": "1", 520 | "EMCode": "202003" 521 | }, 522 | { 523 | "QSid": "260", 524 | "QDes": "/搬砖中", 525 | "isStatic": "1", 526 | "IQLid": "260", 527 | "AQLid": "260", 528 | "QHide": "1", 529 | "EMCode": "10260" 530 | }, 531 | { 532 | "QSid": "261", 533 | "QDes": "/忙到飞起", 534 | "IQLid": "261", 535 | "AQLid": "261", 536 | "QHide": "1", 537 | "EMCode": "10261" 538 | }, 539 | { 540 | "QSid": "262", 541 | "QDes": "/脑阔疼", 542 | "IQLid": "262", 543 | "AQLid": "262", 544 | "EMCode": "10262" 545 | }, 546 | { 547 | "QSid": "263", 548 | "QDes": "/沧桑", 549 | "IQLid": "263", 550 | "AQLid": "263", 551 | "EMCode": "10263" 552 | }, 553 | { 554 | "QSid": "264", 555 | "QDes": "/捂脸", 556 | "IQLid": "264", 557 | "AQLid": "264", 558 | "EMCode": "10264" 559 | }, 560 | { 561 | "QSid": "265", 562 | "QDes": "/辣眼睛", 563 | "IQLid": "265", 564 | "AQLid": "265", 565 | "EMCode": "10265" 566 | }, 567 | { 568 | "QSid": "266", 569 | "QDes": "/哦哟", 570 | "IQLid": "266", 571 | "AQLid": "266", 572 | "EMCode": "10266" 573 | }, 574 | { 575 | "QSid": "267", 576 | "QDes": "/头秃", 577 | "IQLid": "267", 578 | "AQLid": "267", 579 | "EMCode": "10267" 580 | }, 581 | { 582 | "QSid": "268", 583 | "QDes": "/问号脸", 584 | "IQLid": "268", 585 | "AQLid": "268", 586 | "EMCode": "10268" 587 | }, 588 | { 589 | "QSid": "269", 590 | "QDes": "/暗中观察", 591 | "IQLid": "269", 592 | "AQLid": "269", 593 | "EMCode": "10269" 594 | }, 595 | { 596 | "QSid": "270", 597 | "QDes": "/emm", 598 | "IQLid": "270", 599 | "AQLid": "270", 600 | "EMCode": "10270" 601 | }, 602 | { 603 | "QSid": "271", 604 | "QDes": "/吃瓜", 605 | "IQLid": "271", 606 | "AQLid": "271", 607 | "EMCode": "10271" 608 | }, 609 | { 610 | "QSid": "272", 611 | "QDes": "/呵呵哒", 612 | "IQLid": "272", 613 | "AQLid": "272", 614 | "EMCode": "10272" 615 | }, 616 | { 617 | "QSid": "277", 618 | "QDes": "/汪汪", 619 | "isStatic": "1", 620 | "IQLid": "277", 621 | "AQLid": "277", 622 | "EMCode": "10277" 623 | }, 624 | { 625 | "QSid": "307", 626 | "QDes": "/喵喵", 627 | "isStatic": "1", 628 | "IQLid": "307", 629 | "AQLid": "307", 630 | "EMCode": "10307" 631 | }, 632 | { 633 | "QSid": "306", 634 | "QDes": "/牛气冲天", 635 | "isStatic": "1", 636 | "IQLid": "306", 637 | "AQLid": "306", 638 | "EMCode": "10306" 639 | }, 640 | { 641 | "QSid": "281", 642 | "QDes": "/无眼笑", 643 | "IQLid": "281", 644 | "AQLid": "281", 645 | "EMCode": "10281" 646 | }, 647 | { 648 | "QSid": "282", 649 | "QDes": "/敬礼", 650 | "IQLid": "282", 651 | "AQLid": "282", 652 | "EMCode": "10282" 653 | }, 654 | { 655 | "QSid": "283", 656 | "QDes": "/狂笑", 657 | "IQLid": "283", 658 | "AQLid": "283", 659 | "EMCode": "10283" 660 | }, 661 | { 662 | "QSid": "284", 663 | "QDes": "/面无表情", 664 | "IQLid": "284", 665 | "AQLid": "284", 666 | "EMCode": "10284" 667 | }, 668 | { 669 | "QSid": "285", 670 | "QDes": "/摸鱼", 671 | "IQLid": "285", 672 | "AQLid": "285", 673 | "EMCode": "10285" 674 | }, 675 | { 676 | "QSid": "293", 677 | "QDes": "/摸锦鲤", 678 | "IQLid": "293", 679 | "AQLid": "293", 680 | "EMCode": "10293" 681 | }, 682 | { 683 | "QSid": "286", 684 | "QDes": "/魔鬼笑", 685 | "IQLid": "286", 686 | "AQLid": "286", 687 | "EMCode": "10286" 688 | }, 689 | { 690 | "QSid": "287", 691 | "QDes": "/哦", 692 | "IQLid": "287", 693 | "AQLid": "287", 694 | "EMCode": "10287" 695 | }, 696 | { 697 | "QSid": "288", 698 | "QDes": "/请", 699 | "IQLid": "288", 700 | "AQLid": "288", 701 | "EMCode": "10288" 702 | }, 703 | { 704 | "QSid": "289", 705 | "QDes": "/睁眼", 706 | "IQLid": "289", 707 | "AQLid": "289", 708 | "EMCode": "10289" 709 | }, 710 | { 711 | "QSid": "294", 712 | "QDes": "/期待", 713 | "IQLid": "294", 714 | "AQLid": "294", 715 | "EMCode": "10294" 716 | }, 717 | { 718 | "QSid": "296", 719 | "QDes": "/真好", 720 | "IQLid": "296", 721 | "AQLid": "296", 722 | "QHide": "1", 723 | "EMCode": "10296" 724 | }, 725 | { 726 | "QSid": "297", 727 | "QDes": "/拜谢", 728 | "IQLid": "297", 729 | "AQLid": "297", 730 | "EMCode": "10297" 731 | }, 732 | { 733 | "QSid": "298", 734 | "QDes": "/元宝", 735 | "IQLid": "298", 736 | "AQLid": "298", 737 | "EMCode": "10298" 738 | }, 739 | { 740 | "QSid": "299", 741 | "QDes": "/牛啊", 742 | "IQLid": "299", 743 | "AQLid": "299", 744 | "EMCode": "10299" 745 | }, 746 | { 747 | "QSid": "300", 748 | "QDes": "/胖三斤", 749 | "IQLid": "300", 750 | "AQLid": "300", 751 | "EMCode": "10300" 752 | }, 753 | { 754 | "QSid": "301", 755 | "QDes": "/好闪", 756 | "IQLid": "301", 757 | "AQLid": "301", 758 | "EMCode": "10301" 759 | }, 760 | { 761 | "QSid": "304", 762 | "QDes": "/红包包", 763 | "IQLid": "304", 764 | "AQLid": "304", 765 | "QHide": "1", 766 | "EMCode": "10304" 767 | }, 768 | { 769 | "QSid": "322", 770 | "QDes": "/拒绝", 771 | "IQLid": "322", 772 | "AQLid": "322", 773 | "EMCode": "10322" 774 | }, 775 | { 776 | "QSid": "323", 777 | "QDes": "/嫌弃", 778 | "IQLid": "323", 779 | "AQLid": "323", 780 | "EMCode": "10323" 781 | }, 782 | { 783 | "QSid": "332", 784 | "QDes": "/举牌牌", 785 | "IQLid": "332", 786 | "AQLid": "332", 787 | "EMCode": "10332" 788 | }, 789 | { 790 | "QSid": "336", 791 | "QDes": "/豹富", 792 | "IQLid": "336", 793 | "AQLid": "336", 794 | "EMCode": "10336" 795 | }, 796 | { 797 | "QSid": "334", 798 | "QDes": "/虎虎生威", 799 | "IQLid": "334", 800 | "AQLid": "334", 801 | "EMCode": "10334" 802 | }, 803 | { 804 | "QSid": "335", 805 | "QDes": "/绿马护体", 806 | "IQLid": "335", 807 | "AQLid": "335", 808 | "EMCode": "10335" 809 | }, 810 | { 811 | "QSid": "303", 812 | "QDes": "/右拜年", 813 | "IQLid": "303", 814 | "AQLid": "303", 815 | "EMCode": "10303" 816 | }, 817 | { 818 | "QSid": "302", 819 | "QDes": "/左拜年", 820 | "IQLid": "302", 821 | "AQLid": "302", 822 | "EMCode": "10302" 823 | }, 824 | { 825 | "QSid": "295", 826 | "QDes": "/拿到红包", 827 | "IQLid": "295", 828 | "AQLid": "295", 829 | "EMCode": "10295" 830 | }, 831 | { 832 | "QSid": "311", 833 | "QDes": "/打call", 834 | "IQLid": "311", 835 | "AQLid": "311", 836 | "EMCode": "10311", 837 | "AniStickerType": 1, 838 | "AniStickerPackId": "1", 839 | "AniStickerId": "1" 840 | }, 841 | { 842 | "QSid": "312", 843 | "QDes": "/变形", 844 | "IQLid": "312", 845 | "AQLid": "312", 846 | "EMCode": "10312", 847 | "AniStickerType": 1, 848 | "AniStickerPackId": "1", 849 | "AniStickerId": "2" 850 | }, 851 | { 852 | "QSid": "313", 853 | "QDes": "/嗑到了", 854 | "IQLid": "313", 855 | "AQLid": "313", 856 | "QHide": "1", 857 | "EMCode": "10313", 858 | "AniStickerType": 1, 859 | "AniStickerPackId": "1", 860 | "AniStickerId": "3" 861 | }, 862 | { 863 | "QSid": "314", 864 | "QDes": "/仔细分析", 865 | "IQLid": "314", 866 | "AQLid": "314", 867 | "EMCode": "10314", 868 | "AniStickerType": 1, 869 | "AniStickerPackId": "1", 870 | "AniStickerId": "4" 871 | }, 872 | { 873 | "QSid": "315", 874 | "QDes": "/加油", 875 | "IQLid": "315", 876 | "AQLid": "315", 877 | "EMCode": "10315", 878 | "QHide": "1", 879 | "AniStickerType": 1, 880 | "AniStickerPackId": "1", 881 | "AniStickerId": "5" 882 | }, 883 | { 884 | "QSid": "316", 885 | "QDes": "/我没事", 886 | "IQLid": "316", 887 | "AQLid": "316", 888 | "QHide": "1", 889 | "EMCode": "10316", 890 | "AniStickerType": 1, 891 | "AniStickerPackId": "1", 892 | "AniStickerId": "6" 893 | }, 894 | { 895 | "QSid": "317", 896 | "QDes": "/菜汪", 897 | "IQLid": "317", 898 | "AQLid": "317", 899 | "EMCode": "10317", 900 | "AniStickerType": 1, 901 | "AniStickerPackId": "1", 902 | "AniStickerId": "7" 903 | }, 904 | { 905 | "QSid": "318", 906 | "QDes": "/崇拜", 907 | "IQLid": "318", 908 | "AQLid": "318", 909 | "EMCode": "10318", 910 | "AniStickerType": 1, 911 | "AniStickerPackId": "1", 912 | "AniStickerId": "8" 913 | }, 914 | { 915 | "QSid": "319", 916 | "QDes": "/比心", 917 | "IQLid": "319", 918 | "AQLid": "319", 919 | "EMCode": "10319", 920 | "AniStickerType": 1, 921 | "AniStickerPackId": "1", 922 | "AniStickerId": "9" 923 | }, 924 | { 925 | "QSid": "320", 926 | "QDes": "/庆祝", 927 | "IQLid": "320", 928 | "AQLid": "320", 929 | "EMCode": "10320", 930 | "AniStickerType": 1, 931 | "AniStickerPackId": "1", 932 | "AniStickerId": "10" 933 | }, 934 | { 935 | "QSid": "321", 936 | "QDes": "/老色痞", 937 | "IQLid": "321", 938 | "AQLid": "321", 939 | "QHide": "1", 940 | "EMCode": "10321", 941 | "AniStickerType": 1, 942 | "AniStickerPackId": "1", 943 | "AniStickerId": "11" 944 | }, 945 | { 946 | "QSid": "324", 947 | "QDes": "/吃糖", 948 | "IQLid": "324", 949 | "AQLid": "324", 950 | "EMCode": "10324", 951 | "AniStickerType": 1, 952 | "AniStickerPackId": "1", 953 | "AniStickerId": "12" 954 | }, 955 | { 956 | "QSid": "325", 957 | "QDes": "/惊吓", 958 | "IQLid": "325", 959 | "AQLid": "325", 960 | "EMCode": "10325", 961 | "AniStickerType": 1, 962 | "AniStickerPackId": "1", 963 | "AniStickerId": "14" 964 | }, 965 | { 966 | "QSid": "326", 967 | "QDes": "/生气", 968 | "IQLid": "326", 969 | "AQLid": "326", 970 | "EMCode": "10326", 971 | "AniStickerType": 1, 972 | "AniStickerPackId": "1", 973 | "AniStickerId": "15" 974 | }, 975 | { 976 | "QSid": "53", 977 | "QDes": "/蛋糕", 978 | "IQLid": "59", 979 | "AQLid": "59", 980 | "EMCode": "168", 981 | "AniStickerType": 1, 982 | "AniStickerPackId": "1", 983 | "AniStickerId": "17" 984 | }, 985 | { 986 | "QSid": "114", 987 | "QDes": "/篮球", 988 | "IQLid": "90", 989 | "AQLid": "92", 990 | "EMCode": "158", 991 | "AniStickerType": 0, 992 | "AniStickerPackId": "1", 993 | "AniStickerId": "13" 994 | }, 995 | { 996 | "QSid": "327", 997 | "QDes": "/加一", 998 | "QHide": "1", 999 | "IQLid": "327", 1000 | "AQLid": "327", 1001 | "EMCode": "10327" 1002 | }, 1003 | { 1004 | "QSid": "328", 1005 | "QDes": "/错号", 1006 | "QHide": "1", 1007 | "IQLid": "328", 1008 | "AQLid": "328", 1009 | "EMCode": "10328" 1010 | }, 1011 | { 1012 | "QSid": "329", 1013 | "QDes": "/对号", 1014 | "QHide": "1", 1015 | "IQLid": "329", 1016 | "AQLid": "329", 1017 | "EMCode": "10329" 1018 | }, 1019 | { 1020 | "QSid": "330", 1021 | "QDes": "/完成", 1022 | "QHide": "1", 1023 | "IQLid": "330", 1024 | "AQLid": "330", 1025 | "EMCode": "10330" 1026 | }, 1027 | { 1028 | "QSid": "331", 1029 | "QDes": "/明白", 1030 | "QHide": "1", 1031 | "IQLid": "331", 1032 | "AQLid": "331", 1033 | "EMCode": "10331" 1034 | }, 1035 | { 1036 | "QSid": "49", 1037 | "QDes": "/拥抱", 1038 | "IQLid": "45", 1039 | "AQLid": "45", 1040 | "EMCode": "178" 1041 | }, 1042 | { 1043 | "QSid": "66", 1044 | "QDes": "/爱心", 1045 | "isStatic": "1", 1046 | "IQLid": "28", 1047 | "AQLid": "28", 1048 | "EMCode": "166" 1049 | }, 1050 | { 1051 | "QSid": "63", 1052 | "QDes": "/玫瑰", 1053 | "isStatic": "1", 1054 | "IQLid": "8", 1055 | "AQLid": "8", 1056 | "EMCode": "163" 1057 | }, 1058 | { 1059 | "QSid": "64", 1060 | "QDes": "/凋谢", 1061 | "isStatic": "1", 1062 | "IQLid": "57", 1063 | "AQLid": "57", 1064 | "EMCode": "164" 1065 | }, 1066 | { 1067 | "QSid": "187", 1068 | "QDes": "/幽灵", 1069 | "IQLid": "157", 1070 | "AQLid": "179", 1071 | "EMCode": "257" 1072 | }, 1073 | { 1074 | "QSid": "146", 1075 | "QDes": "/爆筋", 1076 | "isStatic": "1", 1077 | "IQLid": "116", 1078 | "AQLid": "118", 1079 | "EMCode": "121011" 1080 | }, 1081 | { 1082 | "QSid": "116", 1083 | "QDes": "/示爱", 1084 | "IQLid": "29", 1085 | "AQLid": "29", 1086 | "EMCode": "165" 1087 | }, 1088 | { 1089 | "QSid": "67", 1090 | "QDes": "/心碎", 1091 | "IQLid": "72", 1092 | "AQLid": "74", 1093 | "EMCode": "167" 1094 | }, 1095 | { 1096 | "QSid": "60", 1097 | "QDes": "/咖啡", 1098 | "IQLid": "66", 1099 | "AQLid": "66", 1100 | "EMCode": "160" 1101 | }, 1102 | { 1103 | "QSid": "185", 1104 | "QDes": "/羊驼", 1105 | "IQLid": "155", 1106 | "AQLid": "177", 1107 | "EMCode": "255" 1108 | }, 1109 | { 1110 | "QSid": "192", 1111 | "QDes": "/红包", 1112 | "IQLid": "162", 1113 | "AQLid": "184", 1114 | "QHide": "1", 1115 | "EMCode": "262" 1116 | }, 1117 | { 1118 | "QSid": "137", 1119 | "QDes": "/鞭炮", 1120 | "isStatic": "1", 1121 | "IQLid": "107", 1122 | "AQLid": "109", 1123 | "EMCode": "121002", 1124 | "AniStickerType": 1, 1125 | "AniStickerPackId": "1", 1126 | "AniStickerId": "18" 1127 | }, 1128 | { 1129 | "QSid": "333", 1130 | "QDes": "/烟花", 1131 | "isStatic": "1", 1132 | "IQLid": "333", 1133 | "AQLid": "333", 1134 | "EMCode": "10333", 1135 | "AniStickerType": 1, 1136 | "AniStickerPackId": "1", 1137 | "AniStickerId": "19" 1138 | }, 1139 | { 1140 | "QSid": "138", 1141 | "QDes": "/灯笼", 1142 | "isStatic": "1", 1143 | "IQLid": "108", 1144 | "AQLid": "110", 1145 | "QHide": "1", 1146 | "EMCode": "121003" 1147 | }, 1148 | { 1149 | "QSid": "136", 1150 | "QDes": "/双喜", 1151 | "isStatic": "1", 1152 | "IQLid": "106", 1153 | "AQLid": "108", 1154 | "QHide": "1", 1155 | "EMCode": "121001" 1156 | }, 1157 | { 1158 | "QSid": "76", 1159 | "QDes": "/赞", 1160 | "IQLid": "52", 1161 | "AQLid": "52", 1162 | "EMCode": "179" 1163 | }, 1164 | { 1165 | "QSid": "124", 1166 | "QDes": "/OK", 1167 | "isStatic": "1", 1168 | "IQLid": "64", 1169 | "AQLid": "64", 1170 | "EMCode": "189" 1171 | }, 1172 | { 1173 | "QSid": "118", 1174 | "QDes": "/抱拳", 1175 | "IQLid": "56", 1176 | "AQLid": "56", 1177 | "EMCode": "183" 1178 | }, 1179 | { 1180 | "QSid": "78", 1181 | "QDes": "/握手", 1182 | "IQLid": "54", 1183 | "AQLid": "54", 1184 | "EMCode": "181" 1185 | }, 1186 | { 1187 | "QSid": "119", 1188 | "QDes": "/勾引", 1189 | "IQLid": "63", 1190 | "AQLid": "63", 1191 | "EMCode": "184" 1192 | }, 1193 | { 1194 | "QSid": "79", 1195 | "QDes": "/胜利", 1196 | "IQLid": "55", 1197 | "AQLid": "55", 1198 | "EMCode": "182" 1199 | }, 1200 | { 1201 | "QSid": "120", 1202 | "QDes": "/拳头", 1203 | "IQLid": "71", 1204 | "AQLid": "73", 1205 | "EMCode": "185" 1206 | }, 1207 | { 1208 | "QSid": "121", 1209 | "QDes": "/差劲", 1210 | "IQLid": "70", 1211 | "AQLid": "72", 1212 | "EMCode": "186" 1213 | }, 1214 | { 1215 | "QSid": "77", 1216 | "QDes": "/踩", 1217 | "IQLid": "53", 1218 | "AQLid": "53", 1219 | "EMCode": "180" 1220 | }, 1221 | { 1222 | "QSid": "122", 1223 | "QDes": "/爱你", 1224 | "IQLid": "65", 1225 | "AQLid": "65", 1226 | "QHide": "1", 1227 | "EMCode": "187" 1228 | }, 1229 | { 1230 | "QSid": "123", 1231 | "QDes": "/NO", 1232 | "IQLid": "92", 1233 | "AQLid": "94", 1234 | "QHide": "1", 1235 | "EMCode": "188" 1236 | }, 1237 | { 1238 | "QSid": "201", 1239 | "QDes": "/点赞", 1240 | "IQLid": "171", 1241 | "AQLid": "150", 1242 | "EMCode": "271" 1243 | }, 1244 | { 1245 | "QSid": "203", 1246 | "QDes": "/托脸", 1247 | "IQLid": "173", 1248 | "AQLid": "152", 1249 | "EMCode": "273" 1250 | }, 1251 | { 1252 | "QSid": "204", 1253 | "QDes": "/吃", 1254 | "IQLid": "174", 1255 | "AQLid": "153", 1256 | "EMCode": "274" 1257 | }, 1258 | { 1259 | "QSid": "202", 1260 | "QDes": "/无聊", 1261 | "IQLid": "172", 1262 | "AQLid": "151", 1263 | "EMCode": "272" 1264 | }, 1265 | { 1266 | "QSid": "200", 1267 | "QDes": "/拜托", 1268 | "IQLid": "170", 1269 | "AQLid": "149", 1270 | "EMCode": "270" 1271 | }, 1272 | { 1273 | "QSid": "194", 1274 | "QDes": "/不开心", 1275 | "IQLid": "164", 1276 | "AQLid": "143", 1277 | "EMCode": "264" 1278 | }, 1279 | { 1280 | "QSid": "193", 1281 | "QDes": "/大笑", 1282 | "IQLid": "163", 1283 | "AQLid": "185", 1284 | "EMCode": "263" 1285 | }, 1286 | { 1287 | "QSid": "197", 1288 | "QDes": "/冷漠", 1289 | "IQLid": "167", 1290 | "AQLid": "146", 1291 | "QHide": "1", 1292 | "EMCode": "267" 1293 | }, 1294 | { 1295 | "QSid": "211", 1296 | "QDes": "/我不看", 1297 | "IQLid": "181", 1298 | "AQLid": "160", 1299 | "QHide": "1", 1300 | "EMCode": "281" 1301 | }, 1302 | { 1303 | "QSid": "210", 1304 | "QDes": "/飙泪", 1305 | "IQLid": "180", 1306 | "AQLid": "159", 1307 | "QHide": "1", 1308 | "EMCode": "280" 1309 | }, 1310 | { 1311 | "QSid": "198", 1312 | "QDes": "/呃", 1313 | "IQLid": "168", 1314 | "AQLid": "147", 1315 | "EMCode": "268" 1316 | }, 1317 | { 1318 | "QSid": "199", 1319 | "QDes": "/好棒", 1320 | "IQLid": "169", 1321 | "AQLid": "148", 1322 | "QHide": "1", 1323 | "EMCode": "269" 1324 | }, 1325 | { 1326 | "QSid": "207", 1327 | "QDes": "/花痴", 1328 | "IQLid": "177", 1329 | "AQLid": "156", 1330 | "QHide": "1", 1331 | "EMCode": "277" 1332 | }, 1333 | { 1334 | "QSid": "205", 1335 | "QDes": "/送花", 1336 | "IQLid": "175", 1337 | "AQLid": "154", 1338 | "QHide": "1", 1339 | "EMCode": "275" 1340 | }, 1341 | { 1342 | "QSid": "206", 1343 | "QDes": "/害怕", 1344 | "IQLid": "176", 1345 | "AQLid": "155", 1346 | "EMCode": "276" 1347 | }, 1348 | { 1349 | "QSid": "208", 1350 | "QDes": "/小样儿", 1351 | "IQLid": "178", 1352 | "AQLid": "157", 1353 | "QHide": "1", 1354 | "EMCode": "278" 1355 | }, 1356 | { 1357 | "QSid": "308", 1358 | "QDes": "/求红包", 1359 | "IQLid": "308", 1360 | "isCMEmoji": "1", 1361 | "AQLid": "308", 1362 | "QHide": "1", 1363 | "EMCode": "20243" 1364 | }, 1365 | { 1366 | "QSid": "309", 1367 | "QDes": "/谢红包", 1368 | "IQLid": "309", 1369 | "isCMEmoji": "1", 1370 | "AQLid": "309", 1371 | "QHide": "1", 1372 | "EMCode": "20244" 1373 | }, 1374 | { 1375 | "QSid": "310", 1376 | "QDes": "/新年烟花", 1377 | "IQLid": "310", 1378 | "isCMEmoji": "1", 1379 | "AQLid": "310", 1380 | "QHide": "1", 1381 | "EMCode": "20245" 1382 | }, 1383 | { 1384 | "QSid": "290", 1385 | "QDes": "/敲开心", 1386 | "IQLid": "290", 1387 | "isCMEmoji": "1", 1388 | "AQLid": "290", 1389 | "QHide": "1", 1390 | "EMCode": "20240" 1391 | }, 1392 | { 1393 | "QSid": "291", 1394 | "QDes": "/震惊", 1395 | "IQLid": "291", 1396 | "isCMEmoji": "1", 1397 | "AQLid": "291", 1398 | "QHide": "1", 1399 | "EMCode": "20241" 1400 | }, 1401 | { 1402 | "QSid": "292", 1403 | "QDes": "/让我康康", 1404 | "IQLid": "292", 1405 | "isCMEmoji": "1", 1406 | "AQLid": "292", 1407 | "QHide": "1", 1408 | "EMCode": "20242" 1409 | }, 1410 | { 1411 | "QSid": "226", 1412 | "QDes": "/拍桌", 1413 | "IQLid": "196", 1414 | "isCMEmoji": "1", 1415 | "AQLid": "198", 1416 | "EMCode": "297" 1417 | }, 1418 | { 1419 | "QSid": "215", 1420 | "QDes": "/糊脸", 1421 | "IQLid": "185", 1422 | "isCMEmoji": "1", 1423 | "AQLid": "187", 1424 | "EMCode": "285" 1425 | }, 1426 | { 1427 | "QSid": "237", 1428 | "QDes": "/偷看", 1429 | "IQLid": "207", 1430 | "isCMEmoji": "1", 1431 | "AQLid": "209", 1432 | "EMCode": "307" 1433 | }, 1434 | { 1435 | "QSid": "214", 1436 | "QDes": "/啵啵", 1437 | "IQLid": "184", 1438 | "isCMEmoji": "1", 1439 | "AQLid": "186", 1440 | "EMCode": "284" 1441 | }, 1442 | { 1443 | "QSid": "235", 1444 | "QDes": "/颤抖", 1445 | "IQLid": "205", 1446 | "isCMEmoji": "1", 1447 | "AQLid": "207", 1448 | "EMCode": "305" 1449 | }, 1450 | { 1451 | "QSid": "222", 1452 | "QDes": "/抱抱", 1453 | "IQLid": "192", 1454 | "isCMEmoji": "1", 1455 | "AQLid": "194", 1456 | "EMCode": "292" 1457 | }, 1458 | { 1459 | "QSid": "217", 1460 | "QDes": "/扯一扯", 1461 | "IQLid": "187", 1462 | "isCMEmoji": "1", 1463 | "AQLid": "189", 1464 | "EMCode": "287" 1465 | }, 1466 | { 1467 | "QSid": "221", 1468 | "QDes": "/顶呱呱", 1469 | "IQLid": "191", 1470 | "isCMEmoji": "1", 1471 | "AQLid": "193", 1472 | "EMCode": "291" 1473 | }, 1474 | { 1475 | "QSid": "225", 1476 | "QDes": "/撩一撩", 1477 | "IQLid": "195", 1478 | "isCMEmoji": "1", 1479 | "AQLid": "197", 1480 | "EMCode": "296" 1481 | }, 1482 | { 1483 | "QSid": "241", 1484 | "QDes": "/生日快乐", 1485 | "IQLid": "211", 1486 | "isCMEmoji": "1", 1487 | "AQLid": "213", 1488 | "EMCode": "311" 1489 | }, 1490 | { 1491 | "QSid": "227", 1492 | "QDes": "/拍手", 1493 | "IQLid": "197", 1494 | "isCMEmoji": "1", 1495 | "AQLid": "199", 1496 | "EMCode": "294" 1497 | }, 1498 | { 1499 | "QSid": "238", 1500 | "QDes": "/扇脸", 1501 | "IQLid": "208", 1502 | "isCMEmoji": "1", 1503 | "AQLid": "210", 1504 | "EMCode": "308" 1505 | }, 1506 | { 1507 | "QSid": "240", 1508 | "QDes": "/喷脸", 1509 | "IQLid": "210", 1510 | "isCMEmoji": "1", 1511 | "AQLid": "212", 1512 | "EMCode": "310" 1513 | }, 1514 | { 1515 | "QSid": "229", 1516 | "QDes": "/干杯", 1517 | "IQLid": "199", 1518 | "isCMEmoji": "1", 1519 | "AQLid": "201", 1520 | "QHide": "1", 1521 | "EMCode": "299" 1522 | }, 1523 | { 1524 | "QSid": "216", 1525 | "QDes": "/拍头", 1526 | "IQLid": "186", 1527 | "isCMEmoji": "1", 1528 | "AQLid": "188", 1529 | "QHide": "1", 1530 | "EMCode": "286" 1531 | }, 1532 | { 1533 | "QSid": "218", 1534 | "QDes": "/舔一舔", 1535 | "IQLid": "188", 1536 | "isCMEmoji": "1", 1537 | "AQLid": "190", 1538 | "EMCode": "288" 1539 | }, 1540 | { 1541 | "QSid": "233", 1542 | "QDes": "/掐一掐", 1543 | "IQLid": "203", 1544 | "isCMEmoji": "1", 1545 | "AQLid": "205", 1546 | "EMCode": "303" 1547 | }, 1548 | { 1549 | "QSid": "219", 1550 | "QDes": "/蹭一蹭", 1551 | "IQLid": "189", 1552 | "isCMEmoji": "1", 1553 | "AQLid": "191", 1554 | "QHide": "1", 1555 | "EMCode": "289" 1556 | }, 1557 | { 1558 | "QSid": "244", 1559 | "QDes": "/扔狗", 1560 | "IQLid": "214", 1561 | "isCMEmoji": "1", 1562 | "AQLid": "216", 1563 | "QHide": "1", 1564 | "EMCode": "312" 1565 | }, 1566 | { 1567 | "QSid": "232", 1568 | "QDes": "/佛系", 1569 | "IQLid": "202", 1570 | "isCMEmoji": "1", 1571 | "AQLid": "204", 1572 | "QHide": "1", 1573 | "EMCode": "302" 1574 | }, 1575 | { 1576 | "QSid": "243", 1577 | "QDes": "/甩头", 1578 | "IQLid": "213", 1579 | "isCMEmoji": "1", 1580 | "AQLid": "215", 1581 | "QHide": "1", 1582 | "EMCode": "313" 1583 | }, 1584 | { 1585 | "QSid": "223", 1586 | "QDes": "/暴击", 1587 | "IQLid": "193", 1588 | "isCMEmoji": "1", 1589 | "AQLid": "195", 1590 | "QHide": "1", 1591 | "EMCode": "293" 1592 | }, 1593 | { 1594 | "QSid": "279", 1595 | "QDes": "/打脸", 1596 | "IQLid": "279", 1597 | "isCMEmoji": "1", 1598 | "AQLid": "279", 1599 | "QHide": "1", 1600 | "EMCode": "20238" 1601 | }, 1602 | { 1603 | "QSid": "280", 1604 | "QDes": "/击掌", 1605 | "IQLid": "280", 1606 | "isCMEmoji": "1", 1607 | "AQLid": "280", 1608 | "QHide": "1", 1609 | "EMCode": "20239" 1610 | }, 1611 | { 1612 | "QSid": "231", 1613 | "QDes": "/哼", 1614 | "IQLid": "201", 1615 | "isCMEmoji": "1", 1616 | "AQLid": "203", 1617 | "QHide": "1", 1618 | "EMCode": "301" 1619 | }, 1620 | { 1621 | "QSid": "224", 1622 | "QDes": "/开枪", 1623 | "IQLid": "194", 1624 | "isCMEmoji": "1", 1625 | "AQLid": "196", 1626 | "QHide": "1", 1627 | "EMCode": "295" 1628 | }, 1629 | { 1630 | "QSid": "278", 1631 | "QDes": "/汗", 1632 | "IQLid": "278", 1633 | "isCMEmoji": "1", 1634 | "AQLid": "278", 1635 | "QHide": "1", 1636 | "EMCode": "20237" 1637 | }, 1638 | { 1639 | "QSid": "236", 1640 | "QDes": "/啃头", 1641 | "IQLid": "206", 1642 | "isCMEmoji": "1", 1643 | "AQLid": "208", 1644 | "QHide": "1", 1645 | "EMCode": "306" 1646 | }, 1647 | { 1648 | "QSid": "228", 1649 | "QDes": "/恭喜", 1650 | "IQLid": "198", 1651 | "isCMEmoji": "1", 1652 | "AQLid": "200", 1653 | "QHide": "1", 1654 | "EMCode": "298" 1655 | }, 1656 | { 1657 | "QSid": "220", 1658 | "QDes": "/拽炸天", 1659 | "IQLid": "190", 1660 | "isCMEmoji": "1", 1661 | "AQLid": "192", 1662 | "QHide": "1", 1663 | "EMCode": "290" 1664 | }, 1665 | { 1666 | "QSid": "239", 1667 | "QDes": "/原谅", 1668 | "IQLid": "209", 1669 | "isCMEmoji": "1", 1670 | "AQLid": "211", 1671 | "QHide": "1", 1672 | "EMCode": "309" 1673 | }, 1674 | { 1675 | "QSid": "242", 1676 | "QDes": "/头撞击", 1677 | "IQLid": "212", 1678 | "isCMEmoji": "1", 1679 | "AQLid": "214", 1680 | "QHide": "1", 1681 | "EMCode": "314" 1682 | }, 1683 | { 1684 | "QSid": "230", 1685 | "QDes": "/嘲讽", 1686 | "IQLid": "200", 1687 | "isCMEmoji": "1", 1688 | "AQLid": "202", 1689 | "QHide": "1", 1690 | "EMCode": "300" 1691 | }, 1692 | { 1693 | "QSid": "234", 1694 | "QDes": "/惊呆", 1695 | "IQLid": "204", 1696 | "isCMEmoji": "1", 1697 | "AQLid": "206", 1698 | "QHide": "1", 1699 | "EMCode": "304" 1700 | }, 1701 | { 1702 | "QSid": "273", 1703 | "QDes": "/我酸了", 1704 | "isStatic": "1", 1705 | "IQLid": "273", 1706 | "AQLid": "273", 1707 | "EMCode": "10273" 1708 | }, 1709 | { 1710 | "QSid": "75", 1711 | "QDes": "/月亮", 1712 | "isStatic": "1", 1713 | "IQLid": "67", 1714 | "AQLid": "68", 1715 | "EMCode": "175" 1716 | }, 1717 | { 1718 | "QSid": "74", 1719 | "QDes": "/太阳", 1720 | "isStatic": "1", 1721 | "IQLid": "73", 1722 | "AQLid": "75", 1723 | "EMCode": "176" 1724 | }, 1725 | { 1726 | "QSid": "46", 1727 | "QDes": "/猪头", 1728 | "isStatic": "1", 1729 | "IQLid": "7", 1730 | "AQLid": "7", 1731 | "EMCode": "162" 1732 | }, 1733 | { 1734 | "QSid": "112", 1735 | "QDes": "/菜刀", 1736 | "IQLid": "17", 1737 | "AQLid": "17", 1738 | "EMCode": "155" 1739 | }, 1740 | { 1741 | "QSid": "56", 1742 | "QDes": "/刀", 1743 | "IQLid": "68", 1744 | "AQLid": "70", 1745 | "QHide": "1", 1746 | "EMCode": "171" 1747 | }, 1748 | { 1749 | "QSid": "169", 1750 | "QDes": "/手枪", 1751 | "isStatic": "1", 1752 | "IQLid": "139", 1753 | "AQLid": "141", 1754 | "QHide": "1", 1755 | "EMCode": "121034" 1756 | }, 1757 | { 1758 | "QSid": "171", 1759 | "QDes": "/茶", 1760 | "IQLid": "141", 1761 | "AQLid": "163", 1762 | "EMCode": "241" 1763 | }, 1764 | { 1765 | "QSid": "59", 1766 | "QDes": "/便便", 1767 | "IQLid": "15", 1768 | "AQLid": "15", 1769 | "EMCode": "174" 1770 | }, 1771 | { 1772 | "QSid": "144", 1773 | "QDes": "/喝彩", 1774 | "isStatic": "1", 1775 | "IQLid": "114", 1776 | "AQLid": "116", 1777 | "EMCode": "121009" 1778 | }, 1779 | { 1780 | "QSid": "147", 1781 | "QDes": "/棒棒糖", 1782 | "isStatic": "1", 1783 | "IQLid": "117", 1784 | "AQLid": "119", 1785 | "QHide": "1", 1786 | "EMCode": "121012" 1787 | }, 1788 | { 1789 | "QSid": "89", 1790 | "QDes": "/西瓜", 1791 | "isStatic": "1", 1792 | "IQLid": "60", 1793 | "AQLid": "60", 1794 | "EMCode": "156" 1795 | }, 1796 | { 1797 | "QSid": "61", 1798 | "QDes": "/饭", 1799 | "isStatic": "1", 1800 | "IQLid": "58", 1801 | "AQLid": "58", 1802 | "QHide": "1", 1803 | "EMCode": "161" 1804 | }, 1805 | { 1806 | "QSid": "148", 1807 | "QDes": "/喝奶", 1808 | "isStatic": "1", 1809 | "IQLid": "118", 1810 | "AQLid": "120", 1811 | "QHide": "1", 1812 | "EMCode": "121013" 1813 | }, 1814 | { 1815 | "QSid": "274", 1816 | "QDes": "/太南了", 1817 | "isStatic": "1", 1818 | "IQLid": "274", 1819 | "AQLid": "274", 1820 | "QHide": "1", 1821 | "EMCode": "10274" 1822 | }, 1823 | { 1824 | "QSid": "113", 1825 | "QDes": "/啤酒", 1826 | "IQLid": "61", 1827 | "AQLid": "61", 1828 | "QHide": "1", 1829 | "EMCode": "157" 1830 | }, 1831 | { 1832 | "QSid": "140", 1833 | "QDes": "/K歌", 1834 | "isStatic": "1", 1835 | "IQLid": "110", 1836 | "AQLid": "112", 1837 | "QHide": "1", 1838 | "EMCode": "121005" 1839 | }, 1840 | { 1841 | "QSid": "188", 1842 | "QDes": "/蛋", 1843 | "IQLid": "158", 1844 | "AQLid": "180", 1845 | "QHide": "1", 1846 | "EMCode": "258" 1847 | }, 1848 | { 1849 | "QSid": "55", 1850 | "QDes": "/炸弹", 1851 | "isStatic": "1", 1852 | "IQLid": "16", 1853 | "AQLid": "16", 1854 | "QHide": "1", 1855 | "EMCode": "170" 1856 | }, 1857 | { 1858 | "QSid": "184", 1859 | "QDes": "/河蟹", 1860 | "IQLid": "154", 1861 | "AQLid": "176", 1862 | "QHide": "1", 1863 | "EMCode": "254" 1864 | }, 1865 | { 1866 | "QSid": "158", 1867 | "QDes": "/钞票", 1868 | "isStatic": "1", 1869 | "IQLid": "128", 1870 | "AQLid": "130", 1871 | "QHide": "1", 1872 | "EMCode": "121023" 1873 | }, 1874 | { 1875 | "QSid": "54", 1876 | "QDes": "/闪电", 1877 | "isStatic": "1", 1878 | "IQLid": "78", 1879 | "AQLid": "80", 1880 | "QHide": "1", 1881 | "EMCode": "169" 1882 | }, 1883 | { 1884 | "QSid": "69", 1885 | "QDes": "/礼物", 1886 | "isStatic": "1", 1887 | "IQLid": "74", 1888 | "AQLid": "76", 1889 | "QHide": "1", 1890 | "EMCode": "177" 1891 | }, 1892 | { 1893 | "QSid": "190", 1894 | "QDes": "/菊花", 1895 | "IQLid": "160", 1896 | "AQLid": "182", 1897 | "QHide": "1", 1898 | "EMCode": "260" 1899 | }, 1900 | { 1901 | "QSid": "151", 1902 | "QDes": "/飞机", 1903 | "isStatic": "1", 1904 | "IQLid": "121", 1905 | "AQLid": "123", 1906 | "QHide": "1", 1907 | "EMCode": "121016" 1908 | }, 1909 | { 1910 | "QSid": "145", 1911 | "QDes": "/祈祷", 1912 | "isStatic": "1", 1913 | "IQLid": "115", 1914 | "AQLid": "117", 1915 | "QHide": "1", 1916 | "EMCode": "121010" 1917 | }, 1918 | { 1919 | "QSid": "117", 1920 | "QDes": "/瓢虫", 1921 | "IQLid": "62", 1922 | "AQLid": "62", 1923 | "QHide": "1", 1924 | "EMCode": "173" 1925 | }, 1926 | { 1927 | "QSid": "168", 1928 | "QDes": "/药", 1929 | "isStatic": "1", 1930 | "IQLid": "138", 1931 | "AQLid": "140", 1932 | "QHide": "1", 1933 | "EMCode": "121033" 1934 | }, 1935 | { 1936 | "QSid": "115", 1937 | "QDes": "/乒乓", 1938 | "IQLid": "91", 1939 | "AQLid": "93", 1940 | "QHide": "1", 1941 | "EMCode": "159" 1942 | }, 1943 | { 1944 | "QSid": "57", 1945 | "QDes": "/足球", 1946 | "IQLid": "75", 1947 | "AQLid": "77", 1948 | "QHide": "1", 1949 | "EMCode": "172" 1950 | }, 1951 | { 1952 | "QSid": "41", 1953 | "QDes": "/发抖", 1954 | "isStatic": "1", 1955 | "IQLid": "69", 1956 | "AQLid": "71", 1957 | "EMCode": "193" 1958 | }, 1959 | { 1960 | "QSid": "125", 1961 | "QDes": "/转圈", 1962 | "IQLid": "95", 1963 | "AQLid": "97", 1964 | "EMCode": "195" 1965 | }, 1966 | { 1967 | "QSid": "42", 1968 | "QDes": "/爱情", 1969 | "IQLid": "38", 1970 | "AQLid": "38", 1971 | "EMCode": "190" 1972 | }, 1973 | { 1974 | "QSid": "43", 1975 | "QDes": "/跳跳", 1976 | "IQLid": "93", 1977 | "AQLid": "95", 1978 | "EMCode": "192" 1979 | }, 1980 | { 1981 | "QSid": "86", 1982 | "QDes": "/怄火", 1983 | "IQLid": "94", 1984 | "AQLid": "96", 1985 | "EMCode": "194" 1986 | }, 1987 | { 1988 | "QSid": "129", 1989 | "QDes": "/挥手", 1990 | "IQLid": "77", 1991 | "AQLid": "79", 1992 | "EMCode": "199" 1993 | }, 1994 | { 1995 | "QSid": "85", 1996 | "QDes": "/飞吻", 1997 | "isStatic": "1", 1998 | "IQLid": "47", 1999 | "AQLid": "47", 2000 | "EMCode": "191" 2001 | }, 2002 | { 2003 | "QSid": "126", 2004 | "QDes": "/磕头", 2005 | "IQLid": "96", 2006 | "AQLid": "98", 2007 | "QHide": "1", 2008 | "EMCode": "196" 2009 | }, 2010 | { 2011 | "QSid": "128", 2012 | "QDes": "/跳绳", 2013 | "IQLid": "98", 2014 | "AQLid": "100", 2015 | "QHide": "1", 2016 | "EMCode": "198" 2017 | }, 2018 | { 2019 | "QSid": "130", 2020 | "QDes": "/激动", 2021 | "IQLid": "99", 2022 | "AQLid": "101", 2023 | "QHide": "1", 2024 | "EMCode": "200" 2025 | }, 2026 | { 2027 | "QSid": "127", 2028 | "QDes": "/回头", 2029 | "IQLid": "97", 2030 | "AQLid": "99", 2031 | "QHide": "1", 2032 | "EMCode": "197" 2033 | }, 2034 | { 2035 | "QSid": "132", 2036 | "QDes": "/献吻", 2037 | "IQLid": "101", 2038 | "AQLid": "103", 2039 | "QHide": "1", 2040 | "EMCode": "202" 2041 | }, 2042 | { 2043 | "QSid": "134", 2044 | "QDes": "/右太极", 2045 | "IQLid": "103", 2046 | "AQLid": "105", 2047 | "QHide": "1", 2048 | "EMCode": "204" 2049 | }, 2050 | { 2051 | "QSid": "133", 2052 | "QDes": "/左太极", 2053 | "IQLid": "102", 2054 | "AQLid": "104", 2055 | "QHide": "1", 2056 | "EMCode": "203" 2057 | }, 2058 | { 2059 | "QSid": "131", 2060 | "QDes": "/街舞", 2061 | "IQLid": "100", 2062 | "AQLid": "102", 2063 | "QHide": "1", 2064 | "EMCode": "201" 2065 | }, 2066 | { 2067 | "QSid": "276", 2068 | "QDes": "/辣椒酱", 2069 | "isStatic": "1", 2070 | "IQLid": "276", 2071 | "AQLid": "276", 2072 | "QHide": "1", 2073 | "EMCode": "10276" 2074 | } 2075 | ], 2076 | "emoji": [ 2077 | { 2078 | "QSid": "😊", 2079 | "QCid": "128522", 2080 | "AQLid": "0", 2081 | "QDes": "/嘿嘿", 2082 | "QHide": "1", 2083 | "EMCode": "400832" 2084 | }, 2085 | { 2086 | "QSid": "😌", 2087 | "QCid": "128524", 2088 | "AQLid": "1", 2089 | "QDes": "/羞涩", 2090 | "QHide": "1", 2091 | "EMCode": "400834" 2092 | }, 2093 | { 2094 | "QSid": "😚", 2095 | "QCid": "128538", 2096 | "AQLid": "2", 2097 | "QDes": "/亲亲", 2098 | "QHide": "1", 2099 | "EMCode": "400848" 2100 | }, 2101 | { 2102 | "QSid": "😓", 2103 | "QCid": "128531", 2104 | "AQLid": "3", 2105 | "QDes": "/汗", 2106 | "EMCode": "400841" 2107 | }, 2108 | { 2109 | "QSid": "😰", 2110 | "QCid": "128560", 2111 | "AQLid": "4", 2112 | "QDes": "/紧张", 2113 | "QHide": "1", 2114 | "EMCode": "400870" 2115 | }, 2116 | { 2117 | "QSid": "😝", 2118 | "QCid": "128541", 2119 | "AQLid": "5", 2120 | "QDes": "/吐舌", 2121 | "QHide": "1", 2122 | "EMCode": "400851" 2123 | }, 2124 | { 2125 | "QSid": "😁", 2126 | "QCid": "128513", 2127 | "AQLid": "6", 2128 | "QDes": "/呲牙", 2129 | "QHide": "1", 2130 | "EMCode": "400823" 2131 | }, 2132 | { 2133 | "QSid": "😜", 2134 | "QCid": "128540", 2135 | "AQLid": "7", 2136 | "QDes": "/淘气", 2137 | "QHide": "1", 2138 | "EMCode": "400850" 2139 | }, 2140 | { 2141 | "QSid": "☺", 2142 | "QCid": "9786", 2143 | "AQLid": "8", 2144 | "QDes": "/可爱", 2145 | "QHide": "1", 2146 | "EMCode": "401181" 2147 | }, 2148 | { 2149 | "QSid": "😉", 2150 | "QCid": "128521", 2151 | "AQLid": "9", 2152 | "QDes": "/媚眼", 2153 | "QHide": "1", 2154 | "EMCode": "400831" 2155 | }, 2156 | { 2157 | "QSid": "😍", 2158 | "QCid": "128525", 2159 | "AQLid": "10", 2160 | "QDes": "/花痴", 2161 | "EMCode": "400835" 2162 | }, 2163 | { 2164 | "QSid": "😔", 2165 | "QCid": "128532", 2166 | "AQLid": "11", 2167 | "QDes": "/失落", 2168 | "EMCode": "400842" 2169 | }, 2170 | { 2171 | "QSid": "😄", 2172 | "QCid": "128516", 2173 | "AQLid": "12", 2174 | "QDes": "/高兴", 2175 | "EMCode": "400826" 2176 | }, 2177 | { 2178 | "QSid": "😏", 2179 | "QCid": "128527", 2180 | "AQLid": "13", 2181 | "QDes": "/哼哼", 2182 | "QHide": "1", 2183 | "EMCode": "400837" 2184 | }, 2185 | { 2186 | "QSid": "😒", 2187 | "QCid": "128530", 2188 | "AQLid": "14", 2189 | "QDes": "/不屑", 2190 | "EMCode": "400840" 2191 | }, 2192 | { 2193 | "QSid": "😳", 2194 | "QCid": "128563", 2195 | "AQLid": "15", 2196 | "QDes": "/瞪眼", 2197 | "EMCode": "400873" 2198 | }, 2199 | { 2200 | "QSid": "😘", 2201 | "QCid": "128536", 2202 | "AQLid": "16", 2203 | "QDes": "/飞吻", 2204 | "EMCode": "400846" 2205 | }, 2206 | { 2207 | "QSid": "😭", 2208 | "QCid": "128557", 2209 | "AQLid": "17", 2210 | "QDes": "/大哭", 2211 | "EMCode": "400867" 2212 | }, 2213 | { 2214 | "QSid": "😱", 2215 | "QCid": "128561", 2216 | "AQLid": "18", 2217 | "QDes": "/害怕", 2218 | "QHide": "1", 2219 | "EMCode": "400871" 2220 | }, 2221 | { 2222 | "QSid": "😂", 2223 | "QCid": "128514", 2224 | "AQLid": "19", 2225 | "QDes": "/激动", 2226 | "EMCode": "400824" 2227 | }, 2228 | { 2229 | "QSid": "💪", 2230 | "QCid": "128170", 2231 | "AQLid": "20", 2232 | "QDes": "/肌肉", 2233 | "EMCode": "400644" 2234 | }, 2235 | { 2236 | "QSid": "👊", 2237 | "QCid": "128074", 2238 | "AQLid": "21", 2239 | "QDes": "/拳头", 2240 | "QHide": "1", 2241 | "EMCode": "400390" 2242 | }, 2243 | { 2244 | "QSid": "👍", 2245 | "QCid": "128077", 2246 | "AQLid": "22", 2247 | "QDes": "/厉害", 2248 | "EMCode": "400408" 2249 | }, 2250 | { 2251 | "QSid": "☝", 2252 | "QCid": "9757", 2253 | "AQLid": "23", 2254 | "QDes": "/向上", 2255 | "QHide": "1", 2256 | "EMCode": "401203" 2257 | }, 2258 | { 2259 | "QSid": "👏", 2260 | "QCid": "128079", 2261 | "AQLid": "24", 2262 | "QDes": "/鼓掌", 2263 | "EMCode": "400420" 2264 | }, 2265 | { 2266 | "QSid": "✌", 2267 | "QCid": "9996", 2268 | "AQLid": "25", 2269 | "QDes": "/胜利", 2270 | "QHide": "1", 2271 | "EMCode": "401210" 2272 | }, 2273 | { 2274 | "QSid": "👎", 2275 | "QCid": "128078", 2276 | "AQLid": "26", 2277 | "QDes": "/鄙视", 2278 | "QHide": "1", 2279 | "EMCode": "400414" 2280 | }, 2281 | { 2282 | "QSid": "🙏", 2283 | "QCid": "128591", 2284 | "AQLid": "27", 2285 | "QDes": "/合十", 2286 | "EMCode": "400396" 2287 | }, 2288 | { 2289 | "QSid": "👌", 2290 | "QCid": "128076", 2291 | "AQLid": "28", 2292 | "QDes": "/好的", 2293 | "EMCode": "400402" 2294 | }, 2295 | { 2296 | "QSid": "👈", 2297 | "QCid": "128072", 2298 | "AQLid": "29", 2299 | "QDes": "/向左", 2300 | "QHide": "1", 2301 | "EMCode": "400378" 2302 | }, 2303 | { 2304 | "QSid": "👉", 2305 | "QCid": "128073", 2306 | "AQLid": "30", 2307 | "QDes": "/向右", 2308 | "QHide": "1", 2309 | "EMCode": "400384" 2310 | }, 2311 | { 2312 | "QSid": "👆", 2313 | "QCid": "128070", 2314 | "AQLid": "31", 2315 | "QDes": "/向上", 2316 | "EMCode": "400366" 2317 | }, 2318 | { 2319 | "QSid": "👇", 2320 | "QCid": "128071", 2321 | "AQLid": "32", 2322 | "QDes": "/向下", 2323 | "QHide": "1", 2324 | "EMCode": "400372" 2325 | }, 2326 | { 2327 | "QSid": "👀", 2328 | "QCid": "128064", 2329 | "AQLid": "33", 2330 | "QDes": "/眼睛", 2331 | "EMCode": "400351" 2332 | }, 2333 | { 2334 | "QSid": "👃", 2335 | "QCid": "128067", 2336 | "AQLid": "34", 2337 | "QDes": "/鼻子", 2338 | "QHide": "1", 2339 | "EMCode": "400358" 2340 | }, 2341 | { 2342 | "QSid": "👄", 2343 | "QCid": "128068", 2344 | "AQLid": "35", 2345 | "QDes": "/嘴唇", 2346 | "QHide": "1", 2347 | "EMCode": "400364" 2348 | }, 2349 | { 2350 | "QSid": "👂", 2351 | "QCid": "128066", 2352 | "AQLid": "36", 2353 | "QDes": "/耳朵", 2354 | "QHide": "1", 2355 | "EMCode": "400352" 2356 | }, 2357 | { 2358 | "QSid": "🍚", 2359 | "QCid": "127834", 2360 | "AQLid": "37", 2361 | "QDes": "/米饭", 2362 | "QHide": "1", 2363 | "EMCode": "400149" 2364 | }, 2365 | { 2366 | "QSid": "🍝", 2367 | "QCid": "127837", 2368 | "AQLid": "38", 2369 | "QDes": "/意面", 2370 | "QHide": "1", 2371 | "EMCode": "400152" 2372 | }, 2373 | { 2374 | "QSid": "🍜", 2375 | "QCid": "127836", 2376 | "AQLid": "39", 2377 | "QDes": "/拉面", 2378 | "QHide": "1", 2379 | "EMCode": "400151" 2380 | }, 2381 | { 2382 | "QSid": "🍙", 2383 | "QCid": "127833", 2384 | "AQLid": "40", 2385 | "QDes": "/饭团", 2386 | "QHide": "1", 2387 | "EMCode": "400148" 2388 | }, 2389 | { 2390 | "QSid": "🍧", 2391 | "QCid": "127847", 2392 | "AQLid": "41", 2393 | "QDes": "/刨冰", 2394 | "QHide": "1", 2395 | "EMCode": "400162" 2396 | }, 2397 | { 2398 | "QSid": "🍣", 2399 | "QCid": "127843", 2400 | "AQLid": "42", 2401 | "QDes": "/寿司", 2402 | "QHide": "1", 2403 | "EMCode": "400158" 2404 | }, 2405 | { 2406 | "QSid": "🎂", 2407 | "QCid": "127874", 2408 | "AQLid": "43", 2409 | "QDes": "/蛋糕", 2410 | "QHide": "1", 2411 | "EMCode": "400186" 2412 | }, 2413 | { 2414 | "QSid": "🍞", 2415 | "QCid": "127838", 2416 | "AQLid": "44", 2417 | "QDes": "/面包", 2418 | "EMCode": "400153" 2419 | }, 2420 | { 2421 | "QSid": "🍔", 2422 | "QCid": "127828", 2423 | "AQLid": "45", 2424 | "QDes": "/汉堡", 2425 | "QHide": "1", 2426 | "EMCode": "400143" 2427 | }, 2428 | { 2429 | "QSid": "🍳", 2430 | "QCid": "127859", 2431 | "AQLid": "46", 2432 | "QDes": "/煎蛋", 2433 | "QHide": "1", 2434 | "EMCode": "400174" 2435 | }, 2436 | { 2437 | "QSid": "🍟", 2438 | "QCid": "127839", 2439 | "AQLid": "47", 2440 | "QDes": "/薯条", 2441 | "QHide": "1", 2442 | "EMCode": "400154" 2443 | }, 2444 | { 2445 | "QSid": "🍺", 2446 | "QCid": "127866", 2447 | "AQLid": "48", 2448 | "QDes": "/啤酒", 2449 | "QHide": "1", 2450 | "EMCode": "400181" 2451 | }, 2452 | { 2453 | "QSid": "🍻", 2454 | "QCid": "127867", 2455 | "AQLid": "49", 2456 | "QDes": "/干杯", 2457 | "QHide": "1", 2458 | "EMCode": "400182" 2459 | }, 2460 | { 2461 | "QSid": "🍸", 2462 | "QCid": "127864", 2463 | "AQLid": "50", 2464 | "QDes": "/高脚杯", 2465 | "QHide": "1", 2466 | "EMCode": "400179" 2467 | }, 2468 | { 2469 | "QSid": "☕", 2470 | "QCid": "9749", 2471 | "AQLid": "51", 2472 | "QDes": "/咖啡", 2473 | "QHide": "1", 2474 | "EMCode": "401262" 2475 | }, 2476 | { 2477 | "QSid": "🍎", 2478 | "QCid": "127822", 2479 | "AQLid": "52", 2480 | "QDes": "/苹果", 2481 | "QHide": "1", 2482 | "EMCode": "400137" 2483 | }, 2484 | { 2485 | "QSid": "🍊", 2486 | "QCid": "127818", 2487 | "AQLid": "53", 2488 | "QDes": "/橙子", 2489 | "QHide": "1", 2490 | "EMCode": "400133" 2491 | }, 2492 | { 2493 | "QSid": "🍓", 2494 | "QCid": "127827", 2495 | "AQLid": "54", 2496 | "QDes": "/草莓", 2497 | "QHide": "1", 2498 | "EMCode": "400142" 2499 | }, 2500 | { 2501 | "QSid": "🍉", 2502 | "QCid": "127817", 2503 | "AQLid": "55", 2504 | "QDes": "/西瓜", 2505 | "QHide": "1", 2506 | "EMCode": "400132" 2507 | }, 2508 | { 2509 | "QSid": "💊", 2510 | "QCid": "128138", 2511 | "AQLid": "56", 2512 | "QDes": "/药丸", 2513 | "QHide": "1", 2514 | "EMCode": "400612" 2515 | }, 2516 | { 2517 | "QSid": "🚬", 2518 | "QCid": "128684", 2519 | "AQLid": "57", 2520 | "QDes": "/吸烟", 2521 | "QHide": "1", 2522 | "EMCode": "400987" 2523 | }, 2524 | { 2525 | "QSid": "🎄", 2526 | "QCid": "127876", 2527 | "AQLid": "58", 2528 | "QDes": "/圣诞树", 2529 | "QHide": "1", 2530 | "EMCode": "400188" 2531 | }, 2532 | { 2533 | "QSid": "🌹", 2534 | "QCid": "127801", 2535 | "AQLid": "59", 2536 | "QDes": "/玫瑰", 2537 | "EMCode": "400116" 2538 | }, 2539 | { 2540 | "QSid": "🎉", 2541 | "QCid": "127881", 2542 | "AQLid": "60", 2543 | "QDes": "/庆祝", 2544 | "QHide": "1", 2545 | "EMCode": "400198" 2546 | }, 2547 | { 2548 | "QSid": "🌴", 2549 | "QCid": "127796", 2550 | "AQLid": "61", 2551 | "QDes": "/椰子树", 2552 | "QHide": "1", 2553 | "EMCode": "400112" 2554 | }, 2555 | { 2556 | "QSid": "💝", 2557 | "QCid": "128157", 2558 | "AQLid": "62", 2559 | "QDes": "/礼物", 2560 | "QHide": "1", 2561 | "EMCode": "400631" 2562 | }, 2563 | { 2564 | "QSid": "🎀", 2565 | "QCid": "127872", 2566 | "AQLid": "63", 2567 | "QDes": "/蝴蝶结", 2568 | "QHide": "1", 2569 | "EMCode": "400184" 2570 | }, 2571 | { 2572 | "QSid": "🎈", 2573 | "QCid": "127880", 2574 | "AQLid": "64", 2575 | "QDes": "/气球", 2576 | "QHide": "1", 2577 | "EMCode": "400197" 2578 | }, 2579 | { 2580 | "QSid": "🐚", 2581 | "QCid": "128026", 2582 | "AQLid": "65", 2583 | "QDes": "/海螺", 2584 | "QHide": "1", 2585 | "EMCode": "400314" 2586 | }, 2587 | { 2588 | "QSid": "💍", 2589 | "QCid": "128141", 2590 | "AQLid": "66", 2591 | "QDes": "/戒指", 2592 | "QHide": "1", 2593 | "EMCode": "400615" 2594 | }, 2595 | { 2596 | "QSid": "💣", 2597 | "QCid": "128163", 2598 | "AQLid": "67", 2599 | "QDes": "/炸弹", 2600 | "EMCode": "400637" 2601 | }, 2602 | { 2603 | "QSid": "👑", 2604 | "QCid": "128081", 2605 | "AQLid": "68", 2606 | "QDes": "/皇冠", 2607 | "QHide": "1", 2608 | "EMCode": "400432" 2609 | }, 2610 | { 2611 | "QSid": "🔔", 2612 | "QCid": "128276", 2613 | "AQLid": "69", 2614 | "QDes": "/铃铛", 2615 | "QHide": "1", 2616 | "EMCode": "400751" 2617 | }, 2618 | { 2619 | "QSid": "⭐", 2620 | "QCid": "11088", 2621 | "AQLid": "70", 2622 | "QDes": "/星星", 2623 | "QHide": "1", 2624 | "EMCode": "401686" 2625 | }, 2626 | { 2627 | "QSid": "✨", 2628 | "QCid": "10024", 2629 | "AQLid": "71", 2630 | "QDes": "/闪光", 2631 | "QHide": "1", 2632 | "EMCode": "401137" 2633 | }, 2634 | { 2635 | "QSid": "💨", 2636 | "QCid": "128168", 2637 | "AQLid": "72", 2638 | "QDes": "/吹气", 2639 | "QHide": "1", 2640 | "EMCode": "400642" 2641 | }, 2642 | { 2643 | "QSid": "💦", 2644 | "QCid": "128166", 2645 | "AQLid": "73", 2646 | "QDes": "/水", 2647 | "EMCode": "400640" 2648 | }, 2649 | { 2650 | "QSid": "🔥", 2651 | "QCid": "128293", 2652 | "AQLid": "74", 2653 | "QDes": "/火", 2654 | "QHide": "1", 2655 | "EMCode": "400768" 2656 | }, 2657 | { 2658 | "QSid": "🏆", 2659 | "QCid": "127942", 2660 | "AQLid": "75", 2661 | "QDes": "/奖杯", 2662 | "QHide": "1", 2663 | "EMCode": "400256" 2664 | }, 2665 | { 2666 | "QSid": "💰", 2667 | "QCid": "128176", 2668 | "AQLid": "76", 2669 | "QDes": "/钱", 2670 | "QHide": "1", 2671 | "EMCode": "400655" 2672 | }, 2673 | { 2674 | "QSid": "💤", 2675 | "QCid": "128164", 2676 | "AQLid": "77", 2677 | "QDes": "/睡觉", 2678 | "QHide": "1", 2679 | "EMCode": "400638" 2680 | }, 2681 | { 2682 | "QSid": "⚡", 2683 | "QCid": "9889", 2684 | "AQLid": "78", 2685 | "QDes": "/闪电", 2686 | "QHide": "1", 2687 | "EMCode": "401685" 2688 | }, 2689 | { 2690 | "QSid": "👣", 2691 | "QCid": "128099", 2692 | "AQLid": "79", 2693 | "QDes": "/脚印", 2694 | "QHide": "1", 2695 | "EMCode": "400450" 2696 | }, 2697 | { 2698 | "QSid": "💩", 2699 | "QCid": "128169", 2700 | "AQLid": "80", 2701 | "QDes": "/便便", 2702 | "EMCode": "400643" 2703 | }, 2704 | { 2705 | "QSid": "💉", 2706 | "QCid": "128137", 2707 | "AQLid": "81", 2708 | "QDes": "/打针", 2709 | "QHide": "1", 2710 | "EMCode": "400611" 2711 | }, 2712 | { 2713 | "QSid": "♨", 2714 | "QCid": "9832", 2715 | "AQLid": "82", 2716 | "QDes": "/热", 2717 | "QHide": "1", 2718 | "EMCode": "401287" 2719 | }, 2720 | { 2721 | "QSid": "📫", 2722 | "QCid": "128235", 2723 | "AQLid": "83", 2724 | "QDes": "/邮箱", 2725 | "EMCode": "400714" 2726 | }, 2727 | { 2728 | "QSid": "🔑", 2729 | "QCid": "128273", 2730 | "AQLid": "84", 2731 | "QDes": "/钥匙", 2732 | "QHide": "1", 2733 | "EMCode": "400748" 2734 | }, 2735 | { 2736 | "QSid": "🔒", 2737 | "QCid": "128274", 2738 | "AQLid": "85", 2739 | "QDes": "/锁", 2740 | "QHide": "1", 2741 | "EMCode": "400749" 2742 | }, 2743 | { 2744 | "QSid": "✈", 2745 | "QCid": "9992", 2746 | "AQLid": "86", 2747 | "QDes": "/飞机", 2748 | "QHide": "1", 2749 | "EMCode": "401298" 2750 | }, 2751 | { 2752 | "QSid": "🚄", 2753 | "QCid": "128644", 2754 | "AQLid": "87", 2755 | "QDes": "/列车", 2756 | "QHide": "1", 2757 | "EMCode": "400942" 2758 | }, 2759 | { 2760 | "QSid": "🚗", 2761 | "QCid": "128663", 2762 | "AQLid": "88", 2763 | "QDes": "/汽车", 2764 | "QHide": "1", 2765 | "EMCode": "400961" 2766 | }, 2767 | { 2768 | "QSid": "🚤", 2769 | "QCid": "128676", 2770 | "AQLid": "89", 2771 | "QDes": "/快艇", 2772 | "QHide": "1", 2773 | "EMCode": "400979" 2774 | }, 2775 | { 2776 | "QSid": "🚲", 2777 | "QCid": "128690", 2778 | "AQLid": "90", 2779 | "QDes": "/自行车", 2780 | "QHide": "1", 2781 | "EMCode": "400993" 2782 | }, 2783 | { 2784 | "QSid": "🐎", 2785 | "QCid": "128014", 2786 | "AQLid": "91", 2787 | "QDes": "/骑马", 2788 | "QHide": "1", 2789 | "EMCode": "400302" 2790 | }, 2791 | { 2792 | "QSid": "🚀", 2793 | "QCid": "128640", 2794 | "AQLid": "92", 2795 | "QDes": "/火箭", 2796 | "QHide": "1", 2797 | "EMCode": "400938" 2798 | }, 2799 | { 2800 | "QSid": "🚌", 2801 | "QCid": "128652", 2802 | "AQLid": "93", 2803 | "QDes": "/公交", 2804 | "QHide": "1", 2805 | "EMCode": "400950" 2806 | }, 2807 | { 2808 | "QSid": "⛵", 2809 | "QCid": "9973", 2810 | "AQLid": "94", 2811 | "QDes": "/船", 2812 | "QHide": "1", 2813 | "EMCode": "401294" 2814 | }, 2815 | { 2816 | "QSid": "👩", 2817 | "QCid": "128105", 2818 | "AQLid": "95", 2819 | "QDes": "/妈妈", 2820 | "QHide": "1", 2821 | "EMCode": "400482" 2822 | }, 2823 | { 2824 | "QSid": "👨", 2825 | "QCid": "128104", 2826 | "AQLid": "96", 2827 | "QDes": "/爸爸", 2828 | "QHide": "1", 2829 | "EMCode": "400465" 2830 | }, 2831 | { 2832 | "QSid": "👧", 2833 | "QCid": "128103", 2834 | "AQLid": "97", 2835 | "QDes": "/女孩", 2836 | "QHide": "1", 2837 | "EMCode": "400459" 2838 | }, 2839 | { 2840 | "QSid": "👦", 2841 | "QCid": "128102", 2842 | "AQLid": "98", 2843 | "QDes": "/男孩", 2844 | "QHide": "1", 2845 | "EMCode": "400453" 2846 | }, 2847 | { 2848 | "QSid": "🐵", 2849 | "QCid": "128053", 2850 | "AQLid": "99", 2851 | "QDes": "/猴", 2852 | "QHide": "1", 2853 | "EMCode": "400341" 2854 | }, 2855 | { 2856 | "QSid": "🐙", 2857 | "QCid": "128025", 2858 | "AQLid": "100", 2859 | "QDes": "/章鱼", 2860 | "QHide": "1", 2861 | "EMCode": "400313" 2862 | }, 2863 | { 2864 | "QSid": "🐷", 2865 | "QCid": "128055", 2866 | "AQLid": "101", 2867 | "QDes": "/猪", 2868 | "EMCode": "400343" 2869 | }, 2870 | { 2871 | "QSid": "💀", 2872 | "QCid": "128128", 2873 | "AQLid": "102", 2874 | "QDes": "/骷髅", 2875 | "QHide": "1", 2876 | "EMCode": "400572" 2877 | }, 2878 | { 2879 | "QSid": "🐤", 2880 | "QCid": "128036", 2881 | "AQLid": "103", 2882 | "QDes": "/小鸡", 2883 | "QHide": "1", 2884 | "EMCode": "400324" 2885 | }, 2886 | { 2887 | "QSid": "🐨", 2888 | "QCid": "128040", 2889 | "AQLid": "104", 2890 | "QDes": "/树懒", 2891 | "QHide": "1", 2892 | "EMCode": "400328" 2893 | }, 2894 | { 2895 | "QSid": "🐮", 2896 | "QCid": "128046", 2897 | "AQLid": "105", 2898 | "QDes": "/牛", 2899 | "EMCode": "400334" 2900 | }, 2901 | { 2902 | "QSid": "🐔", 2903 | "QCid": "128020", 2904 | "AQLid": "106", 2905 | "QDes": "/公鸡", 2906 | "QHide": "1", 2907 | "EMCode": "400308" 2908 | }, 2909 | { 2910 | "QSid": "🐸", 2911 | "QCid": "128056", 2912 | "AQLid": "107", 2913 | "QDes": "/青蛙", 2914 | "QHide": "1", 2915 | "EMCode": "400344" 2916 | }, 2917 | { 2918 | "QSid": "👻", 2919 | "QCid": "128123", 2920 | "AQLid": "108", 2921 | "QDes": "/幽灵", 2922 | "QHide": "1", 2923 | "EMCode": "400562" 2924 | }, 2925 | { 2926 | "QSid": "🐛", 2927 | "QCid": "128027", 2928 | "AQLid": "109", 2929 | "QDes": "/虫", 2930 | "QHide": "1", 2931 | "EMCode": "400315" 2932 | }, 2933 | { 2934 | "QSid": "🐠", 2935 | "QCid": "128032", 2936 | "AQLid": "110", 2937 | "QDes": "/鱼", 2938 | "QHide": "1", 2939 | "EMCode": "400320" 2940 | }, 2941 | { 2942 | "QSid": "🐶", 2943 | "QCid": "128054", 2944 | "AQLid": "111", 2945 | "QDes": "/狗", 2946 | "QHide": "1", 2947 | "EMCode": "400342" 2948 | }, 2949 | { 2950 | "QSid": "🐯", 2951 | "QCid": "128047", 2952 | "AQLid": "112", 2953 | "QDes": "/老虎", 2954 | "QHide": "1", 2955 | "EMCode": "400335" 2956 | }, 2957 | { 2958 | "QSid": "👼", 2959 | "QCid": "128124", 2960 | "AQLid": "113", 2961 | "QDes": "/天使", 2962 | "QHide": "1", 2963 | "EMCode": "400563" 2964 | }, 2965 | { 2966 | "QSid": "🐧", 2967 | "QCid": "128039", 2968 | "AQLid": "114", 2969 | "QDes": "/企鹅", 2970 | "QHide": "1", 2971 | "EMCode": "400327" 2972 | }, 2973 | { 2974 | "QSid": "🐳", 2975 | "QCid": "128051", 2976 | "AQLid": "115", 2977 | "QDes": "/鲸鱼", 2978 | "EMCode": "400339" 2979 | }, 2980 | { 2981 | "QSid": "🐭", 2982 | "QCid": "128045", 2983 | "AQLid": "116", 2984 | "QDes": "/老鼠", 2985 | "QHide": "1", 2986 | "EMCode": "400333" 2987 | }, 2988 | { 2989 | "QSid": "👒", 2990 | "QCid": "128082", 2991 | "AQLid": "117", 2992 | "QDes": "/帽子", 2993 | "QHide": "1", 2994 | "EMCode": "400433" 2995 | }, 2996 | { 2997 | "QSid": "👗", 2998 | "QCid": "128087", 2999 | "AQLid": "118", 3000 | "QDes": "/连衣裙", 3001 | "QHide": "1", 3002 | "EMCode": "400438" 3003 | }, 3004 | { 3005 | "QSid": "💄", 3006 | "QCid": "128132", 3007 | "AQLid": "119", 3008 | "QDes": "/口红", 3009 | "QHide": "1", 3010 | "EMCode": "400591" 3011 | }, 3012 | { 3013 | "QSid": "👠", 3014 | "QCid": "128096", 3015 | "AQLid": "120", 3016 | "QDes": "/高跟鞋", 3017 | "QHide": "1", 3018 | "EMCode": "400447" 3019 | }, 3020 | { 3021 | "QSid": "👢", 3022 | "QCid": "128098", 3023 | "AQLid": "121", 3024 | "QDes": "/靴子", 3025 | "EMCode": "400449" 3026 | }, 3027 | { 3028 | "QSid": "🌂", 3029 | "QCid": "127746", 3030 | "AQLid": "122", 3031 | "QDes": "/雨伞", 3032 | "QHide": "1", 3033 | "EMCode": "400077" 3034 | }, 3035 | { 3036 | "QSid": "👜", 3037 | "QCid": "128092", 3038 | "AQLid": "123", 3039 | "QDes": "/包", 3040 | "QHide": "1", 3041 | "EMCode": "400443" 3042 | }, 3043 | { 3044 | "QSid": "👙", 3045 | "QCid": "128089", 3046 | "AQLid": "124", 3047 | "QDes": "/内衣", 3048 | "QHide": "1", 3049 | "EMCode": "400440" 3050 | }, 3051 | { 3052 | "QSid": "👕", 3053 | "QCid": "128085", 3054 | "AQLid": "125", 3055 | "QDes": "/衣服", 3056 | "QHide": "1", 3057 | "EMCode": "400436" 3058 | }, 3059 | { 3060 | "QSid": "👟", 3061 | "QCid": "128095", 3062 | "AQLid": "126", 3063 | "QDes": "/鞋子", 3064 | "QHide": "1", 3065 | "EMCode": "400446" 3066 | }, 3067 | { 3068 | "QSid": "☁", 3069 | "QCid": "9729", 3070 | "AQLid": "127", 3071 | "QDes": "/云朵", 3072 | "QHide": "1", 3073 | "EMCode": "401329" 3074 | }, 3075 | { 3076 | "QSid": "☀", 3077 | "QCid": "9728", 3078 | "AQLid": "128", 3079 | "QDes": "/晴天", 3080 | "QHide": "1", 3081 | "EMCode": "401328" 3082 | }, 3083 | { 3084 | "QSid": "☔", 3085 | "QCid": "9748", 3086 | "AQLid": "129", 3087 | "QDes": "/雨天", 3088 | "QHide": "1", 3089 | "EMCode": "401342" 3090 | }, 3091 | { 3092 | "QSid": "🌙", 3093 | "QCid": "127769", 3094 | "AQLid": "130", 3095 | "QDes": "/月亮", 3096 | "QHide": "1", 3097 | "EMCode": "400100" 3098 | }, 3099 | { 3100 | "QSid": "⛄", 3101 | "QCid": "9924", 3102 | "AQLid": "131", 3103 | "QDes": "/雪人", 3104 | "QHide": "1", 3105 | "EMCode": "401346" 3106 | }, 3107 | { 3108 | "QSid": "⭕", 3109 | "QCid": "11093", 3110 | "AQLid": "132", 3111 | "QDes": "/正确", 3112 | "QHide": "1", 3113 | "EMCode": "401687" 3114 | }, 3115 | { 3116 | "QSid": "❌", 3117 | "QCid": "10060", 3118 | "AQLid": "133", 3119 | "QDes": "/错误", 3120 | "QHide": "1", 3121 | "EMCode": "401142" 3122 | }, 3123 | { 3124 | "QSid": "❔", 3125 | "QCid": "10068", 3126 | "AQLid": "134", 3127 | "QDes": "/问号", 3128 | "QHide": "1", 3129 | "EMCode": "401145" 3130 | }, 3131 | { 3132 | "QSid": "❕", 3133 | "QCid": "10069", 3134 | "AQLid": "135", 3135 | "QDes": "/叹号", 3136 | "QHide": "1", 3137 | "EMCode": "401146" 3138 | }, 3139 | { 3140 | "QSid": "☎", 3141 | "QCid": "9742", 3142 | "AQLid": "136", 3143 | "QDes": "/电话", 3144 | "QHide": "1", 3145 | "EMCode": "401398" 3146 | }, 3147 | { 3148 | "QSid": "📷", 3149 | "QCid": "128247", 3150 | "AQLid": "137", 3151 | "QDes": "/相机", 3152 | "QHide": "1", 3153 | "EMCode": "400726" 3154 | }, 3155 | { 3156 | "QSid": "📱", 3157 | "QCid": "128241", 3158 | "AQLid": "138", 3159 | "QDes": "/手机", 3160 | "QHide": "1", 3161 | "EMCode": "400720" 3162 | }, 3163 | { 3164 | "QSid": "📠", 3165 | "QCid": "128224", 3166 | "AQLid": "139", 3167 | "QDes": "/传真", 3168 | "QHide": "1", 3169 | "EMCode": "400703" 3170 | }, 3171 | { 3172 | "QSid": "💻", 3173 | "QCid": "128187", 3174 | "AQLid": "140", 3175 | "QDes": "/电脑", 3176 | "QHide": "1", 3177 | "EMCode": "400666" 3178 | }, 3179 | { 3180 | "QSid": "🎥", 3181 | "QCid": "127909", 3182 | "AQLid": "141", 3183 | "QDes": "/摄影机", 3184 | "QHide": "1", 3185 | "EMCode": "400214" 3186 | }, 3187 | { 3188 | "QSid": "🎤", 3189 | "QCid": "127908", 3190 | "AQLid": "142", 3191 | "QDes": "/话筒", 3192 | "QHide": "1", 3193 | "EMCode": "400213" 3194 | }, 3195 | { 3196 | "QSid": "🔫", 3197 | "QCid": "128299", 3198 | "AQLid": "143", 3199 | "QDes": "/手枪", 3200 | "QHide": "1", 3201 | "EMCode": "400774" 3202 | }, 3203 | { 3204 | "QSid": "💿", 3205 | "QCid": "128191", 3206 | "AQLid": "144", 3207 | "QDes": "/光碟", 3208 | "QHide": "1", 3209 | "EMCode": "400670" 3210 | }, 3211 | { 3212 | "QSid": "💓", 3213 | "QCid": "128147", 3214 | "AQLid": "145", 3215 | "QDes": "/爱心", 3216 | "QHide": "1", 3217 | "EMCode": "400621" 3218 | }, 3219 | { 3220 | "QSid": "♣", 3221 | "QCid": "9827", 3222 | "AQLid": "146", 3223 | "QDes": "/扑克", 3224 | "QHide": "1", 3225 | "EMCode": "401385" 3226 | }, 3227 | { 3228 | "QSid": "🀄", 3229 | "QCid": "126980", 3230 | "AQLid": "147", 3231 | "QDes": "/麻将", 3232 | "QHide": "1", 3233 | "EMCode": "401386" 3234 | }, 3235 | { 3236 | "QSid": "〽", 3237 | "QCid": "12349", 3238 | "AQLid": "148", 3239 | "QDes": "/股票", 3240 | "QHide": "1", 3241 | "EMCode": "401691" 3242 | }, 3243 | { 3244 | "QSid": "🎰", 3245 | "QCid": "127920", 3246 | "AQLid": "149", 3247 | "QDes": "/老虎机", 3248 | "QHide": "1", 3249 | "EMCode": "400225" 3250 | }, 3251 | { 3252 | "QSid": "🚥", 3253 | "QCid": "128677", 3254 | "AQLid": "150", 3255 | "QDes": "/信号灯", 3256 | "QHide": "1", 3257 | "EMCode": "400980" 3258 | }, 3259 | { 3260 | "QSid": "🚧", 3261 | "QCid": "128679", 3262 | "AQLid": "151", 3263 | "QDes": "/路障", 3264 | "QHide": "1", 3265 | "EMCode": "400982" 3266 | }, 3267 | { 3268 | "QSid": "🎸", 3269 | "QCid": "127928", 3270 | "AQLid": "152", 3271 | "QDes": "/吉他", 3272 | "QHide": "1", 3273 | "EMCode": "400233" 3274 | }, 3275 | { 3276 | "QSid": "💈", 3277 | "QCid": "128136", 3278 | "AQLid": "153", 3279 | "QDes": "/理发厅", 3280 | "QHide": "1", 3281 | "EMCode": "400610" 3282 | }, 3283 | { 3284 | "QSid": "🛀", 3285 | "QCid": "128704", 3286 | "AQLid": "154", 3287 | "QDes": "/浴缸", 3288 | "QHide": "1", 3289 | "EMCode": "401022" 3290 | }, 3291 | { 3292 | "QSid": "🚽", 3293 | "QCid": "128701", 3294 | "AQLid": "155", 3295 | "QDes": "/马桶", 3296 | "QHide": "1", 3297 | "EMCode": "401019" 3298 | }, 3299 | { 3300 | "QSid": "🏠", 3301 | "QCid": "127968", 3302 | "AQLid": "156", 3303 | "QDes": "/家", 3304 | "QHide": "1", 3305 | "EMCode": "400271" 3306 | }, 3307 | { 3308 | "QSid": "⛪", 3309 | "QCid": "9962", 3310 | "AQLid": "157", 3311 | "QDes": "/教堂", 3312 | "QHide": "1", 3313 | "EMCode": "401281" 3314 | }, 3315 | { 3316 | "QSid": "🏦", 3317 | "QCid": "127974", 3318 | "AQLid": "158", 3319 | "QDes": "/银行", 3320 | "QHide": "1", 3321 | "EMCode": "400277" 3322 | }, 3323 | { 3324 | "QSid": "🏥", 3325 | "QCid": "127973", 3326 | "AQLid": "159", 3327 | "QDes": "/医院", 3328 | "QHide": "1", 3329 | "EMCode": "400276" 3330 | }, 3331 | { 3332 | "QSid": "🏨", 3333 | "QCid": "127976", 3334 | "AQLid": "160", 3335 | "QDes": "/酒店", 3336 | "QHide": "1", 3337 | "EMCode": "400279" 3338 | }, 3339 | { 3340 | "QSid": "🏧", 3341 | "QCid": "127975", 3342 | "AQLid": "161", 3343 | "QDes": "/取款机", 3344 | "QHide": "1", 3345 | "EMCode": "400278" 3346 | }, 3347 | { 3348 | "QSid": "🏪", 3349 | "QCid": "127978", 3350 | "AQLid": "162", 3351 | "QDes": "/便利店", 3352 | "EMCode": "400281" 3353 | }, 3354 | { 3355 | "QSid": "🚹", 3356 | "QCid": "128697", 3357 | "AQLid": "163", 3358 | "QDes": "/男性", 3359 | "QHide": "1", 3360 | "EMCode": "401015" 3361 | }, 3362 | { 3363 | "QSid": "🚺", 3364 | "QCid": "128698", 3365 | "AQLid": "164", 3366 | "QDes": "/女性", 3367 | "QHide": "1", 3368 | "EMCode": "401016" 3369 | } 3370 | ] 3371 | } --------------------------------------------------------------------------------