diff --git a/package.json b/package.json
index 6b70464..3307ede 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,7 @@
     "deploy-win": "cmd /c \"xcopy /C /S /Y dist\\* %LITELOADERQQNT_PROFILE%\\plugins\\LLOneBot\\\"",
     "format": "prettier -cw .",
     "check": "tsc",
-    "compile:proto": "pbjs --no-create --no-convert --no-encode --no-verify -t static-module -w es6 -p src/ntqqapi/proto -o src/ntqqapi/proto/compiled.js systemMessage.proto profileLikeTip.proto groupMemberChange.proto && pbts -o src/ntqqapi/proto/compiled.d.ts src/ntqqapi/proto/compiled.js"
+    "compile:proto": "pbjs --no-create --no-convert --no-verify -t static-module -w es6 -p src/ntqqapi/proto -o src/ntqqapi/proto/compiled.js profileLikeTip.proto groupMemberChange.proto message.proto richMedia.proto && pbts -o src/ntqqapi/proto/compiled.d.ts src/ntqqapi/proto/compiled.js"
   },
   "author": "",
   "license": "MIT",
@@ -25,7 +25,6 @@
     "cors": "^2.8.5",
     "cosmokit": "^1.6.3",
     "express": "^5.0.1",
-    "fast-xml-parser": "^4.5.0",
     "fluent-ffmpeg": "^2.1.3",
     "minato": "^3.6.0",
     "protobufjs": "^7.4.0",
@@ -46,5 +45,5 @@
     "vite": "^5.4.9",
     "vite-plugin-cp": "^4.0.8"
   },
-  "packageManager": "yarn@4.5.0"
+  "packageManager": "yarn@4.5.1"
 }
diff --git a/src/ntqqapi/api/file.ts b/src/ntqqapi/api/file.ts
index 1dd3cfc..1768fd6 100644
--- a/src/ntqqapi/api/file.ts
+++ b/src/ntqqapi/api/file.ts
@@ -16,7 +16,7 @@ import path from 'node:path'
 import { existsSync } from 'node:fs'
 import { ReceiveCmdS } from '../hook'
 import { RkeyManager } from '@/ntqqapi/helper/rkey'
-import { RichMediaDownloadCompleteNotify, Peer } from '@/ntqqapi/types/msg'
+import { RichMediaDownloadCompleteNotify, RichMediaUploadCompleteNotify, RMBizType, Peer } from '@/ntqqapi/types/msg'
 import { calculateFileMD5 } from '@/common/utils/file'
 import { copyFile, stat, unlink } from 'node:fs/promises'
 import { Time } from 'cosmokit'
@@ -211,6 +211,28 @@ export class NTQQFileApi extends Service {
       ]
     )
   }
+
+  async uploadRMFileWithoutMsg(filePath: string, bizType: RMBizType, peerUid: string) {
+    const data = await invoke<{
+      notifyInfo: RichMediaUploadCompleteNotify
+    }>(
+      'nodeIKernelRichMediaService/uploadRMFileWithoutMsg',
+      [{
+        params: {
+          filePath,
+          bizType,
+          peerUid,
+          useNTV2: true
+        }
+      }],
+      {
+        cbCmd: ReceiveCmdS.MEDIA_UPLOAD_COMPLETE,
+        cmdCB: payload => payload.notifyInfo.filePath === filePath,
+        timeout: 10 * Time.second,
+      }
+    )
+    return data.notifyInfo
+  }
 }
 
 export class NTQQFileCacheApi extends Service {
diff --git a/src/ntqqapi/native/index.ts b/src/ntqqapi/native/index.ts
index 9606ae4..843e1ef 100644
--- a/src/ntqqapi/native/index.ts
+++ b/src/ntqqapi/native/index.ts
@@ -3,11 +3,15 @@ import { Dict } from 'cosmokit'
 import { getBuildVersion } from '@/common/utils/misc'
 import { TEMP_DIR } from '@/common/globalVars'
 import { copyFile } from 'fs/promises'
+import { ChatType, Peer } from '../types'
 import path from 'node:path'
 import addon from './external/crychic-win32-x64.node?asset'
 
 export class Native {
+  public activated = false
   private crychic?: Dict
+  private seq = 0
+  private cb: Map<number, Function> = new Map()
 
   constructor(private ctx: Context) {
     ctx.on('ready', () => {
@@ -35,6 +39,11 @@ export class Native {
     if (!this.checkVersion()) {
       return
     }
+    const handler = async (name: string, ...e: unknown[]) => {
+      if (name === 'cb') {
+        this.cb.get(e[0] as number)?.(e[1])
+      }
+    }
     try {
       const fileName = path.basename(addon)
       const dest = path.join(TEMP_DIR, fileName)
@@ -45,7 +54,9 @@ export class Native {
         this.ctx.logger.warn(e)
       }
       this.crychic = require(dest)
+      this.crychic!.setCryHandler(handler)
       this.crychic!.init()
+      this.activated = true
     } catch (e) {
       this.ctx.logger.warn('crychic 加载失败', e)
     }
@@ -62,4 +73,27 @@ export class Native {
     this.crychic.sendGroupPoke(memberUin, groupCode)
     await this.ctx.ntMsgApi.fetchUnitedCommendConfig(['100243'])
   }
+
+  uploadForward(peer: Peer, transmit: Uint8Array) {
+    return new Promise<string>(async (resolve, reject) => {
+      if (!this.crychic) return
+      let groupCode = 0
+      const uid = peer.peerUid
+      const isGroup = peer.chatType === ChatType.Group
+      if (isGroup) {
+        groupCode = +uid
+      }
+      const seq = ++this.seq
+      this.cb.set(seq, (resid: string) => {
+        this.cb.delete(seq)
+        resolve(resid)
+      })
+      setTimeout(() => {
+        this.cb.delete(seq)
+        reject(new Error('fake forward timeout'))
+      }, 5000)
+      this.crychic.uploadForward(seq, isGroup, uid, groupCode, transmit)
+      await this.ctx.ntMsgApi.fetchUnitedCommendConfig(['100243'])
+    })
+  }
 }
diff --git a/src/ntqqapi/proto/compiled.d.ts b/src/ntqqapi/proto/compiled.d.ts
index fc0f684..4b3318f 100644
--- a/src/ntqqapi/proto/compiled.d.ts
+++ b/src/ntqqapi/proto/compiled.d.ts
@@ -3,244 +3,6 @@ import Long = require("long");
 /** Namespace SysMsg. */
 export namespace SysMsg {
 
-    /** Properties of a SystemMessage. */
-    interface ISystemMessage {
-
-        /** SystemMessage header */
-        header?: (SysMsg.ISystemMessageHeader[]|null);
-
-        /** SystemMessage msgSpec */
-        msgSpec?: (SysMsg.ISystemMessageMsgSpec[]|null);
-
-        /** SystemMessage bodyWrapper */
-        bodyWrapper?: (SysMsg.ISystemMessageBodyWrapper|null);
-    }
-
-    /** Represents a SystemMessage. */
-    class SystemMessage implements ISystemMessage {
-
-        /**
-         * Constructs a new SystemMessage.
-         * @param [properties] Properties to set
-         */
-        constructor(properties?: SysMsg.ISystemMessage);
-
-        /** SystemMessage header. */
-        public header: SysMsg.ISystemMessageHeader[];
-
-        /** SystemMessage msgSpec. */
-        public msgSpec: SysMsg.ISystemMessageMsgSpec[];
-
-        /** SystemMessage bodyWrapper. */
-        public bodyWrapper?: (SysMsg.ISystemMessageBodyWrapper|null);
-
-        /**
-         * Decodes a SystemMessage message from the specified reader or buffer.
-         * @param reader Reader or buffer to decode from
-         * @param [length] Message length if known beforehand
-         * @returns SystemMessage
-         * @throws {Error} If the payload is not a reader or valid buffer
-         * @throws {$protobuf.util.ProtocolError} If required fields are missing
-         */
-        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): SysMsg.SystemMessage;
-
-        /**
-         * Decodes a SystemMessage message from the specified reader or buffer, length delimited.
-         * @param reader Reader or buffer to decode from
-         * @returns SystemMessage
-         * @throws {Error} If the payload is not a reader or valid buffer
-         * @throws {$protobuf.util.ProtocolError} If required fields are missing
-         */
-        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): SysMsg.SystemMessage;
-
-        /**
-         * Gets the default type url for SystemMessage
-         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
-         * @returns The default type url
-         */
-        public static getTypeUrl(typeUrlPrefix?: string): string;
-    }
-
-    /** Properties of a SystemMessageHeader. */
-    interface ISystemMessageHeader {
-
-        /** SystemMessageHeader peerUin */
-        peerUin?: (number|null);
-
-        /** SystemMessageHeader uin */
-        uin?: (number|null);
-
-        /** SystemMessageHeader uid */
-        uid?: (string|null);
-    }
-
-    /** Represents a SystemMessageHeader. */
-    class SystemMessageHeader implements ISystemMessageHeader {
-
-        /**
-         * Constructs a new SystemMessageHeader.
-         * @param [properties] Properties to set
-         */
-        constructor(properties?: SysMsg.ISystemMessageHeader);
-
-        /** SystemMessageHeader peerUin. */
-        public peerUin: number;
-
-        /** SystemMessageHeader uin. */
-        public uin: number;
-
-        /** SystemMessageHeader uid. */
-        public uid?: (string|null);
-
-        /**
-         * Decodes a SystemMessageHeader message from the specified reader or buffer.
-         * @param reader Reader or buffer to decode from
-         * @param [length] Message length if known beforehand
-         * @returns SystemMessageHeader
-         * @throws {Error} If the payload is not a reader or valid buffer
-         * @throws {$protobuf.util.ProtocolError} If required fields are missing
-         */
-        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): SysMsg.SystemMessageHeader;
-
-        /**
-         * Decodes a SystemMessageHeader message from the specified reader or buffer, length delimited.
-         * @param reader Reader or buffer to decode from
-         * @returns SystemMessageHeader
-         * @throws {Error} If the payload is not a reader or valid buffer
-         * @throws {$protobuf.util.ProtocolError} If required fields are missing
-         */
-        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): SysMsg.SystemMessageHeader;
-
-        /**
-         * Gets the default type url for SystemMessageHeader
-         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
-         * @returns The default type url
-         */
-        public static getTypeUrl(typeUrlPrefix?: string): string;
-    }
-
-    /** Properties of a SystemMessageMsgSpec. */
-    interface ISystemMessageMsgSpec {
-
-        /** SystemMessageMsgSpec msgType */
-        msgType?: (number|null);
-
-        /** SystemMessageMsgSpec subType */
-        subType?: (number|null);
-
-        /** SystemMessageMsgSpec subSubType */
-        subSubType?: (number|null);
-
-        /** SystemMessageMsgSpec msgSeq */
-        msgSeq?: (number|null);
-
-        /** SystemMessageMsgSpec time */
-        time?: (number|null);
-
-        /** SystemMessageMsgSpec other */
-        other?: (number|null);
-    }
-
-    /** Represents a SystemMessageMsgSpec. */
-    class SystemMessageMsgSpec implements ISystemMessageMsgSpec {
-
-        /**
-         * Constructs a new SystemMessageMsgSpec.
-         * @param [properties] Properties to set
-         */
-        constructor(properties?: SysMsg.ISystemMessageMsgSpec);
-
-        /** SystemMessageMsgSpec msgType. */
-        public msgType: number;
-
-        /** SystemMessageMsgSpec subType. */
-        public subType?: (number|null);
-
-        /** SystemMessageMsgSpec subSubType. */
-        public subSubType?: (number|null);
-
-        /** SystemMessageMsgSpec msgSeq. */
-        public msgSeq: number;
-
-        /** SystemMessageMsgSpec time. */
-        public time: number;
-
-        /** SystemMessageMsgSpec other. */
-        public other?: (number|null);
-
-        /**
-         * Decodes a SystemMessageMsgSpec message from the specified reader or buffer.
-         * @param reader Reader or buffer to decode from
-         * @param [length] Message length if known beforehand
-         * @returns SystemMessageMsgSpec
-         * @throws {Error} If the payload is not a reader or valid buffer
-         * @throws {$protobuf.util.ProtocolError} If required fields are missing
-         */
-        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): SysMsg.SystemMessageMsgSpec;
-
-        /**
-         * Decodes a SystemMessageMsgSpec message from the specified reader or buffer, length delimited.
-         * @param reader Reader or buffer to decode from
-         * @returns SystemMessageMsgSpec
-         * @throws {Error} If the payload is not a reader or valid buffer
-         * @throws {$protobuf.util.ProtocolError} If required fields are missing
-         */
-        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): SysMsg.SystemMessageMsgSpec;
-
-        /**
-         * Gets the default type url for SystemMessageMsgSpec
-         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
-         * @returns The default type url
-         */
-        public static getTypeUrl(typeUrlPrefix?: string): string;
-    }
-
-    /** Properties of a SystemMessageBodyWrapper. */
-    interface ISystemMessageBodyWrapper {
-
-        /** SystemMessageBodyWrapper body */
-        body?: (Uint8Array|null);
-    }
-
-    /** Represents a SystemMessageBodyWrapper. */
-    class SystemMessageBodyWrapper implements ISystemMessageBodyWrapper {
-
-        /**
-         * Constructs a new SystemMessageBodyWrapper.
-         * @param [properties] Properties to set
-         */
-        constructor(properties?: SysMsg.ISystemMessageBodyWrapper);
-
-        /** SystemMessageBodyWrapper body. */
-        public body: Uint8Array;
-
-        /**
-         * Decodes a SystemMessageBodyWrapper message from the specified reader or buffer.
-         * @param reader Reader or buffer to decode from
-         * @param [length] Message length if known beforehand
-         * @returns SystemMessageBodyWrapper
-         * @throws {Error} If the payload is not a reader or valid buffer
-         * @throws {$protobuf.util.ProtocolError} If required fields are missing
-         */
-        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): SysMsg.SystemMessageBodyWrapper;
-
-        /**
-         * Decodes a SystemMessageBodyWrapper message from the specified reader or buffer, length delimited.
-         * @param reader Reader or buffer to decode from
-         * @returns SystemMessageBodyWrapper
-         * @throws {Error} If the payload is not a reader or valid buffer
-         * @throws {$protobuf.util.ProtocolError} If required fields are missing
-         */
-        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): SysMsg.SystemMessageBodyWrapper;
-
-        /**
-         * Gets the default type url for SystemMessageBodyWrapper
-         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
-         * @returns The default type url
-         */
-        public static getTypeUrl(typeUrlPrefix?: string): string;
-    }
-
     /** Properties of a LikeDetail. */
     interface ILikeDetail {
 
@@ -272,6 +34,22 @@ export namespace SysMsg {
         /** LikeDetail nickname. */
         public nickname: string;
 
+        /**
+         * Encodes the specified LikeDetail message. Does not implicitly {@link SysMsg.LikeDetail.verify|verify} messages.
+         * @param message LikeDetail message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: SysMsg.ILikeDetail, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified LikeDetail message, length delimited. Does not implicitly {@link SysMsg.LikeDetail.verify|verify} messages.
+         * @param message LikeDetail message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: SysMsg.ILikeDetail, writer?: $protobuf.Writer): $protobuf.Writer;
+
         /**
          * Decodes a LikeDetail message from the specified reader or buffer.
          * @param reader Reader or buffer to decode from
@@ -330,6 +108,22 @@ export namespace SysMsg {
         /** LikeMsg detail. */
         public detail?: (SysMsg.ILikeDetail|null);
 
+        /**
+         * Encodes the specified LikeMsg message. Does not implicitly {@link SysMsg.LikeMsg.verify|verify} messages.
+         * @param message LikeMsg message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: SysMsg.ILikeMsg, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified LikeMsg message, length delimited. Does not implicitly {@link SysMsg.LikeMsg.verify|verify} messages.
+         * @param message LikeMsg message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: SysMsg.ILikeMsg, writer?: $protobuf.Writer): $protobuf.Writer;
+
         /**
          * Decodes a LikeMsg message from the specified reader or buffer.
          * @param reader Reader or buffer to decode from
@@ -376,6 +170,22 @@ export namespace SysMsg {
         /** ProfileLikeSubTip msg. */
         public msg?: (SysMsg.ILikeMsg|null);
 
+        /**
+         * Encodes the specified ProfileLikeSubTip message. Does not implicitly {@link SysMsg.ProfileLikeSubTip.verify|verify} messages.
+         * @param message ProfileLikeSubTip message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: SysMsg.IProfileLikeSubTip, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified ProfileLikeSubTip message, length delimited. Does not implicitly {@link SysMsg.ProfileLikeSubTip.verify|verify} messages.
+         * @param message ProfileLikeSubTip message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: SysMsg.IProfileLikeSubTip, writer?: $protobuf.Writer): $protobuf.Writer;
+
         /**
          * Decodes a ProfileLikeSubTip message from the specified reader or buffer.
          * @param reader Reader or buffer to decode from
@@ -434,6 +244,22 @@ export namespace SysMsg {
         /** ProfileLikeTip content. */
         public content?: (SysMsg.IProfileLikeSubTip|null);
 
+        /**
+         * Encodes the specified ProfileLikeTip message. Does not implicitly {@link SysMsg.ProfileLikeTip.verify|verify} messages.
+         * @param message ProfileLikeTip message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: SysMsg.IProfileLikeTip, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified ProfileLikeTip message, length delimited. Does not implicitly {@link SysMsg.ProfileLikeTip.verify|verify} messages.
+         * @param message ProfileLikeTip message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: SysMsg.IProfileLikeTip, writer?: $protobuf.Writer): $protobuf.Writer;
+
         /**
          * Decodes a ProfileLikeTip message from the specified reader or buffer.
          * @param reader Reader or buffer to decode from
@@ -498,6 +324,22 @@ export namespace SysMsg {
         /** GroupMemberChange adminUid. */
         public adminUid: string;
 
+        /**
+         * Encodes the specified GroupMemberChange message. Does not implicitly {@link SysMsg.GroupMemberChange.verify|verify} messages.
+         * @param message GroupMemberChange message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: SysMsg.IGroupMemberChange, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified GroupMemberChange message, length delimited. Does not implicitly {@link SysMsg.GroupMemberChange.verify|verify} messages.
+         * @param message GroupMemberChange message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: SysMsg.IGroupMemberChange, writer?: $protobuf.Writer): $protobuf.Writer;
+
         /**
          * Decodes a GroupMemberChange message from the specified reader or buffer.
          * @param reader Reader or buffer to decode from
@@ -525,3 +367,2349 @@ export namespace SysMsg {
         public static getTypeUrl(typeUrlPrefix?: string): string;
     }
 }
+
+/** Namespace Msg. */
+export namespace Msg {
+
+    /** Properties of a RoutingHead. */
+    interface IRoutingHead {
+
+        /** RoutingHead fromUin */
+        fromUin?: (number|Long|null);
+
+        /** RoutingHead fromUid */
+        fromUid?: (string|null);
+
+        /** RoutingHead fromAppid */
+        fromAppid?: (number|null);
+
+        /** RoutingHead fromInstid */
+        fromInstid?: (number|null);
+
+        /** RoutingHead toUin */
+        toUin?: (number|Long|null);
+
+        /** RoutingHead toUid */
+        toUid?: (string|null);
+
+        /** RoutingHead c2c */
+        c2c?: (Msg.IC2c|null);
+
+        /** RoutingHead group */
+        group?: (Msg.IGroup|null);
+    }
+
+    /** Represents a RoutingHead. */
+    class RoutingHead implements IRoutingHead {
+
+        /**
+         * Constructs a new RoutingHead.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.IRoutingHead);
+
+        /** RoutingHead fromUin. */
+        public fromUin?: (number|Long|null);
+
+        /** RoutingHead fromUid. */
+        public fromUid?: (string|null);
+
+        /** RoutingHead fromAppid. */
+        public fromAppid?: (number|null);
+
+        /** RoutingHead fromInstid. */
+        public fromInstid?: (number|null);
+
+        /** RoutingHead toUin. */
+        public toUin?: (number|Long|null);
+
+        /** RoutingHead toUid. */
+        public toUid?: (string|null);
+
+        /** RoutingHead c2c. */
+        public c2c?: (Msg.IC2c|null);
+
+        /** RoutingHead group. */
+        public group?: (Msg.IGroup|null);
+
+        /**
+         * Encodes the specified RoutingHead message. Does not implicitly {@link Msg.RoutingHead.verify|verify} messages.
+         * @param message RoutingHead message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.IRoutingHead, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified RoutingHead message, length delimited. Does not implicitly {@link Msg.RoutingHead.verify|verify} messages.
+         * @param message RoutingHead message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.IRoutingHead, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a RoutingHead message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns RoutingHead
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.RoutingHead;
+
+        /**
+         * Decodes a RoutingHead message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns RoutingHead
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.RoutingHead;
+
+        /**
+         * Gets the default type url for RoutingHead
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a C2c. */
+    interface IC2c {
+
+        /** C2c friendName */
+        friendName?: (string|null);
+    }
+
+    /** Represents a C2c. */
+    class C2c implements IC2c {
+
+        /**
+         * Constructs a new C2c.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.IC2c);
+
+        /** C2c friendName. */
+        public friendName?: (string|null);
+
+        /**
+         * Encodes the specified C2c message. Does not implicitly {@link Msg.C2c.verify|verify} messages.
+         * @param message C2c message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.IC2c, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified C2c message, length delimited. Does not implicitly {@link Msg.C2c.verify|verify} messages.
+         * @param message C2c message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.IC2c, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a C2c message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns C2c
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.C2c;
+
+        /**
+         * Decodes a C2c message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns C2c
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.C2c;
+
+        /**
+         * Gets the default type url for C2c
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a Group. */
+    interface IGroup {
+
+        /** Group groupCode */
+        groupCode?: (number|Long|null);
+
+        /** Group groupType */
+        groupType?: (number|null);
+
+        /** Group groupInfoSeq */
+        groupInfoSeq?: (number|Long|null);
+
+        /** Group groupCard */
+        groupCard?: (string|null);
+
+        /** Group groupCardType */
+        groupCardType?: (number|null);
+
+        /** Group groupLevel */
+        groupLevel?: (number|null);
+
+        /** Group groupName */
+        groupName?: (string|null);
+
+        /** Group extGroupKeyInfo */
+        extGroupKeyInfo?: (string|null);
+
+        /** Group msgFlag */
+        msgFlag?: (number|null);
+    }
+
+    /** Represents a Group. */
+    class Group implements IGroup {
+
+        /**
+         * Constructs a new Group.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.IGroup);
+
+        /** Group groupCode. */
+        public groupCode?: (number|Long|null);
+
+        /** Group groupType. */
+        public groupType?: (number|null);
+
+        /** Group groupInfoSeq. */
+        public groupInfoSeq?: (number|Long|null);
+
+        /** Group groupCard. */
+        public groupCard?: (string|null);
+
+        /** Group groupCardType. */
+        public groupCardType?: (number|null);
+
+        /** Group groupLevel. */
+        public groupLevel?: (number|null);
+
+        /** Group groupName. */
+        public groupName?: (string|null);
+
+        /** Group extGroupKeyInfo. */
+        public extGroupKeyInfo?: (string|null);
+
+        /** Group msgFlag. */
+        public msgFlag?: (number|null);
+
+        /**
+         * Encodes the specified Group message. Does not implicitly {@link Msg.Group.verify|verify} messages.
+         * @param message Group message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.IGroup, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified Group message, length delimited. Does not implicitly {@link Msg.Group.verify|verify} messages.
+         * @param message Group message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.IGroup, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a Group message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns Group
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.Group;
+
+        /**
+         * Decodes a Group message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns Group
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.Group;
+
+        /**
+         * Gets the default type url for Group
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a ContentHead. */
+    interface IContentHead {
+
+        /** ContentHead msgType */
+        msgType?: (number|Long|null);
+
+        /** ContentHead subType */
+        subType?: (number|Long|null);
+
+        /** ContentHead c2cCmd */
+        c2cCmd?: (number|null);
+
+        /** ContentHead random */
+        random?: (number|Long|null);
+
+        /** ContentHead msgSeq */
+        msgSeq?: (number|Long|null);
+
+        /** ContentHead msgTime */
+        msgTime?: (number|Long|null);
+
+        /** ContentHead pkgNum */
+        pkgNum?: (number|null);
+
+        /** ContentHead pkgIndex */
+        pkgIndex?: (number|null);
+
+        /** ContentHead divSeq */
+        divSeq?: (number|null);
+
+        /** ContentHead autoReply */
+        autoReply?: (number|null);
+
+        /** ContentHead ntMsgSeq */
+        ntMsgSeq?: (number|Long|null);
+
+        /** ContentHead msgUid */
+        msgUid?: (number|Long|null);
+
+        /** ContentHead field15 */
+        field15?: (Msg.IContentHeadField15|null);
+    }
+
+    /** Represents a ContentHead. */
+    class ContentHead implements IContentHead {
+
+        /**
+         * Constructs a new ContentHead.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.IContentHead);
+
+        /** ContentHead msgType. */
+        public msgType?: (number|Long|null);
+
+        /** ContentHead subType. */
+        public subType?: (number|Long|null);
+
+        /** ContentHead c2cCmd. */
+        public c2cCmd?: (number|null);
+
+        /** ContentHead random. */
+        public random?: (number|Long|null);
+
+        /** ContentHead msgSeq. */
+        public msgSeq?: (number|Long|null);
+
+        /** ContentHead msgTime. */
+        public msgTime?: (number|Long|null);
+
+        /** ContentHead pkgNum. */
+        public pkgNum?: (number|null);
+
+        /** ContentHead pkgIndex. */
+        public pkgIndex?: (number|null);
+
+        /** ContentHead divSeq. */
+        public divSeq?: (number|null);
+
+        /** ContentHead autoReply. */
+        public autoReply?: (number|null);
+
+        /** ContentHead ntMsgSeq. */
+        public ntMsgSeq?: (number|Long|null);
+
+        /** ContentHead msgUid. */
+        public msgUid?: (number|Long|null);
+
+        /** ContentHead field15. */
+        public field15?: (Msg.IContentHeadField15|null);
+
+        /**
+         * Encodes the specified ContentHead message. Does not implicitly {@link Msg.ContentHead.verify|verify} messages.
+         * @param message ContentHead message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.IContentHead, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified ContentHead message, length delimited. Does not implicitly {@link Msg.ContentHead.verify|verify} messages.
+         * @param message ContentHead message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.IContentHead, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a ContentHead message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns ContentHead
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.ContentHead;
+
+        /**
+         * Decodes a ContentHead message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns ContentHead
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.ContentHead;
+
+        /**
+         * Gets the default type url for ContentHead
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a ContentHeadField15. */
+    interface IContentHeadField15 {
+
+        /** ContentHeadField15 field1 */
+        field1?: (number|null);
+
+        /** ContentHeadField15 field2 */
+        field2?: (number|null);
+
+        /** ContentHeadField15 field3 */
+        field3?: (number|null);
+
+        /** ContentHeadField15 field4 */
+        field4?: (string|null);
+
+        /** ContentHeadField15 field5 */
+        field5?: (string|null);
+    }
+
+    /** Represents a ContentHeadField15. */
+    class ContentHeadField15 implements IContentHeadField15 {
+
+        /**
+         * Constructs a new ContentHeadField15.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.IContentHeadField15);
+
+        /** ContentHeadField15 field1. */
+        public field1?: (number|null);
+
+        /** ContentHeadField15 field2. */
+        public field2?: (number|null);
+
+        /** ContentHeadField15 field3. */
+        public field3?: (number|null);
+
+        /** ContentHeadField15 field4. */
+        public field4?: (string|null);
+
+        /** ContentHeadField15 field5. */
+        public field5?: (string|null);
+
+        /**
+         * Encodes the specified ContentHeadField15 message. Does not implicitly {@link Msg.ContentHeadField15.verify|verify} messages.
+         * @param message ContentHeadField15 message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.IContentHeadField15, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified ContentHeadField15 message, length delimited. Does not implicitly {@link Msg.ContentHeadField15.verify|verify} messages.
+         * @param message ContentHeadField15 message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.IContentHeadField15, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a ContentHeadField15 message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns ContentHeadField15
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.ContentHeadField15;
+
+        /**
+         * Decodes a ContentHeadField15 message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns ContentHeadField15
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.ContentHeadField15;
+
+        /**
+         * Gets the default type url for ContentHeadField15
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a Message. */
+    interface IMessage {
+
+        /** Message routingHead */
+        routingHead?: (Msg.IRoutingHead|null);
+
+        /** Message contentHead */
+        contentHead?: (Msg.IContentHead|null);
+
+        /** Message body */
+        body?: (Msg.IMessageBody|null);
+    }
+
+    /** Represents a Message. */
+    class Message implements IMessage {
+
+        /**
+         * Constructs a new Message.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.IMessage);
+
+        /** Message routingHead. */
+        public routingHead?: (Msg.IRoutingHead|null);
+
+        /** Message contentHead. */
+        public contentHead?: (Msg.IContentHead|null);
+
+        /** Message body. */
+        public body?: (Msg.IMessageBody|null);
+
+        /**
+         * Encodes the specified Message message. Does not implicitly {@link Msg.Message.verify|verify} messages.
+         * @param message Message message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.IMessage, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified Message message, length delimited. Does not implicitly {@link Msg.Message.verify|verify} messages.
+         * @param message Message message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.IMessage, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a Message message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns Message
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.Message;
+
+        /**
+         * Decodes a Message message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns Message
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.Message;
+
+        /**
+         * Gets the default type url for Message
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a MessageBody. */
+    interface IMessageBody {
+
+        /** MessageBody richText */
+        richText?: (Msg.IRichText|null);
+
+        /** MessageBody msgContent */
+        msgContent?: (Uint8Array|null);
+
+        /** MessageBody msgEncryptContent */
+        msgEncryptContent?: (Uint8Array|null);
+    }
+
+    /** Represents a MessageBody. */
+    class MessageBody implements IMessageBody {
+
+        /**
+         * Constructs a new MessageBody.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.IMessageBody);
+
+        /** MessageBody richText. */
+        public richText?: (Msg.IRichText|null);
+
+        /** MessageBody msgContent. */
+        public msgContent?: (Uint8Array|null);
+
+        /** MessageBody msgEncryptContent. */
+        public msgEncryptContent?: (Uint8Array|null);
+
+        /**
+         * Encodes the specified MessageBody message. Does not implicitly {@link Msg.MessageBody.verify|verify} messages.
+         * @param message MessageBody message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.IMessageBody, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified MessageBody message, length delimited. Does not implicitly {@link Msg.MessageBody.verify|verify} messages.
+         * @param message MessageBody message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.IMessageBody, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a MessageBody message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns MessageBody
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.MessageBody;
+
+        /**
+         * Decodes a MessageBody message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns MessageBody
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.MessageBody;
+
+        /**
+         * Gets the default type url for MessageBody
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a RichText. */
+    interface IRichText {
+
+        /** RichText attr */
+        attr?: (Msg.IAttr|null);
+
+        /** RichText elems */
+        elems?: (Msg.IElem[]|null);
+    }
+
+    /** Represents a RichText. */
+    class RichText implements IRichText {
+
+        /**
+         * Constructs a new RichText.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.IRichText);
+
+        /** RichText attr. */
+        public attr?: (Msg.IAttr|null);
+
+        /** RichText elems. */
+        public elems: Msg.IElem[];
+
+        /**
+         * Encodes the specified RichText message. Does not implicitly {@link Msg.RichText.verify|verify} messages.
+         * @param message RichText message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.IRichText, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified RichText message, length delimited. Does not implicitly {@link Msg.RichText.verify|verify} messages.
+         * @param message RichText message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.IRichText, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a RichText message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns RichText
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.RichText;
+
+        /**
+         * Decodes a RichText message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns RichText
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.RichText;
+
+        /**
+         * Gets the default type url for RichText
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of an Elem. */
+    interface IElem {
+
+        /** Elem text */
+        text?: (Msg.IText|null);
+
+        /** Elem face */
+        face?: (Msg.IFace|null);
+
+        /** Elem lightApp */
+        lightApp?: (Msg.ILightAppElem|null);
+
+        /** Elem commonElem */
+        commonElem?: (Msg.ICommonElem|null);
+    }
+
+    /** Represents an Elem. */
+    class Elem implements IElem {
+
+        /**
+         * Constructs a new Elem.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.IElem);
+
+        /** Elem text. */
+        public text?: (Msg.IText|null);
+
+        /** Elem face. */
+        public face?: (Msg.IFace|null);
+
+        /** Elem lightApp. */
+        public lightApp?: (Msg.ILightAppElem|null);
+
+        /** Elem commonElem. */
+        public commonElem?: (Msg.ICommonElem|null);
+
+        /**
+         * Encodes the specified Elem message. Does not implicitly {@link Msg.Elem.verify|verify} messages.
+         * @param message Elem message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.IElem, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified Elem message, length delimited. Does not implicitly {@link Msg.Elem.verify|verify} messages.
+         * @param message Elem message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.IElem, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes an Elem message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns Elem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.Elem;
+
+        /**
+         * Decodes an Elem message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns Elem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.Elem;
+
+        /**
+         * Gets the default type url for Elem
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a Text. */
+    interface IText {
+
+        /** Text str */
+        str?: (string|null);
+
+        /** Text link */
+        link?: (string|null);
+
+        /** Text attr6Buf */
+        attr6Buf?: (Uint8Array|null);
+
+        /** Text attr7Buf */
+        attr7Buf?: (Uint8Array|null);
+
+        /** Text buf */
+        buf?: (Uint8Array|null);
+
+        /** Text pbReserve */
+        pbReserve?: (Uint8Array|null);
+    }
+
+    /** Represents a Text. */
+    class Text implements IText {
+
+        /**
+         * Constructs a new Text.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.IText);
+
+        /** Text str. */
+        public str?: (string|null);
+
+        /** Text link. */
+        public link?: (string|null);
+
+        /** Text attr6Buf. */
+        public attr6Buf?: (Uint8Array|null);
+
+        /** Text attr7Buf. */
+        public attr7Buf?: (Uint8Array|null);
+
+        /** Text buf. */
+        public buf?: (Uint8Array|null);
+
+        /** Text pbReserve. */
+        public pbReserve?: (Uint8Array|null);
+
+        /**
+         * Encodes the specified Text message. Does not implicitly {@link Msg.Text.verify|verify} messages.
+         * @param message Text message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.IText, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified Text message, length delimited. Does not implicitly {@link Msg.Text.verify|verify} messages.
+         * @param message Text message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.IText, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a Text message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns Text
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.Text;
+
+        /**
+         * Decodes a Text message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns Text
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.Text;
+
+        /**
+         * Gets the default type url for Text
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a Face. */
+    interface IFace {
+
+        /** Face index */
+        index?: (number|null);
+
+        /** Face old */
+        old?: (Uint8Array|null);
+
+        /** Face buf */
+        buf?: (Uint8Array|null);
+    }
+
+    /** Represents a Face. */
+    class Face implements IFace {
+
+        /**
+         * Constructs a new Face.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.IFace);
+
+        /** Face index. */
+        public index?: (number|null);
+
+        /** Face old. */
+        public old?: (Uint8Array|null);
+
+        /** Face buf. */
+        public buf?: (Uint8Array|null);
+
+        /**
+         * Encodes the specified Face message. Does not implicitly {@link Msg.Face.verify|verify} messages.
+         * @param message Face message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.IFace, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified Face message, length delimited. Does not implicitly {@link Msg.Face.verify|verify} messages.
+         * @param message Face message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.IFace, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a Face message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns Face
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.Face;
+
+        /**
+         * Decodes a Face message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns Face
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.Face;
+
+        /**
+         * Gets the default type url for Face
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a LightAppElem. */
+    interface ILightAppElem {
+
+        /** LightAppElem data */
+        data?: (Uint8Array|null);
+
+        /** LightAppElem msgResid */
+        msgResid?: (Uint8Array|null);
+    }
+
+    /** Represents a LightAppElem. */
+    class LightAppElem implements ILightAppElem {
+
+        /**
+         * Constructs a new LightAppElem.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.ILightAppElem);
+
+        /** LightAppElem data. */
+        public data?: (Uint8Array|null);
+
+        /** LightAppElem msgResid. */
+        public msgResid?: (Uint8Array|null);
+
+        /**
+         * Encodes the specified LightAppElem message. Does not implicitly {@link Msg.LightAppElem.verify|verify} messages.
+         * @param message LightAppElem message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.ILightAppElem, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified LightAppElem message, length delimited. Does not implicitly {@link Msg.LightAppElem.verify|verify} messages.
+         * @param message LightAppElem message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.ILightAppElem, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a LightAppElem message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns LightAppElem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.LightAppElem;
+
+        /**
+         * Decodes a LightAppElem message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns LightAppElem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.LightAppElem;
+
+        /**
+         * Gets the default type url for LightAppElem
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a CommonElem. */
+    interface ICommonElem {
+
+        /** CommonElem serviceType */
+        serviceType: number;
+
+        /** CommonElem pbElem */
+        pbElem?: (Uint8Array|null);
+
+        /** CommonElem businessType */
+        businessType?: (number|null);
+    }
+
+    /** Represents a CommonElem. */
+    class CommonElem implements ICommonElem {
+
+        /**
+         * Constructs a new CommonElem.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.ICommonElem);
+
+        /** CommonElem serviceType. */
+        public serviceType: number;
+
+        /** CommonElem pbElem. */
+        public pbElem?: (Uint8Array|null);
+
+        /** CommonElem businessType. */
+        public businessType?: (number|null);
+
+        /**
+         * Encodes the specified CommonElem message. Does not implicitly {@link Msg.CommonElem.verify|verify} messages.
+         * @param message CommonElem message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.ICommonElem, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified CommonElem message, length delimited. Does not implicitly {@link Msg.CommonElem.verify|verify} messages.
+         * @param message CommonElem message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.ICommonElem, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a CommonElem message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns CommonElem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.CommonElem;
+
+        /**
+         * Decodes a CommonElem message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns CommonElem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.CommonElem;
+
+        /**
+         * Gets the default type url for CommonElem
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of an Attr. */
+    interface IAttr {
+
+        /** Attr codePage */
+        codePage?: (number|null);
+
+        /** Attr time */
+        time?: (number|null);
+
+        /** Attr random */
+        random?: (number|null);
+
+        /** Attr color */
+        color?: (number|null);
+
+        /** Attr size */
+        size?: (number|null);
+
+        /** Attr effect */
+        effect?: (number|null);
+
+        /** Attr charSet */
+        charSet?: (number|null);
+
+        /** Attr pitchAndFamily */
+        pitchAndFamily?: (number|null);
+
+        /** Attr fontName */
+        fontName?: (string|null);
+
+        /** Attr reserveData */
+        reserveData?: (Uint8Array|null);
+    }
+
+    /** Represents an Attr. */
+    class Attr implements IAttr {
+
+        /**
+         * Constructs a new Attr.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.IAttr);
+
+        /** Attr codePage. */
+        public codePage?: (number|null);
+
+        /** Attr time. */
+        public time?: (number|null);
+
+        /** Attr random. */
+        public random?: (number|null);
+
+        /** Attr color. */
+        public color?: (number|null);
+
+        /** Attr size. */
+        public size?: (number|null);
+
+        /** Attr effect. */
+        public effect?: (number|null);
+
+        /** Attr charSet. */
+        public charSet?: (number|null);
+
+        /** Attr pitchAndFamily. */
+        public pitchAndFamily?: (number|null);
+
+        /** Attr fontName. */
+        public fontName?: (string|null);
+
+        /** Attr reserveData. */
+        public reserveData?: (Uint8Array|null);
+
+        /**
+         * Encodes the specified Attr message. Does not implicitly {@link Msg.Attr.verify|verify} messages.
+         * @param message Attr message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.IAttr, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified Attr message, length delimited. Does not implicitly {@link Msg.Attr.verify|verify} messages.
+         * @param message Attr message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.IAttr, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes an Attr message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns Attr
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.Attr;
+
+        /**
+         * Decodes an Attr message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns Attr
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.Attr;
+
+        /**
+         * Gets the default type url for Attr
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a MarkdownElem. */
+    interface IMarkdownElem {
+
+        /** MarkdownElem content */
+        content?: (string|null);
+    }
+
+    /** Represents a MarkdownElem. */
+    class MarkdownElem implements IMarkdownElem {
+
+        /**
+         * Constructs a new MarkdownElem.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.IMarkdownElem);
+
+        /** MarkdownElem content. */
+        public content: string;
+
+        /**
+         * Encodes the specified MarkdownElem message. Does not implicitly {@link Msg.MarkdownElem.verify|verify} messages.
+         * @param message MarkdownElem message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.IMarkdownElem, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified MarkdownElem message, length delimited. Does not implicitly {@link Msg.MarkdownElem.verify|verify} messages.
+         * @param message MarkdownElem message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.IMarkdownElem, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a MarkdownElem message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns MarkdownElem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.MarkdownElem;
+
+        /**
+         * Decodes a MarkdownElem message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns MarkdownElem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.MarkdownElem;
+
+        /**
+         * Gets the default type url for MarkdownElem
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a PbMultiMsgItem. */
+    interface IPbMultiMsgItem {
+
+        /** PbMultiMsgItem fileName */
+        fileName?: (string|null);
+
+        /** PbMultiMsgItem buffer */
+        buffer?: (Msg.IPbMultiMsgNew|null);
+    }
+
+    /** Represents a PbMultiMsgItem. */
+    class PbMultiMsgItem implements IPbMultiMsgItem {
+
+        /**
+         * Constructs a new PbMultiMsgItem.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.IPbMultiMsgItem);
+
+        /** PbMultiMsgItem fileName. */
+        public fileName: string;
+
+        /** PbMultiMsgItem buffer. */
+        public buffer?: (Msg.IPbMultiMsgNew|null);
+
+        /**
+         * Encodes the specified PbMultiMsgItem message. Does not implicitly {@link Msg.PbMultiMsgItem.verify|verify} messages.
+         * @param message PbMultiMsgItem message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.IPbMultiMsgItem, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified PbMultiMsgItem message, length delimited. Does not implicitly {@link Msg.PbMultiMsgItem.verify|verify} messages.
+         * @param message PbMultiMsgItem message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.IPbMultiMsgItem, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a PbMultiMsgItem message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns PbMultiMsgItem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.PbMultiMsgItem;
+
+        /**
+         * Decodes a PbMultiMsgItem message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns PbMultiMsgItem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.PbMultiMsgItem;
+
+        /**
+         * Gets the default type url for PbMultiMsgItem
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a PbMultiMsgNew. */
+    interface IPbMultiMsgNew {
+
+        /** PbMultiMsgNew msg */
+        msg?: (Msg.IMessage[]|null);
+    }
+
+    /** Represents a PbMultiMsgNew. */
+    class PbMultiMsgNew implements IPbMultiMsgNew {
+
+        /**
+         * Constructs a new PbMultiMsgNew.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.IPbMultiMsgNew);
+
+        /** PbMultiMsgNew msg. */
+        public msg: Msg.IMessage[];
+
+        /**
+         * Encodes the specified PbMultiMsgNew message. Does not implicitly {@link Msg.PbMultiMsgNew.verify|verify} messages.
+         * @param message PbMultiMsgNew message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.IPbMultiMsgNew, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified PbMultiMsgNew message, length delimited. Does not implicitly {@link Msg.PbMultiMsgNew.verify|verify} messages.
+         * @param message PbMultiMsgNew message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.IPbMultiMsgNew, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a PbMultiMsgNew message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns PbMultiMsgNew
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.PbMultiMsgNew;
+
+        /**
+         * Decodes a PbMultiMsgNew message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns PbMultiMsgNew
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.PbMultiMsgNew;
+
+        /**
+         * Gets the default type url for PbMultiMsgNew
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a PbMultiMsgTransmit. */
+    interface IPbMultiMsgTransmit {
+
+        /** PbMultiMsgTransmit msg */
+        msg?: (Msg.IMessage[]|null);
+
+        /** PbMultiMsgTransmit pbItemList */
+        pbItemList?: (Msg.IPbMultiMsgItem[]|null);
+    }
+
+    /** Represents a PbMultiMsgTransmit. */
+    class PbMultiMsgTransmit implements IPbMultiMsgTransmit {
+
+        /**
+         * Constructs a new PbMultiMsgTransmit.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: Msg.IPbMultiMsgTransmit);
+
+        /** PbMultiMsgTransmit msg. */
+        public msg: Msg.IMessage[];
+
+        /** PbMultiMsgTransmit pbItemList. */
+        public pbItemList: Msg.IPbMultiMsgItem[];
+
+        /**
+         * Encodes the specified PbMultiMsgTransmit message. Does not implicitly {@link Msg.PbMultiMsgTransmit.verify|verify} messages.
+         * @param message PbMultiMsgTransmit message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: Msg.IPbMultiMsgTransmit, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified PbMultiMsgTransmit message, length delimited. Does not implicitly {@link Msg.PbMultiMsgTransmit.verify|verify} messages.
+         * @param message PbMultiMsgTransmit message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: Msg.IPbMultiMsgTransmit, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a PbMultiMsgTransmit message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns PbMultiMsgTransmit
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Msg.PbMultiMsgTransmit;
+
+        /**
+         * Decodes a PbMultiMsgTransmit message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns PbMultiMsgTransmit
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Msg.PbMultiMsgTransmit;
+
+        /**
+         * Gets the default type url for PbMultiMsgTransmit
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+}
+
+/** Namespace RichMedia. */
+export namespace RichMedia {
+
+    /** Properties of a MsgInfo. */
+    interface IMsgInfo {
+
+        /** MsgInfo msgInfoBody */
+        msgInfoBody?: (RichMedia.IMsgInfoBody[]|null);
+
+        /** MsgInfo extBizInfo */
+        extBizInfo?: (RichMedia.IExtBizInfo|null);
+    }
+
+    /** Represents a MsgInfo. */
+    class MsgInfo implements IMsgInfo {
+
+        /**
+         * Constructs a new MsgInfo.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: RichMedia.IMsgInfo);
+
+        /** MsgInfo msgInfoBody. */
+        public msgInfoBody: RichMedia.IMsgInfoBody[];
+
+        /** MsgInfo extBizInfo. */
+        public extBizInfo?: (RichMedia.IExtBizInfo|null);
+
+        /**
+         * Encodes the specified MsgInfo message. Does not implicitly {@link RichMedia.MsgInfo.verify|verify} messages.
+         * @param message MsgInfo message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: RichMedia.IMsgInfo, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified MsgInfo message, length delimited. Does not implicitly {@link RichMedia.MsgInfo.verify|verify} messages.
+         * @param message MsgInfo message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: RichMedia.IMsgInfo, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a MsgInfo message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns MsgInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): RichMedia.MsgInfo;
+
+        /**
+         * Decodes a MsgInfo message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns MsgInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): RichMedia.MsgInfo;
+
+        /**
+         * Gets the default type url for MsgInfo
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a MsgInfoBody. */
+    interface IMsgInfoBody {
+
+        /** MsgInfoBody index */
+        index?: (RichMedia.IIndexNode|null);
+
+        /** MsgInfoBody pic */
+        pic?: (RichMedia.IPicInfo|null);
+
+        /** MsgInfoBody fileExist */
+        fileExist?: (boolean|null);
+    }
+
+    /** Represents a MsgInfoBody. */
+    class MsgInfoBody implements IMsgInfoBody {
+
+        /**
+         * Constructs a new MsgInfoBody.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: RichMedia.IMsgInfoBody);
+
+        /** MsgInfoBody index. */
+        public index?: (RichMedia.IIndexNode|null);
+
+        /** MsgInfoBody pic. */
+        public pic?: (RichMedia.IPicInfo|null);
+
+        /** MsgInfoBody fileExist. */
+        public fileExist: boolean;
+
+        /**
+         * Encodes the specified MsgInfoBody message. Does not implicitly {@link RichMedia.MsgInfoBody.verify|verify} messages.
+         * @param message MsgInfoBody message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: RichMedia.IMsgInfoBody, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified MsgInfoBody message, length delimited. Does not implicitly {@link RichMedia.MsgInfoBody.verify|verify} messages.
+         * @param message MsgInfoBody message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: RichMedia.IMsgInfoBody, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a MsgInfoBody message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns MsgInfoBody
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): RichMedia.MsgInfoBody;
+
+        /**
+         * Decodes a MsgInfoBody message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns MsgInfoBody
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): RichMedia.MsgInfoBody;
+
+        /**
+         * Gets the default type url for MsgInfoBody
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of an IndexNode. */
+    interface IIndexNode {
+
+        /** IndexNode info */
+        info?: (RichMedia.IFileInfo|null);
+
+        /** IndexNode fileUuid */
+        fileUuid?: (string|null);
+
+        /** IndexNode storeID */
+        storeID?: (number|null);
+
+        /** IndexNode uploadTime */
+        uploadTime?: (number|null);
+
+        /** IndexNode expire */
+        expire?: (number|null);
+
+        /** IndexNode type */
+        type?: (number|null);
+    }
+
+    /** Represents an IndexNode. */
+    class IndexNode implements IIndexNode {
+
+        /**
+         * Constructs a new IndexNode.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: RichMedia.IIndexNode);
+
+        /** IndexNode info. */
+        public info?: (RichMedia.IFileInfo|null);
+
+        /** IndexNode fileUuid. */
+        public fileUuid: string;
+
+        /** IndexNode storeID. */
+        public storeID: number;
+
+        /** IndexNode uploadTime. */
+        public uploadTime: number;
+
+        /** IndexNode expire. */
+        public expire: number;
+
+        /** IndexNode type. */
+        public type: number;
+
+        /**
+         * Encodes the specified IndexNode message. Does not implicitly {@link RichMedia.IndexNode.verify|verify} messages.
+         * @param message IndexNode message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: RichMedia.IIndexNode, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified IndexNode message, length delimited. Does not implicitly {@link RichMedia.IndexNode.verify|verify} messages.
+         * @param message IndexNode message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: RichMedia.IIndexNode, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes an IndexNode message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns IndexNode
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): RichMedia.IndexNode;
+
+        /**
+         * Decodes an IndexNode message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns IndexNode
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): RichMedia.IndexNode;
+
+        /**
+         * Gets the default type url for IndexNode
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a FileInfo. */
+    interface IFileInfo {
+
+        /** FileInfo fileSize */
+        fileSize?: (number|null);
+
+        /** FileInfo md5HexStr */
+        md5HexStr?: (string|null);
+
+        /** FileInfo sha1HexStr */
+        sha1HexStr?: (string|null);
+
+        /** FileInfo fileName */
+        fileName?: (string|null);
+
+        /** FileInfo fileType */
+        fileType?: (RichMedia.IFileType|null);
+
+        /** FileInfo width */
+        width?: (number|null);
+
+        /** FileInfo height */
+        height?: (number|null);
+
+        /** FileInfo time */
+        time?: (number|null);
+
+        /** FileInfo original */
+        original?: (number|null);
+    }
+
+    /** Represents a FileInfo. */
+    class FileInfo implements IFileInfo {
+
+        /**
+         * Constructs a new FileInfo.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: RichMedia.IFileInfo);
+
+        /** FileInfo fileSize. */
+        public fileSize: number;
+
+        /** FileInfo md5HexStr. */
+        public md5HexStr: string;
+
+        /** FileInfo sha1HexStr. */
+        public sha1HexStr: string;
+
+        /** FileInfo fileName. */
+        public fileName: string;
+
+        /** FileInfo fileType. */
+        public fileType?: (RichMedia.IFileType|null);
+
+        /** FileInfo width. */
+        public width: number;
+
+        /** FileInfo height. */
+        public height: number;
+
+        /** FileInfo time. */
+        public time: number;
+
+        /** FileInfo original. */
+        public original: number;
+
+        /**
+         * Encodes the specified FileInfo message. Does not implicitly {@link RichMedia.FileInfo.verify|verify} messages.
+         * @param message FileInfo message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: RichMedia.IFileInfo, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified FileInfo message, length delimited. Does not implicitly {@link RichMedia.FileInfo.verify|verify} messages.
+         * @param message FileInfo message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: RichMedia.IFileInfo, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a FileInfo message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns FileInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): RichMedia.FileInfo;
+
+        /**
+         * Decodes a FileInfo message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns FileInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): RichMedia.FileInfo;
+
+        /**
+         * Gets the default type url for FileInfo
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a FileType. */
+    interface IFileType {
+
+        /** FileType type */
+        type?: (number|null);
+
+        /** FileType picFormat */
+        picFormat?: (number|null);
+
+        /** FileType videoFormat */
+        videoFormat?: (number|null);
+
+        /** FileType pttFormat */
+        pttFormat?: (number|null);
+    }
+
+    /** Represents a FileType. */
+    class FileType implements IFileType {
+
+        /**
+         * Constructs a new FileType.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: RichMedia.IFileType);
+
+        /** FileType type. */
+        public type: number;
+
+        /** FileType picFormat. */
+        public picFormat: number;
+
+        /** FileType videoFormat. */
+        public videoFormat: number;
+
+        /** FileType pttFormat. */
+        public pttFormat: number;
+
+        /**
+         * Encodes the specified FileType message. Does not implicitly {@link RichMedia.FileType.verify|verify} messages.
+         * @param message FileType message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: RichMedia.IFileType, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified FileType message, length delimited. Does not implicitly {@link RichMedia.FileType.verify|verify} messages.
+         * @param message FileType message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: RichMedia.IFileType, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a FileType message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns FileType
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): RichMedia.FileType;
+
+        /**
+         * Decodes a FileType message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns FileType
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): RichMedia.FileType;
+
+        /**
+         * Gets the default type url for FileType
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a PicInfo. */
+    interface IPicInfo {
+
+        /** PicInfo urlPath */
+        urlPath?: (string|null);
+
+        /** PicInfo ext */
+        ext?: (RichMedia.IPicUrlExtParams|null);
+
+        /** PicInfo domain */
+        domain?: (string|null);
+    }
+
+    /** Represents a PicInfo. */
+    class PicInfo implements IPicInfo {
+
+        /**
+         * Constructs a new PicInfo.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: RichMedia.IPicInfo);
+
+        /** PicInfo urlPath. */
+        public urlPath: string;
+
+        /** PicInfo ext. */
+        public ext?: (RichMedia.IPicUrlExtParams|null);
+
+        /** PicInfo domain. */
+        public domain: string;
+
+        /**
+         * Encodes the specified PicInfo message. Does not implicitly {@link RichMedia.PicInfo.verify|verify} messages.
+         * @param message PicInfo message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: RichMedia.IPicInfo, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified PicInfo message, length delimited. Does not implicitly {@link RichMedia.PicInfo.verify|verify} messages.
+         * @param message PicInfo message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: RichMedia.IPicInfo, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a PicInfo message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns PicInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): RichMedia.PicInfo;
+
+        /**
+         * Decodes a PicInfo message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns PicInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): RichMedia.PicInfo;
+
+        /**
+         * Gets the default type url for PicInfo
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a PicUrlExtParams. */
+    interface IPicUrlExtParams {
+
+        /** PicUrlExtParams originalParam */
+        originalParam?: (string|null);
+
+        /** PicUrlExtParams bigParam */
+        bigParam?: (string|null);
+
+        /** PicUrlExtParams thumbParam */
+        thumbParam?: (string|null);
+    }
+
+    /** Represents a PicUrlExtParams. */
+    class PicUrlExtParams implements IPicUrlExtParams {
+
+        /**
+         * Constructs a new PicUrlExtParams.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: RichMedia.IPicUrlExtParams);
+
+        /** PicUrlExtParams originalParam. */
+        public originalParam: string;
+
+        /** PicUrlExtParams bigParam. */
+        public bigParam: string;
+
+        /** PicUrlExtParams thumbParam. */
+        public thumbParam: string;
+
+        /**
+         * Encodes the specified PicUrlExtParams message. Does not implicitly {@link RichMedia.PicUrlExtParams.verify|verify} messages.
+         * @param message PicUrlExtParams message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: RichMedia.IPicUrlExtParams, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified PicUrlExtParams message, length delimited. Does not implicitly {@link RichMedia.PicUrlExtParams.verify|verify} messages.
+         * @param message PicUrlExtParams message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: RichMedia.IPicUrlExtParams, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a PicUrlExtParams message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns PicUrlExtParams
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): RichMedia.PicUrlExtParams;
+
+        /**
+         * Decodes a PicUrlExtParams message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns PicUrlExtParams
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): RichMedia.PicUrlExtParams;
+
+        /**
+         * Gets the default type url for PicUrlExtParams
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of an ExtBizInfo. */
+    interface IExtBizInfo {
+
+        /** ExtBizInfo pic */
+        pic?: (RichMedia.IPicExtBizInfo|null);
+
+        /** ExtBizInfo video */
+        video?: (RichMedia.IVideoExtBizInfo|null);
+
+        /** ExtBizInfo busiType */
+        busiType?: (number|null);
+    }
+
+    /** Represents an ExtBizInfo. */
+    class ExtBizInfo implements IExtBizInfo {
+
+        /**
+         * Constructs a new ExtBizInfo.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: RichMedia.IExtBizInfo);
+
+        /** ExtBizInfo pic. */
+        public pic?: (RichMedia.IPicExtBizInfo|null);
+
+        /** ExtBizInfo video. */
+        public video?: (RichMedia.IVideoExtBizInfo|null);
+
+        /** ExtBizInfo busiType. */
+        public busiType: number;
+
+        /**
+         * Encodes the specified ExtBizInfo message. Does not implicitly {@link RichMedia.ExtBizInfo.verify|verify} messages.
+         * @param message ExtBizInfo message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: RichMedia.IExtBizInfo, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified ExtBizInfo message, length delimited. Does not implicitly {@link RichMedia.ExtBizInfo.verify|verify} messages.
+         * @param message ExtBizInfo message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: RichMedia.IExtBizInfo, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes an ExtBizInfo message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns ExtBizInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): RichMedia.ExtBizInfo;
+
+        /**
+         * Decodes an ExtBizInfo message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns ExtBizInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): RichMedia.ExtBizInfo;
+
+        /**
+         * Gets the default type url for ExtBizInfo
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a PicExtBizInfo. */
+    interface IPicExtBizInfo {
+
+        /** PicExtBizInfo bizType */
+        bizType?: (number|null);
+
+        /** PicExtBizInfo summary */
+        summary?: (string|null);
+    }
+
+    /** Represents a PicExtBizInfo. */
+    class PicExtBizInfo implements IPicExtBizInfo {
+
+        /**
+         * Constructs a new PicExtBizInfo.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: RichMedia.IPicExtBizInfo);
+
+        /** PicExtBizInfo bizType. */
+        public bizType: number;
+
+        /** PicExtBizInfo summary. */
+        public summary: string;
+
+        /**
+         * Encodes the specified PicExtBizInfo message. Does not implicitly {@link RichMedia.PicExtBizInfo.verify|verify} messages.
+         * @param message PicExtBizInfo message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: RichMedia.IPicExtBizInfo, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified PicExtBizInfo message, length delimited. Does not implicitly {@link RichMedia.PicExtBizInfo.verify|verify} messages.
+         * @param message PicExtBizInfo message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: RichMedia.IPicExtBizInfo, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a PicExtBizInfo message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns PicExtBizInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): RichMedia.PicExtBizInfo;
+
+        /**
+         * Decodes a PicExtBizInfo message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns PicExtBizInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): RichMedia.PicExtBizInfo;
+
+        /**
+         * Gets the default type url for PicExtBizInfo
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a VideoExtBizInfo. */
+    interface IVideoExtBizInfo {
+
+        /** VideoExtBizInfo pbReserve */
+        pbReserve?: (Uint8Array|null);
+    }
+
+    /** Represents a VideoExtBizInfo. */
+    class VideoExtBizInfo implements IVideoExtBizInfo {
+
+        /**
+         * Constructs a new VideoExtBizInfo.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: RichMedia.IVideoExtBizInfo);
+
+        /** VideoExtBizInfo pbReserve. */
+        public pbReserve: Uint8Array;
+
+        /**
+         * Encodes the specified VideoExtBizInfo message. Does not implicitly {@link RichMedia.VideoExtBizInfo.verify|verify} messages.
+         * @param message VideoExtBizInfo message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: RichMedia.IVideoExtBizInfo, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified VideoExtBizInfo message, length delimited. Does not implicitly {@link RichMedia.VideoExtBizInfo.verify|verify} messages.
+         * @param message VideoExtBizInfo message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: RichMedia.IVideoExtBizInfo, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a VideoExtBizInfo message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns VideoExtBizInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): RichMedia.VideoExtBizInfo;
+
+        /**
+         * Decodes a VideoExtBizInfo message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns VideoExtBizInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): RichMedia.VideoExtBizInfo;
+
+        /**
+         * Gets the default type url for VideoExtBizInfo
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+
+    /** Properties of a PicFileIdInfo. */
+    interface IPicFileIdInfo {
+
+        /** PicFileIdInfo sha1 */
+        sha1?: (Uint8Array|null);
+
+        /** PicFileIdInfo size */
+        size?: (number|null);
+
+        /** PicFileIdInfo appid */
+        appid?: (number|null);
+
+        /** PicFileIdInfo time */
+        time?: (number|null);
+
+        /** PicFileIdInfo expire */
+        expire?: (number|null);
+    }
+
+    /** Represents a PicFileIdInfo. */
+    class PicFileIdInfo implements IPicFileIdInfo {
+
+        /**
+         * Constructs a new PicFileIdInfo.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: RichMedia.IPicFileIdInfo);
+
+        /** PicFileIdInfo sha1. */
+        public sha1: Uint8Array;
+
+        /** PicFileIdInfo size. */
+        public size: number;
+
+        /** PicFileIdInfo appid. */
+        public appid: number;
+
+        /** PicFileIdInfo time. */
+        public time: number;
+
+        /** PicFileIdInfo expire. */
+        public expire: number;
+
+        /**
+         * Encodes the specified PicFileIdInfo message. Does not implicitly {@link RichMedia.PicFileIdInfo.verify|verify} messages.
+         * @param message PicFileIdInfo message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: RichMedia.IPicFileIdInfo, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified PicFileIdInfo message, length delimited. Does not implicitly {@link RichMedia.PicFileIdInfo.verify|verify} messages.
+         * @param message PicFileIdInfo message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: RichMedia.IPicFileIdInfo, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes a PicFileIdInfo message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns PicFileIdInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): RichMedia.PicFileIdInfo;
+
+        /**
+         * Decodes a PicFileIdInfo message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns PicFileIdInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): RichMedia.PicFileIdInfo;
+
+        /**
+         * Gets the default type url for PicFileIdInfo
+         * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns The default type url
+         */
+        public static getTypeUrl(typeUrlPrefix?: string): string;
+    }
+}
diff --git a/src/ntqqapi/proto/compiled.js b/src/ntqqapi/proto/compiled.js
index b7169d8..2b41bc0 100644
--- a/src/ntqqapi/proto/compiled.js
+++ b/src/ntqqapi/proto/compiled.js
@@ -2,7 +2,7 @@
 import * as $protobuf from "protobufjs/minimal";
 
 // Common aliases
-const $Reader = $protobuf.Reader, $util = $protobuf.util;
+const $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
 
 // Exported root namespace
 const $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {});
@@ -16,543 +16,6 @@ export const SysMsg = $root.SysMsg = (() => {
      */
     const SysMsg = {};
 
-    SysMsg.SystemMessage = (function() {
-
-        /**
-         * Properties of a SystemMessage.
-         * @memberof SysMsg
-         * @interface ISystemMessage
-         * @property {Array.<SysMsg.ISystemMessageHeader>|null} [header] SystemMessage header
-         * @property {Array.<SysMsg.ISystemMessageMsgSpec>|null} [msgSpec] SystemMessage msgSpec
-         * @property {SysMsg.ISystemMessageBodyWrapper|null} [bodyWrapper] SystemMessage bodyWrapper
-         */
-
-        /**
-         * Constructs a new SystemMessage.
-         * @memberof SysMsg
-         * @classdesc Represents a SystemMessage.
-         * @implements ISystemMessage
-         * @constructor
-         * @param {SysMsg.ISystemMessage=} [properties] Properties to set
-         */
-        function SystemMessage(properties) {
-            this.header = [];
-            this.msgSpec = [];
-            if (properties)
-                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                    if (properties[keys[i]] != null)
-                        this[keys[i]] = properties[keys[i]];
-        }
-
-        /**
-         * SystemMessage header.
-         * @member {Array.<SysMsg.ISystemMessageHeader>} header
-         * @memberof SysMsg.SystemMessage
-         * @instance
-         */
-        SystemMessage.prototype.header = $util.emptyArray;
-
-        /**
-         * SystemMessage msgSpec.
-         * @member {Array.<SysMsg.ISystemMessageMsgSpec>} msgSpec
-         * @memberof SysMsg.SystemMessage
-         * @instance
-         */
-        SystemMessage.prototype.msgSpec = $util.emptyArray;
-
-        /**
-         * SystemMessage bodyWrapper.
-         * @member {SysMsg.ISystemMessageBodyWrapper|null|undefined} bodyWrapper
-         * @memberof SysMsg.SystemMessage
-         * @instance
-         */
-        SystemMessage.prototype.bodyWrapper = null;
-
-        /**
-         * Decodes a SystemMessage message from the specified reader or buffer.
-         * @function decode
-         * @memberof SysMsg.SystemMessage
-         * @static
-         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-         * @param {number} [length] Message length if known beforehand
-         * @returns {SysMsg.SystemMessage} SystemMessage
-         * @throws {Error} If the payload is not a reader or valid buffer
-         * @throws {$protobuf.util.ProtocolError} If required fields are missing
-         */
-        SystemMessage.decode = function decode(reader, length) {
-            if (!(reader instanceof $Reader))
-                reader = $Reader.create(reader);
-            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.SysMsg.SystemMessage();
-            while (reader.pos < end) {
-                let tag = reader.uint32();
-                switch (tag >>> 3) {
-                case 1: {
-                        if (!(message.header && message.header.length))
-                            message.header = [];
-                        message.header.push($root.SysMsg.SystemMessageHeader.decode(reader, reader.uint32()));
-                        break;
-                    }
-                case 2: {
-                        if (!(message.msgSpec && message.msgSpec.length))
-                            message.msgSpec = [];
-                        message.msgSpec.push($root.SysMsg.SystemMessageMsgSpec.decode(reader, reader.uint32()));
-                        break;
-                    }
-                case 3: {
-                        message.bodyWrapper = $root.SysMsg.SystemMessageBodyWrapper.decode(reader, reader.uint32());
-                        break;
-                    }
-                default:
-                    reader.skipType(tag & 7);
-                    break;
-                }
-            }
-            return message;
-        };
-
-        /**
-         * Decodes a SystemMessage message from the specified reader or buffer, length delimited.
-         * @function decodeDelimited
-         * @memberof SysMsg.SystemMessage
-         * @static
-         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-         * @returns {SysMsg.SystemMessage} SystemMessage
-         * @throws {Error} If the payload is not a reader or valid buffer
-         * @throws {$protobuf.util.ProtocolError} If required fields are missing
-         */
-        SystemMessage.decodeDelimited = function decodeDelimited(reader) {
-            if (!(reader instanceof $Reader))
-                reader = new $Reader(reader);
-            return this.decode(reader, reader.uint32());
-        };
-
-        /**
-         * Gets the default type url for SystemMessage
-         * @function getTypeUrl
-         * @memberof SysMsg.SystemMessage
-         * @static
-         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
-         * @returns {string} The default type url
-         */
-        SystemMessage.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
-            if (typeUrlPrefix === undefined) {
-                typeUrlPrefix = "type.googleapis.com";
-            }
-            return typeUrlPrefix + "/SysMsg.SystemMessage";
-        };
-
-        return SystemMessage;
-    })();
-
-    SysMsg.SystemMessageHeader = (function() {
-
-        /**
-         * Properties of a SystemMessageHeader.
-         * @memberof SysMsg
-         * @interface ISystemMessageHeader
-         * @property {number|null} [peerUin] SystemMessageHeader peerUin
-         * @property {number|null} [uin] SystemMessageHeader uin
-         * @property {string|null} [uid] SystemMessageHeader uid
-         */
-
-        /**
-         * Constructs a new SystemMessageHeader.
-         * @memberof SysMsg
-         * @classdesc Represents a SystemMessageHeader.
-         * @implements ISystemMessageHeader
-         * @constructor
-         * @param {SysMsg.ISystemMessageHeader=} [properties] Properties to set
-         */
-        function SystemMessageHeader(properties) {
-            if (properties)
-                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                    if (properties[keys[i]] != null)
-                        this[keys[i]] = properties[keys[i]];
-        }
-
-        /**
-         * SystemMessageHeader peerUin.
-         * @member {number} peerUin
-         * @memberof SysMsg.SystemMessageHeader
-         * @instance
-         */
-        SystemMessageHeader.prototype.peerUin = 0;
-
-        /**
-         * SystemMessageHeader uin.
-         * @member {number} uin
-         * @memberof SysMsg.SystemMessageHeader
-         * @instance
-         */
-        SystemMessageHeader.prototype.uin = 0;
-
-        /**
-         * SystemMessageHeader uid.
-         * @member {string|null|undefined} uid
-         * @memberof SysMsg.SystemMessageHeader
-         * @instance
-         */
-        SystemMessageHeader.prototype.uid = null;
-
-        // OneOf field names bound to virtual getters and setters
-        let $oneOfFields;
-
-        // Virtual OneOf for proto3 optional field
-        Object.defineProperty(SystemMessageHeader.prototype, "_uid", {
-            get: $util.oneOfGetter($oneOfFields = ["uid"]),
-            set: $util.oneOfSetter($oneOfFields)
-        });
-
-        /**
-         * Decodes a SystemMessageHeader message from the specified reader or buffer.
-         * @function decode
-         * @memberof SysMsg.SystemMessageHeader
-         * @static
-         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-         * @param {number} [length] Message length if known beforehand
-         * @returns {SysMsg.SystemMessageHeader} SystemMessageHeader
-         * @throws {Error} If the payload is not a reader or valid buffer
-         * @throws {$protobuf.util.ProtocolError} If required fields are missing
-         */
-        SystemMessageHeader.decode = function decode(reader, length) {
-            if (!(reader instanceof $Reader))
-                reader = $Reader.create(reader);
-            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.SysMsg.SystemMessageHeader();
-            while (reader.pos < end) {
-                let tag = reader.uint32();
-                switch (tag >>> 3) {
-                case 1: {
-                        message.peerUin = reader.uint32();
-                        break;
-                    }
-                case 5: {
-                        message.uin = reader.uint32();
-                        break;
-                    }
-                case 6: {
-                        message.uid = reader.string();
-                        break;
-                    }
-                default:
-                    reader.skipType(tag & 7);
-                    break;
-                }
-            }
-            return message;
-        };
-
-        /**
-         * Decodes a SystemMessageHeader message from the specified reader or buffer, length delimited.
-         * @function decodeDelimited
-         * @memberof SysMsg.SystemMessageHeader
-         * @static
-         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-         * @returns {SysMsg.SystemMessageHeader} SystemMessageHeader
-         * @throws {Error} If the payload is not a reader or valid buffer
-         * @throws {$protobuf.util.ProtocolError} If required fields are missing
-         */
-        SystemMessageHeader.decodeDelimited = function decodeDelimited(reader) {
-            if (!(reader instanceof $Reader))
-                reader = new $Reader(reader);
-            return this.decode(reader, reader.uint32());
-        };
-
-        /**
-         * Gets the default type url for SystemMessageHeader
-         * @function getTypeUrl
-         * @memberof SysMsg.SystemMessageHeader
-         * @static
-         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
-         * @returns {string} The default type url
-         */
-        SystemMessageHeader.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
-            if (typeUrlPrefix === undefined) {
-                typeUrlPrefix = "type.googleapis.com";
-            }
-            return typeUrlPrefix + "/SysMsg.SystemMessageHeader";
-        };
-
-        return SystemMessageHeader;
-    })();
-
-    SysMsg.SystemMessageMsgSpec = (function() {
-
-        /**
-         * Properties of a SystemMessageMsgSpec.
-         * @memberof SysMsg
-         * @interface ISystemMessageMsgSpec
-         * @property {number|null} [msgType] SystemMessageMsgSpec msgType
-         * @property {number|null} [subType] SystemMessageMsgSpec subType
-         * @property {number|null} [subSubType] SystemMessageMsgSpec subSubType
-         * @property {number|null} [msgSeq] SystemMessageMsgSpec msgSeq
-         * @property {number|null} [time] SystemMessageMsgSpec time
-         * @property {number|null} [other] SystemMessageMsgSpec other
-         */
-
-        /**
-         * Constructs a new SystemMessageMsgSpec.
-         * @memberof SysMsg
-         * @classdesc Represents a SystemMessageMsgSpec.
-         * @implements ISystemMessageMsgSpec
-         * @constructor
-         * @param {SysMsg.ISystemMessageMsgSpec=} [properties] Properties to set
-         */
-        function SystemMessageMsgSpec(properties) {
-            if (properties)
-                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                    if (properties[keys[i]] != null)
-                        this[keys[i]] = properties[keys[i]];
-        }
-
-        /**
-         * SystemMessageMsgSpec msgType.
-         * @member {number} msgType
-         * @memberof SysMsg.SystemMessageMsgSpec
-         * @instance
-         */
-        SystemMessageMsgSpec.prototype.msgType = 0;
-
-        /**
-         * SystemMessageMsgSpec subType.
-         * @member {number|null|undefined} subType
-         * @memberof SysMsg.SystemMessageMsgSpec
-         * @instance
-         */
-        SystemMessageMsgSpec.prototype.subType = null;
-
-        /**
-         * SystemMessageMsgSpec subSubType.
-         * @member {number|null|undefined} subSubType
-         * @memberof SysMsg.SystemMessageMsgSpec
-         * @instance
-         */
-        SystemMessageMsgSpec.prototype.subSubType = null;
-
-        /**
-         * SystemMessageMsgSpec msgSeq.
-         * @member {number} msgSeq
-         * @memberof SysMsg.SystemMessageMsgSpec
-         * @instance
-         */
-        SystemMessageMsgSpec.prototype.msgSeq = 0;
-
-        /**
-         * SystemMessageMsgSpec time.
-         * @member {number} time
-         * @memberof SysMsg.SystemMessageMsgSpec
-         * @instance
-         */
-        SystemMessageMsgSpec.prototype.time = 0;
-
-        /**
-         * SystemMessageMsgSpec other.
-         * @member {number|null|undefined} other
-         * @memberof SysMsg.SystemMessageMsgSpec
-         * @instance
-         */
-        SystemMessageMsgSpec.prototype.other = null;
-
-        // OneOf field names bound to virtual getters and setters
-        let $oneOfFields;
-
-        // Virtual OneOf for proto3 optional field
-        Object.defineProperty(SystemMessageMsgSpec.prototype, "_subType", {
-            get: $util.oneOfGetter($oneOfFields = ["subType"]),
-            set: $util.oneOfSetter($oneOfFields)
-        });
-
-        // Virtual OneOf for proto3 optional field
-        Object.defineProperty(SystemMessageMsgSpec.prototype, "_subSubType", {
-            get: $util.oneOfGetter($oneOfFields = ["subSubType"]),
-            set: $util.oneOfSetter($oneOfFields)
-        });
-
-        // Virtual OneOf for proto3 optional field
-        Object.defineProperty(SystemMessageMsgSpec.prototype, "_other", {
-            get: $util.oneOfGetter($oneOfFields = ["other"]),
-            set: $util.oneOfSetter($oneOfFields)
-        });
-
-        /**
-         * Decodes a SystemMessageMsgSpec message from the specified reader or buffer.
-         * @function decode
-         * @memberof SysMsg.SystemMessageMsgSpec
-         * @static
-         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-         * @param {number} [length] Message length if known beforehand
-         * @returns {SysMsg.SystemMessageMsgSpec} SystemMessageMsgSpec
-         * @throws {Error} If the payload is not a reader or valid buffer
-         * @throws {$protobuf.util.ProtocolError} If required fields are missing
-         */
-        SystemMessageMsgSpec.decode = function decode(reader, length) {
-            if (!(reader instanceof $Reader))
-                reader = $Reader.create(reader);
-            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.SysMsg.SystemMessageMsgSpec();
-            while (reader.pos < end) {
-                let tag = reader.uint32();
-                switch (tag >>> 3) {
-                case 1: {
-                        message.msgType = reader.uint32();
-                        break;
-                    }
-                case 2: {
-                        message.subType = reader.uint32();
-                        break;
-                    }
-                case 3: {
-                        message.subSubType = reader.uint32();
-                        break;
-                    }
-                case 5: {
-                        message.msgSeq = reader.uint32();
-                        break;
-                    }
-                case 6: {
-                        message.time = reader.uint32();
-                        break;
-                    }
-                case 13: {
-                        message.other = reader.uint32();
-                        break;
-                    }
-                default:
-                    reader.skipType(tag & 7);
-                    break;
-                }
-            }
-            return message;
-        };
-
-        /**
-         * Decodes a SystemMessageMsgSpec message from the specified reader or buffer, length delimited.
-         * @function decodeDelimited
-         * @memberof SysMsg.SystemMessageMsgSpec
-         * @static
-         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-         * @returns {SysMsg.SystemMessageMsgSpec} SystemMessageMsgSpec
-         * @throws {Error} If the payload is not a reader or valid buffer
-         * @throws {$protobuf.util.ProtocolError} If required fields are missing
-         */
-        SystemMessageMsgSpec.decodeDelimited = function decodeDelimited(reader) {
-            if (!(reader instanceof $Reader))
-                reader = new $Reader(reader);
-            return this.decode(reader, reader.uint32());
-        };
-
-        /**
-         * Gets the default type url for SystemMessageMsgSpec
-         * @function getTypeUrl
-         * @memberof SysMsg.SystemMessageMsgSpec
-         * @static
-         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
-         * @returns {string} The default type url
-         */
-        SystemMessageMsgSpec.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
-            if (typeUrlPrefix === undefined) {
-                typeUrlPrefix = "type.googleapis.com";
-            }
-            return typeUrlPrefix + "/SysMsg.SystemMessageMsgSpec";
-        };
-
-        return SystemMessageMsgSpec;
-    })();
-
-    SysMsg.SystemMessageBodyWrapper = (function() {
-
-        /**
-         * Properties of a SystemMessageBodyWrapper.
-         * @memberof SysMsg
-         * @interface ISystemMessageBodyWrapper
-         * @property {Uint8Array|null} [body] SystemMessageBodyWrapper body
-         */
-
-        /**
-         * Constructs a new SystemMessageBodyWrapper.
-         * @memberof SysMsg
-         * @classdesc Represents a SystemMessageBodyWrapper.
-         * @implements ISystemMessageBodyWrapper
-         * @constructor
-         * @param {SysMsg.ISystemMessageBodyWrapper=} [properties] Properties to set
-         */
-        function SystemMessageBodyWrapper(properties) {
-            if (properties)
-                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                    if (properties[keys[i]] != null)
-                        this[keys[i]] = properties[keys[i]];
-        }
-
-        /**
-         * SystemMessageBodyWrapper body.
-         * @member {Uint8Array} body
-         * @memberof SysMsg.SystemMessageBodyWrapper
-         * @instance
-         */
-        SystemMessageBodyWrapper.prototype.body = $util.newBuffer([]);
-
-        /**
-         * Decodes a SystemMessageBodyWrapper message from the specified reader or buffer.
-         * @function decode
-         * @memberof SysMsg.SystemMessageBodyWrapper
-         * @static
-         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-         * @param {number} [length] Message length if known beforehand
-         * @returns {SysMsg.SystemMessageBodyWrapper} SystemMessageBodyWrapper
-         * @throws {Error} If the payload is not a reader or valid buffer
-         * @throws {$protobuf.util.ProtocolError} If required fields are missing
-         */
-        SystemMessageBodyWrapper.decode = function decode(reader, length) {
-            if (!(reader instanceof $Reader))
-                reader = $Reader.create(reader);
-            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.SysMsg.SystemMessageBodyWrapper();
-            while (reader.pos < end) {
-                let tag = reader.uint32();
-                switch (tag >>> 3) {
-                case 2: {
-                        message.body = reader.bytes();
-                        break;
-                    }
-                default:
-                    reader.skipType(tag & 7);
-                    break;
-                }
-            }
-            return message;
-        };
-
-        /**
-         * Decodes a SystemMessageBodyWrapper message from the specified reader or buffer, length delimited.
-         * @function decodeDelimited
-         * @memberof SysMsg.SystemMessageBodyWrapper
-         * @static
-         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-         * @returns {SysMsg.SystemMessageBodyWrapper} SystemMessageBodyWrapper
-         * @throws {Error} If the payload is not a reader or valid buffer
-         * @throws {$protobuf.util.ProtocolError} If required fields are missing
-         */
-        SystemMessageBodyWrapper.decodeDelimited = function decodeDelimited(reader) {
-            if (!(reader instanceof $Reader))
-                reader = new $Reader(reader);
-            return this.decode(reader, reader.uint32());
-        };
-
-        /**
-         * Gets the default type url for SystemMessageBodyWrapper
-         * @function getTypeUrl
-         * @memberof SysMsg.SystemMessageBodyWrapper
-         * @static
-         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
-         * @returns {string} The default type url
-         */
-        SystemMessageBodyWrapper.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
-            if (typeUrlPrefix === undefined) {
-                typeUrlPrefix = "type.googleapis.com";
-            }
-            return typeUrlPrefix + "/SysMsg.SystemMessageBodyWrapper";
-        };
-
-        return SystemMessageBodyWrapper;
-    })();
-
     SysMsg.LikeDetail = (function() {
 
         /**
@@ -603,6 +66,40 @@ export const SysMsg = $root.SysMsg = (() => {
          */
         LikeDetail.prototype.nickname = "";
 
+        /**
+         * Encodes the specified LikeDetail message. Does not implicitly {@link SysMsg.LikeDetail.verify|verify} messages.
+         * @function encode
+         * @memberof SysMsg.LikeDetail
+         * @static
+         * @param {SysMsg.ILikeDetail} message LikeDetail message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        LikeDetail.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.txt != null && Object.hasOwnProperty.call(message, "txt"))
+                writer.uint32(/* id 1, wireType 2 =*/10).string(message.txt);
+            if (message.uin != null && Object.hasOwnProperty.call(message, "uin"))
+                writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.uin);
+            if (message.nickname != null && Object.hasOwnProperty.call(message, "nickname"))
+                writer.uint32(/* id 5, wireType 2 =*/42).string(message.nickname);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified LikeDetail message, length delimited. Does not implicitly {@link SysMsg.LikeDetail.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof SysMsg.LikeDetail
+         * @static
+         * @param {SysMsg.ILikeDetail} message LikeDetail message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        LikeDetail.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
         /**
          * Decodes a LikeDetail message from the specified reader or buffer.
          * @function decode
@@ -725,6 +222,40 @@ export const SysMsg = $root.SysMsg = (() => {
          */
         LikeMsg.prototype.detail = null;
 
+        /**
+         * Encodes the specified LikeMsg message. Does not implicitly {@link SysMsg.LikeMsg.verify|verify} messages.
+         * @function encode
+         * @memberof SysMsg.LikeMsg
+         * @static
+         * @param {SysMsg.ILikeMsg} message LikeMsg message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        LikeMsg.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.count != null && Object.hasOwnProperty.call(message, "count"))
+                writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.count);
+            if (message.time != null && Object.hasOwnProperty.call(message, "time"))
+                writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.time);
+            if (message.detail != null && Object.hasOwnProperty.call(message, "detail"))
+                $root.SysMsg.LikeDetail.encode(message.detail, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
+            return writer;
+        };
+
+        /**
+         * Encodes the specified LikeMsg message, length delimited. Does not implicitly {@link SysMsg.LikeMsg.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof SysMsg.LikeMsg
+         * @static
+         * @param {SysMsg.ILikeMsg} message LikeMsg message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        LikeMsg.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
         /**
          * Decodes a LikeMsg message from the specified reader or buffer.
          * @function decode
@@ -829,6 +360,36 @@ export const SysMsg = $root.SysMsg = (() => {
          */
         ProfileLikeSubTip.prototype.msg = null;
 
+        /**
+         * Encodes the specified ProfileLikeSubTip message. Does not implicitly {@link SysMsg.ProfileLikeSubTip.verify|verify} messages.
+         * @function encode
+         * @memberof SysMsg.ProfileLikeSubTip
+         * @static
+         * @param {SysMsg.IProfileLikeSubTip} message ProfileLikeSubTip message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        ProfileLikeSubTip.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.msg != null && Object.hasOwnProperty.call(message, "msg"))
+                $root.SysMsg.LikeMsg.encode(message.msg, writer.uint32(/* id 14, wireType 2 =*/114).fork()).ldelim();
+            return writer;
+        };
+
+        /**
+         * Encodes the specified ProfileLikeSubTip message, length delimited. Does not implicitly {@link SysMsg.ProfileLikeSubTip.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof SysMsg.ProfileLikeSubTip
+         * @static
+         * @param {SysMsg.IProfileLikeSubTip} message ProfileLikeSubTip message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        ProfileLikeSubTip.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
         /**
          * Decodes a ProfileLikeSubTip message from the specified reader or buffer.
          * @function decode
@@ -943,6 +504,40 @@ export const SysMsg = $root.SysMsg = (() => {
          */
         ProfileLikeTip.prototype.content = null;
 
+        /**
+         * Encodes the specified ProfileLikeTip message. Does not implicitly {@link SysMsg.ProfileLikeTip.verify|verify} messages.
+         * @function encode
+         * @memberof SysMsg.ProfileLikeTip
+         * @static
+         * @param {SysMsg.IProfileLikeTip} message ProfileLikeTip message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        ProfileLikeTip.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.msgType != null && Object.hasOwnProperty.call(message, "msgType"))
+                writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.msgType);
+            if (message.subType != null && Object.hasOwnProperty.call(message, "subType"))
+                writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.subType);
+            if (message.content != null && Object.hasOwnProperty.call(message, "content"))
+                $root.SysMsg.ProfileLikeSubTip.encode(message.content, writer.uint32(/* id 203, wireType 2 =*/1626).fork()).ldelim();
+            return writer;
+        };
+
+        /**
+         * Encodes the specified ProfileLikeTip message, length delimited. Does not implicitly {@link SysMsg.ProfileLikeTip.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof SysMsg.ProfileLikeTip
+         * @static
+         * @param {SysMsg.IProfileLikeTip} message ProfileLikeTip message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        ProfileLikeTip.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
         /**
          * Decodes a ProfileLikeTip message from the specified reader or buffer.
          * @function decode
@@ -1074,6 +669,42 @@ export const SysMsg = $root.SysMsg = (() => {
          */
         GroupMemberChange.prototype.adminUid = "";
 
+        /**
+         * Encodes the specified GroupMemberChange message. Does not implicitly {@link SysMsg.GroupMemberChange.verify|verify} messages.
+         * @function encode
+         * @memberof SysMsg.GroupMemberChange
+         * @static
+         * @param {SysMsg.IGroupMemberChange} message GroupMemberChange message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        GroupMemberChange.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.groupCode != null && Object.hasOwnProperty.call(message, "groupCode"))
+                writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.groupCode);
+            if (message.memberUid != null && Object.hasOwnProperty.call(message, "memberUid"))
+                writer.uint32(/* id 3, wireType 2 =*/26).string(message.memberUid);
+            if (message.type != null && Object.hasOwnProperty.call(message, "type"))
+                writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.type);
+            if (message.adminUid != null && Object.hasOwnProperty.call(message, "adminUid"))
+                writer.uint32(/* id 5, wireType 2 =*/42).string(message.adminUid);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified GroupMemberChange message, length delimited. Does not implicitly {@link SysMsg.GroupMemberChange.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof SysMsg.GroupMemberChange
+         * @static
+         * @param {SysMsg.IGroupMemberChange} message GroupMemberChange message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        GroupMemberChange.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
         /**
          * Decodes a GroupMemberChange message from the specified reader or buffer.
          * @function decode
@@ -1153,4 +784,5515 @@ export const SysMsg = $root.SysMsg = (() => {
     return SysMsg;
 })();
 
+export const Msg = $root.Msg = (() => {
+
+    /**
+     * Namespace Msg.
+     * @exports Msg
+     * @namespace
+     */
+    const Msg = {};
+
+    Msg.RoutingHead = (function() {
+
+        /**
+         * Properties of a RoutingHead.
+         * @memberof Msg
+         * @interface IRoutingHead
+         * @property {number|Long|null} [fromUin] RoutingHead fromUin
+         * @property {string|null} [fromUid] RoutingHead fromUid
+         * @property {number|null} [fromAppid] RoutingHead fromAppid
+         * @property {number|null} [fromInstid] RoutingHead fromInstid
+         * @property {number|Long|null} [toUin] RoutingHead toUin
+         * @property {string|null} [toUid] RoutingHead toUid
+         * @property {Msg.IC2c|null} [c2c] RoutingHead c2c
+         * @property {Msg.IGroup|null} [group] RoutingHead group
+         */
+
+        /**
+         * Constructs a new RoutingHead.
+         * @memberof Msg
+         * @classdesc Represents a RoutingHead.
+         * @implements IRoutingHead
+         * @constructor
+         * @param {Msg.IRoutingHead=} [properties] Properties to set
+         */
+        function RoutingHead(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * RoutingHead fromUin.
+         * @member {number|Long|null|undefined} fromUin
+         * @memberof Msg.RoutingHead
+         * @instance
+         */
+        RoutingHead.prototype.fromUin = null;
+
+        /**
+         * RoutingHead fromUid.
+         * @member {string|null|undefined} fromUid
+         * @memberof Msg.RoutingHead
+         * @instance
+         */
+        RoutingHead.prototype.fromUid = null;
+
+        /**
+         * RoutingHead fromAppid.
+         * @member {number|null|undefined} fromAppid
+         * @memberof Msg.RoutingHead
+         * @instance
+         */
+        RoutingHead.prototype.fromAppid = null;
+
+        /**
+         * RoutingHead fromInstid.
+         * @member {number|null|undefined} fromInstid
+         * @memberof Msg.RoutingHead
+         * @instance
+         */
+        RoutingHead.prototype.fromInstid = null;
+
+        /**
+         * RoutingHead toUin.
+         * @member {number|Long|null|undefined} toUin
+         * @memberof Msg.RoutingHead
+         * @instance
+         */
+        RoutingHead.prototype.toUin = null;
+
+        /**
+         * RoutingHead toUid.
+         * @member {string|null|undefined} toUid
+         * @memberof Msg.RoutingHead
+         * @instance
+         */
+        RoutingHead.prototype.toUid = null;
+
+        /**
+         * RoutingHead c2c.
+         * @member {Msg.IC2c|null|undefined} c2c
+         * @memberof Msg.RoutingHead
+         * @instance
+         */
+        RoutingHead.prototype.c2c = null;
+
+        /**
+         * RoutingHead group.
+         * @member {Msg.IGroup|null|undefined} group
+         * @memberof Msg.RoutingHead
+         * @instance
+         */
+        RoutingHead.prototype.group = null;
+
+        // OneOf field names bound to virtual getters and setters
+        let $oneOfFields;
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(RoutingHead.prototype, "_fromUin", {
+            get: $util.oneOfGetter($oneOfFields = ["fromUin"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(RoutingHead.prototype, "_fromUid", {
+            get: $util.oneOfGetter($oneOfFields = ["fromUid"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(RoutingHead.prototype, "_fromAppid", {
+            get: $util.oneOfGetter($oneOfFields = ["fromAppid"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(RoutingHead.prototype, "_fromInstid", {
+            get: $util.oneOfGetter($oneOfFields = ["fromInstid"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(RoutingHead.prototype, "_toUin", {
+            get: $util.oneOfGetter($oneOfFields = ["toUin"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(RoutingHead.prototype, "_toUid", {
+            get: $util.oneOfGetter($oneOfFields = ["toUid"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(RoutingHead.prototype, "_c2c", {
+            get: $util.oneOfGetter($oneOfFields = ["c2c"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(RoutingHead.prototype, "_group", {
+            get: $util.oneOfGetter($oneOfFields = ["group"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        /**
+         * Encodes the specified RoutingHead message. Does not implicitly {@link Msg.RoutingHead.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.RoutingHead
+         * @static
+         * @param {Msg.IRoutingHead} message RoutingHead message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        RoutingHead.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.fromUin != null && Object.hasOwnProperty.call(message, "fromUin"))
+                writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.fromUin);
+            if (message.fromUid != null && Object.hasOwnProperty.call(message, "fromUid"))
+                writer.uint32(/* id 2, wireType 2 =*/18).string(message.fromUid);
+            if (message.fromAppid != null && Object.hasOwnProperty.call(message, "fromAppid"))
+                writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.fromAppid);
+            if (message.fromInstid != null && Object.hasOwnProperty.call(message, "fromInstid"))
+                writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.fromInstid);
+            if (message.toUin != null && Object.hasOwnProperty.call(message, "toUin"))
+                writer.uint32(/* id 5, wireType 0 =*/40).uint64(message.toUin);
+            if (message.toUid != null && Object.hasOwnProperty.call(message, "toUid"))
+                writer.uint32(/* id 6, wireType 2 =*/50).string(message.toUid);
+            if (message.c2c != null && Object.hasOwnProperty.call(message, "c2c"))
+                $root.Msg.C2c.encode(message.c2c, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
+            if (message.group != null && Object.hasOwnProperty.call(message, "group"))
+                $root.Msg.Group.encode(message.group, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
+            return writer;
+        };
+
+        /**
+         * Encodes the specified RoutingHead message, length delimited. Does not implicitly {@link Msg.RoutingHead.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.RoutingHead
+         * @static
+         * @param {Msg.IRoutingHead} message RoutingHead message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        RoutingHead.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a RoutingHead message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.RoutingHead
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.RoutingHead} RoutingHead
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        RoutingHead.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.RoutingHead();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.fromUin = reader.uint64();
+                        break;
+                    }
+                case 2: {
+                        message.fromUid = reader.string();
+                        break;
+                    }
+                case 3: {
+                        message.fromAppid = reader.uint32();
+                        break;
+                    }
+                case 4: {
+                        message.fromInstid = reader.uint32();
+                        break;
+                    }
+                case 5: {
+                        message.toUin = reader.uint64();
+                        break;
+                    }
+                case 6: {
+                        message.toUid = reader.string();
+                        break;
+                    }
+                case 7: {
+                        message.c2c = $root.Msg.C2c.decode(reader, reader.uint32());
+                        break;
+                    }
+                case 8: {
+                        message.group = $root.Msg.Group.decode(reader, reader.uint32());
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a RoutingHead message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.RoutingHead
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.RoutingHead} RoutingHead
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        RoutingHead.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for RoutingHead
+         * @function getTypeUrl
+         * @memberof Msg.RoutingHead
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        RoutingHead.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.RoutingHead";
+        };
+
+        return RoutingHead;
+    })();
+
+    Msg.C2c = (function() {
+
+        /**
+         * Properties of a C2c.
+         * @memberof Msg
+         * @interface IC2c
+         * @property {string|null} [friendName] C2c friendName
+         */
+
+        /**
+         * Constructs a new C2c.
+         * @memberof Msg
+         * @classdesc Represents a C2c.
+         * @implements IC2c
+         * @constructor
+         * @param {Msg.IC2c=} [properties] Properties to set
+         */
+        function C2c(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * C2c friendName.
+         * @member {string|null|undefined} friendName
+         * @memberof Msg.C2c
+         * @instance
+         */
+        C2c.prototype.friendName = null;
+
+        // OneOf field names bound to virtual getters and setters
+        let $oneOfFields;
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(C2c.prototype, "_friendName", {
+            get: $util.oneOfGetter($oneOfFields = ["friendName"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        /**
+         * Encodes the specified C2c message. Does not implicitly {@link Msg.C2c.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.C2c
+         * @static
+         * @param {Msg.IC2c} message C2c message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        C2c.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.friendName != null && Object.hasOwnProperty.call(message, "friendName"))
+                writer.uint32(/* id 6, wireType 2 =*/50).string(message.friendName);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified C2c message, length delimited. Does not implicitly {@link Msg.C2c.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.C2c
+         * @static
+         * @param {Msg.IC2c} message C2c message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        C2c.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a C2c message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.C2c
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.C2c} C2c
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        C2c.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.C2c();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 6: {
+                        message.friendName = reader.string();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a C2c message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.C2c
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.C2c} C2c
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        C2c.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for C2c
+         * @function getTypeUrl
+         * @memberof Msg.C2c
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        C2c.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.C2c";
+        };
+
+        return C2c;
+    })();
+
+    Msg.Group = (function() {
+
+        /**
+         * Properties of a Group.
+         * @memberof Msg
+         * @interface IGroup
+         * @property {number|Long|null} [groupCode] Group groupCode
+         * @property {number|null} [groupType] Group groupType
+         * @property {number|Long|null} [groupInfoSeq] Group groupInfoSeq
+         * @property {string|null} [groupCard] Group groupCard
+         * @property {number|null} [groupCardType] Group groupCardType
+         * @property {number|null} [groupLevel] Group groupLevel
+         * @property {string|null} [groupName] Group groupName
+         * @property {string|null} [extGroupKeyInfo] Group extGroupKeyInfo
+         * @property {number|null} [msgFlag] Group msgFlag
+         */
+
+        /**
+         * Constructs a new Group.
+         * @memberof Msg
+         * @classdesc Represents a Group.
+         * @implements IGroup
+         * @constructor
+         * @param {Msg.IGroup=} [properties] Properties to set
+         */
+        function Group(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * Group groupCode.
+         * @member {number|Long|null|undefined} groupCode
+         * @memberof Msg.Group
+         * @instance
+         */
+        Group.prototype.groupCode = null;
+
+        /**
+         * Group groupType.
+         * @member {number|null|undefined} groupType
+         * @memberof Msg.Group
+         * @instance
+         */
+        Group.prototype.groupType = null;
+
+        /**
+         * Group groupInfoSeq.
+         * @member {number|Long|null|undefined} groupInfoSeq
+         * @memberof Msg.Group
+         * @instance
+         */
+        Group.prototype.groupInfoSeq = null;
+
+        /**
+         * Group groupCard.
+         * @member {string|null|undefined} groupCard
+         * @memberof Msg.Group
+         * @instance
+         */
+        Group.prototype.groupCard = null;
+
+        /**
+         * Group groupCardType.
+         * @member {number|null|undefined} groupCardType
+         * @memberof Msg.Group
+         * @instance
+         */
+        Group.prototype.groupCardType = null;
+
+        /**
+         * Group groupLevel.
+         * @member {number|null|undefined} groupLevel
+         * @memberof Msg.Group
+         * @instance
+         */
+        Group.prototype.groupLevel = null;
+
+        /**
+         * Group groupName.
+         * @member {string|null|undefined} groupName
+         * @memberof Msg.Group
+         * @instance
+         */
+        Group.prototype.groupName = null;
+
+        /**
+         * Group extGroupKeyInfo.
+         * @member {string|null|undefined} extGroupKeyInfo
+         * @memberof Msg.Group
+         * @instance
+         */
+        Group.prototype.extGroupKeyInfo = null;
+
+        /**
+         * Group msgFlag.
+         * @member {number|null|undefined} msgFlag
+         * @memberof Msg.Group
+         * @instance
+         */
+        Group.prototype.msgFlag = null;
+
+        // OneOf field names bound to virtual getters and setters
+        let $oneOfFields;
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Group.prototype, "_groupCode", {
+            get: $util.oneOfGetter($oneOfFields = ["groupCode"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Group.prototype, "_groupType", {
+            get: $util.oneOfGetter($oneOfFields = ["groupType"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Group.prototype, "_groupInfoSeq", {
+            get: $util.oneOfGetter($oneOfFields = ["groupInfoSeq"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Group.prototype, "_groupCard", {
+            get: $util.oneOfGetter($oneOfFields = ["groupCard"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Group.prototype, "_groupCardType", {
+            get: $util.oneOfGetter($oneOfFields = ["groupCardType"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Group.prototype, "_groupLevel", {
+            get: $util.oneOfGetter($oneOfFields = ["groupLevel"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Group.prototype, "_groupName", {
+            get: $util.oneOfGetter($oneOfFields = ["groupName"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Group.prototype, "_extGroupKeyInfo", {
+            get: $util.oneOfGetter($oneOfFields = ["extGroupKeyInfo"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Group.prototype, "_msgFlag", {
+            get: $util.oneOfGetter($oneOfFields = ["msgFlag"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        /**
+         * Encodes the specified Group message. Does not implicitly {@link Msg.Group.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.Group
+         * @static
+         * @param {Msg.IGroup} message Group message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        Group.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.groupCode != null && Object.hasOwnProperty.call(message, "groupCode"))
+                writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.groupCode);
+            if (message.groupType != null && Object.hasOwnProperty.call(message, "groupType"))
+                writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.groupType);
+            if (message.groupInfoSeq != null && Object.hasOwnProperty.call(message, "groupInfoSeq"))
+                writer.uint32(/* id 3, wireType 0 =*/24).uint64(message.groupInfoSeq);
+            if (message.groupCard != null && Object.hasOwnProperty.call(message, "groupCard"))
+                writer.uint32(/* id 4, wireType 2 =*/34).string(message.groupCard);
+            if (message.groupCardType != null && Object.hasOwnProperty.call(message, "groupCardType"))
+                writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.groupCardType);
+            if (message.groupLevel != null && Object.hasOwnProperty.call(message, "groupLevel"))
+                writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.groupLevel);
+            if (message.groupName != null && Object.hasOwnProperty.call(message, "groupName"))
+                writer.uint32(/* id 7, wireType 2 =*/58).string(message.groupName);
+            if (message.extGroupKeyInfo != null && Object.hasOwnProperty.call(message, "extGroupKeyInfo"))
+                writer.uint32(/* id 8, wireType 2 =*/66).string(message.extGroupKeyInfo);
+            if (message.msgFlag != null && Object.hasOwnProperty.call(message, "msgFlag"))
+                writer.uint32(/* id 9, wireType 0 =*/72).uint32(message.msgFlag);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified Group message, length delimited. Does not implicitly {@link Msg.Group.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.Group
+         * @static
+         * @param {Msg.IGroup} message Group message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        Group.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a Group message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.Group
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.Group} Group
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        Group.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.Group();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.groupCode = reader.uint64();
+                        break;
+                    }
+                case 2: {
+                        message.groupType = reader.uint32();
+                        break;
+                    }
+                case 3: {
+                        message.groupInfoSeq = reader.uint64();
+                        break;
+                    }
+                case 4: {
+                        message.groupCard = reader.string();
+                        break;
+                    }
+                case 5: {
+                        message.groupCardType = reader.uint32();
+                        break;
+                    }
+                case 6: {
+                        message.groupLevel = reader.uint32();
+                        break;
+                    }
+                case 7: {
+                        message.groupName = reader.string();
+                        break;
+                    }
+                case 8: {
+                        message.extGroupKeyInfo = reader.string();
+                        break;
+                    }
+                case 9: {
+                        message.msgFlag = reader.uint32();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a Group message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.Group
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.Group} Group
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        Group.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for Group
+         * @function getTypeUrl
+         * @memberof Msg.Group
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        Group.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.Group";
+        };
+
+        return Group;
+    })();
+
+    Msg.ContentHead = (function() {
+
+        /**
+         * Properties of a ContentHead.
+         * @memberof Msg
+         * @interface IContentHead
+         * @property {number|Long|null} [msgType] ContentHead msgType
+         * @property {number|Long|null} [subType] ContentHead subType
+         * @property {number|null} [c2cCmd] ContentHead c2cCmd
+         * @property {number|Long|null} [random] ContentHead random
+         * @property {number|Long|null} [msgSeq] ContentHead msgSeq
+         * @property {number|Long|null} [msgTime] ContentHead msgTime
+         * @property {number|null} [pkgNum] ContentHead pkgNum
+         * @property {number|null} [pkgIndex] ContentHead pkgIndex
+         * @property {number|null} [divSeq] ContentHead divSeq
+         * @property {number|null} [autoReply] ContentHead autoReply
+         * @property {number|Long|null} [ntMsgSeq] ContentHead ntMsgSeq
+         * @property {number|Long|null} [msgUid] ContentHead msgUid
+         * @property {Msg.IContentHeadField15|null} [field15] ContentHead field15
+         */
+
+        /**
+         * Constructs a new ContentHead.
+         * @memberof Msg
+         * @classdesc Represents a ContentHead.
+         * @implements IContentHead
+         * @constructor
+         * @param {Msg.IContentHead=} [properties] Properties to set
+         */
+        function ContentHead(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * ContentHead msgType.
+         * @member {number|Long|null|undefined} msgType
+         * @memberof Msg.ContentHead
+         * @instance
+         */
+        ContentHead.prototype.msgType = null;
+
+        /**
+         * ContentHead subType.
+         * @member {number|Long|null|undefined} subType
+         * @memberof Msg.ContentHead
+         * @instance
+         */
+        ContentHead.prototype.subType = null;
+
+        /**
+         * ContentHead c2cCmd.
+         * @member {number|null|undefined} c2cCmd
+         * @memberof Msg.ContentHead
+         * @instance
+         */
+        ContentHead.prototype.c2cCmd = null;
+
+        /**
+         * ContentHead random.
+         * @member {number|Long|null|undefined} random
+         * @memberof Msg.ContentHead
+         * @instance
+         */
+        ContentHead.prototype.random = null;
+
+        /**
+         * ContentHead msgSeq.
+         * @member {number|Long|null|undefined} msgSeq
+         * @memberof Msg.ContentHead
+         * @instance
+         */
+        ContentHead.prototype.msgSeq = null;
+
+        /**
+         * ContentHead msgTime.
+         * @member {number|Long|null|undefined} msgTime
+         * @memberof Msg.ContentHead
+         * @instance
+         */
+        ContentHead.prototype.msgTime = null;
+
+        /**
+         * ContentHead pkgNum.
+         * @member {number|null|undefined} pkgNum
+         * @memberof Msg.ContentHead
+         * @instance
+         */
+        ContentHead.prototype.pkgNum = null;
+
+        /**
+         * ContentHead pkgIndex.
+         * @member {number|null|undefined} pkgIndex
+         * @memberof Msg.ContentHead
+         * @instance
+         */
+        ContentHead.prototype.pkgIndex = null;
+
+        /**
+         * ContentHead divSeq.
+         * @member {number|null|undefined} divSeq
+         * @memberof Msg.ContentHead
+         * @instance
+         */
+        ContentHead.prototype.divSeq = null;
+
+        /**
+         * ContentHead autoReply.
+         * @member {number|null|undefined} autoReply
+         * @memberof Msg.ContentHead
+         * @instance
+         */
+        ContentHead.prototype.autoReply = null;
+
+        /**
+         * ContentHead ntMsgSeq.
+         * @member {number|Long|null|undefined} ntMsgSeq
+         * @memberof Msg.ContentHead
+         * @instance
+         */
+        ContentHead.prototype.ntMsgSeq = null;
+
+        /**
+         * ContentHead msgUid.
+         * @member {number|Long|null|undefined} msgUid
+         * @memberof Msg.ContentHead
+         * @instance
+         */
+        ContentHead.prototype.msgUid = null;
+
+        /**
+         * ContentHead field15.
+         * @member {Msg.IContentHeadField15|null|undefined} field15
+         * @memberof Msg.ContentHead
+         * @instance
+         */
+        ContentHead.prototype.field15 = null;
+
+        // OneOf field names bound to virtual getters and setters
+        let $oneOfFields;
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHead.prototype, "_msgType", {
+            get: $util.oneOfGetter($oneOfFields = ["msgType"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHead.prototype, "_subType", {
+            get: $util.oneOfGetter($oneOfFields = ["subType"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHead.prototype, "_c2cCmd", {
+            get: $util.oneOfGetter($oneOfFields = ["c2cCmd"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHead.prototype, "_random", {
+            get: $util.oneOfGetter($oneOfFields = ["random"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHead.prototype, "_msgSeq", {
+            get: $util.oneOfGetter($oneOfFields = ["msgSeq"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHead.prototype, "_msgTime", {
+            get: $util.oneOfGetter($oneOfFields = ["msgTime"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHead.prototype, "_pkgNum", {
+            get: $util.oneOfGetter($oneOfFields = ["pkgNum"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHead.prototype, "_pkgIndex", {
+            get: $util.oneOfGetter($oneOfFields = ["pkgIndex"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHead.prototype, "_divSeq", {
+            get: $util.oneOfGetter($oneOfFields = ["divSeq"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHead.prototype, "_autoReply", {
+            get: $util.oneOfGetter($oneOfFields = ["autoReply"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHead.prototype, "_ntMsgSeq", {
+            get: $util.oneOfGetter($oneOfFields = ["ntMsgSeq"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHead.prototype, "_msgUid", {
+            get: $util.oneOfGetter($oneOfFields = ["msgUid"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHead.prototype, "_field15", {
+            get: $util.oneOfGetter($oneOfFields = ["field15"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        /**
+         * Encodes the specified ContentHead message. Does not implicitly {@link Msg.ContentHead.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.ContentHead
+         * @static
+         * @param {Msg.IContentHead} message ContentHead message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        ContentHead.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.msgType != null && Object.hasOwnProperty.call(message, "msgType"))
+                writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.msgType);
+            if (message.subType != null && Object.hasOwnProperty.call(message, "subType"))
+                writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.subType);
+            if (message.c2cCmd != null && Object.hasOwnProperty.call(message, "c2cCmd"))
+                writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.c2cCmd);
+            if (message.random != null && Object.hasOwnProperty.call(message, "random"))
+                writer.uint32(/* id 4, wireType 0 =*/32).uint64(message.random);
+            if (message.msgSeq != null && Object.hasOwnProperty.call(message, "msgSeq"))
+                writer.uint32(/* id 5, wireType 0 =*/40).uint64(message.msgSeq);
+            if (message.msgTime != null && Object.hasOwnProperty.call(message, "msgTime"))
+                writer.uint32(/* id 6, wireType 0 =*/48).uint64(message.msgTime);
+            if (message.pkgNum != null && Object.hasOwnProperty.call(message, "pkgNum"))
+                writer.uint32(/* id 7, wireType 0 =*/56).uint32(message.pkgNum);
+            if (message.pkgIndex != null && Object.hasOwnProperty.call(message, "pkgIndex"))
+                writer.uint32(/* id 8, wireType 0 =*/64).uint32(message.pkgIndex);
+            if (message.divSeq != null && Object.hasOwnProperty.call(message, "divSeq"))
+                writer.uint32(/* id 9, wireType 0 =*/72).uint32(message.divSeq);
+            if (message.autoReply != null && Object.hasOwnProperty.call(message, "autoReply"))
+                writer.uint32(/* id 10, wireType 0 =*/80).uint32(message.autoReply);
+            if (message.ntMsgSeq != null && Object.hasOwnProperty.call(message, "ntMsgSeq"))
+                writer.uint32(/* id 11, wireType 0 =*/88).uint64(message.ntMsgSeq);
+            if (message.msgUid != null && Object.hasOwnProperty.call(message, "msgUid"))
+                writer.uint32(/* id 12, wireType 0 =*/96).uint64(message.msgUid);
+            if (message.field15 != null && Object.hasOwnProperty.call(message, "field15"))
+                $root.Msg.ContentHeadField15.encode(message.field15, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim();
+            return writer;
+        };
+
+        /**
+         * Encodes the specified ContentHead message, length delimited. Does not implicitly {@link Msg.ContentHead.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.ContentHead
+         * @static
+         * @param {Msg.IContentHead} message ContentHead message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        ContentHead.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a ContentHead message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.ContentHead
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.ContentHead} ContentHead
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        ContentHead.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.ContentHead();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.msgType = reader.uint64();
+                        break;
+                    }
+                case 2: {
+                        message.subType = reader.uint64();
+                        break;
+                    }
+                case 3: {
+                        message.c2cCmd = reader.uint32();
+                        break;
+                    }
+                case 4: {
+                        message.random = reader.uint64();
+                        break;
+                    }
+                case 5: {
+                        message.msgSeq = reader.uint64();
+                        break;
+                    }
+                case 6: {
+                        message.msgTime = reader.uint64();
+                        break;
+                    }
+                case 7: {
+                        message.pkgNum = reader.uint32();
+                        break;
+                    }
+                case 8: {
+                        message.pkgIndex = reader.uint32();
+                        break;
+                    }
+                case 9: {
+                        message.divSeq = reader.uint32();
+                        break;
+                    }
+                case 10: {
+                        message.autoReply = reader.uint32();
+                        break;
+                    }
+                case 11: {
+                        message.ntMsgSeq = reader.uint64();
+                        break;
+                    }
+                case 12: {
+                        message.msgUid = reader.uint64();
+                        break;
+                    }
+                case 15: {
+                        message.field15 = $root.Msg.ContentHeadField15.decode(reader, reader.uint32());
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a ContentHead message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.ContentHead
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.ContentHead} ContentHead
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        ContentHead.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for ContentHead
+         * @function getTypeUrl
+         * @memberof Msg.ContentHead
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        ContentHead.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.ContentHead";
+        };
+
+        return ContentHead;
+    })();
+
+    Msg.ContentHeadField15 = (function() {
+
+        /**
+         * Properties of a ContentHeadField15.
+         * @memberof Msg
+         * @interface IContentHeadField15
+         * @property {number|null} [field1] ContentHeadField15 field1
+         * @property {number|null} [field2] ContentHeadField15 field2
+         * @property {number|null} [field3] ContentHeadField15 field3
+         * @property {string|null} [field4] ContentHeadField15 field4
+         * @property {string|null} [field5] ContentHeadField15 field5
+         */
+
+        /**
+         * Constructs a new ContentHeadField15.
+         * @memberof Msg
+         * @classdesc Represents a ContentHeadField15.
+         * @implements IContentHeadField15
+         * @constructor
+         * @param {Msg.IContentHeadField15=} [properties] Properties to set
+         */
+        function ContentHeadField15(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * ContentHeadField15 field1.
+         * @member {number|null|undefined} field1
+         * @memberof Msg.ContentHeadField15
+         * @instance
+         */
+        ContentHeadField15.prototype.field1 = null;
+
+        /**
+         * ContentHeadField15 field2.
+         * @member {number|null|undefined} field2
+         * @memberof Msg.ContentHeadField15
+         * @instance
+         */
+        ContentHeadField15.prototype.field2 = null;
+
+        /**
+         * ContentHeadField15 field3.
+         * @member {number|null|undefined} field3
+         * @memberof Msg.ContentHeadField15
+         * @instance
+         */
+        ContentHeadField15.prototype.field3 = null;
+
+        /**
+         * ContentHeadField15 field4.
+         * @member {string|null|undefined} field4
+         * @memberof Msg.ContentHeadField15
+         * @instance
+         */
+        ContentHeadField15.prototype.field4 = null;
+
+        /**
+         * ContentHeadField15 field5.
+         * @member {string|null|undefined} field5
+         * @memberof Msg.ContentHeadField15
+         * @instance
+         */
+        ContentHeadField15.prototype.field5 = null;
+
+        // OneOf field names bound to virtual getters and setters
+        let $oneOfFields;
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHeadField15.prototype, "_field1", {
+            get: $util.oneOfGetter($oneOfFields = ["field1"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHeadField15.prototype, "_field2", {
+            get: $util.oneOfGetter($oneOfFields = ["field2"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHeadField15.prototype, "_field3", {
+            get: $util.oneOfGetter($oneOfFields = ["field3"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHeadField15.prototype, "_field4", {
+            get: $util.oneOfGetter($oneOfFields = ["field4"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(ContentHeadField15.prototype, "_field5", {
+            get: $util.oneOfGetter($oneOfFields = ["field5"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        /**
+         * Encodes the specified ContentHeadField15 message. Does not implicitly {@link Msg.ContentHeadField15.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.ContentHeadField15
+         * @static
+         * @param {Msg.IContentHeadField15} message ContentHeadField15 message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        ContentHeadField15.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.field1 != null && Object.hasOwnProperty.call(message, "field1"))
+                writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.field1);
+            if (message.field2 != null && Object.hasOwnProperty.call(message, "field2"))
+                writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.field2);
+            if (message.field3 != null && Object.hasOwnProperty.call(message, "field3"))
+                writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.field3);
+            if (message.field4 != null && Object.hasOwnProperty.call(message, "field4"))
+                writer.uint32(/* id 4, wireType 2 =*/34).string(message.field4);
+            if (message.field5 != null && Object.hasOwnProperty.call(message, "field5"))
+                writer.uint32(/* id 5, wireType 2 =*/42).string(message.field5);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified ContentHeadField15 message, length delimited. Does not implicitly {@link Msg.ContentHeadField15.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.ContentHeadField15
+         * @static
+         * @param {Msg.IContentHeadField15} message ContentHeadField15 message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        ContentHeadField15.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a ContentHeadField15 message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.ContentHeadField15
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.ContentHeadField15} ContentHeadField15
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        ContentHeadField15.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.ContentHeadField15();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.field1 = reader.uint32();
+                        break;
+                    }
+                case 2: {
+                        message.field2 = reader.uint32();
+                        break;
+                    }
+                case 3: {
+                        message.field3 = reader.uint32();
+                        break;
+                    }
+                case 4: {
+                        message.field4 = reader.string();
+                        break;
+                    }
+                case 5: {
+                        message.field5 = reader.string();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a ContentHeadField15 message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.ContentHeadField15
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.ContentHeadField15} ContentHeadField15
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        ContentHeadField15.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for ContentHeadField15
+         * @function getTypeUrl
+         * @memberof Msg.ContentHeadField15
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        ContentHeadField15.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.ContentHeadField15";
+        };
+
+        return ContentHeadField15;
+    })();
+
+    Msg.Message = (function() {
+
+        /**
+         * Properties of a Message.
+         * @memberof Msg
+         * @interface IMessage
+         * @property {Msg.IRoutingHead|null} [routingHead] Message routingHead
+         * @property {Msg.IContentHead|null} [contentHead] Message contentHead
+         * @property {Msg.IMessageBody|null} [body] Message body
+         */
+
+        /**
+         * Constructs a new Message.
+         * @memberof Msg
+         * @classdesc Represents a Message.
+         * @implements IMessage
+         * @constructor
+         * @param {Msg.IMessage=} [properties] Properties to set
+         */
+        function Message(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * Message routingHead.
+         * @member {Msg.IRoutingHead|null|undefined} routingHead
+         * @memberof Msg.Message
+         * @instance
+         */
+        Message.prototype.routingHead = null;
+
+        /**
+         * Message contentHead.
+         * @member {Msg.IContentHead|null|undefined} contentHead
+         * @memberof Msg.Message
+         * @instance
+         */
+        Message.prototype.contentHead = null;
+
+        /**
+         * Message body.
+         * @member {Msg.IMessageBody|null|undefined} body
+         * @memberof Msg.Message
+         * @instance
+         */
+        Message.prototype.body = null;
+
+        // OneOf field names bound to virtual getters and setters
+        let $oneOfFields;
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Message.prototype, "_routingHead", {
+            get: $util.oneOfGetter($oneOfFields = ["routingHead"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Message.prototype, "_contentHead", {
+            get: $util.oneOfGetter($oneOfFields = ["contentHead"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Message.prototype, "_body", {
+            get: $util.oneOfGetter($oneOfFields = ["body"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        /**
+         * Encodes the specified Message message. Does not implicitly {@link Msg.Message.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.Message
+         * @static
+         * @param {Msg.IMessage} message Message message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        Message.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.routingHead != null && Object.hasOwnProperty.call(message, "routingHead"))
+                $root.Msg.RoutingHead.encode(message.routingHead, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
+            if (message.contentHead != null && Object.hasOwnProperty.call(message, "contentHead"))
+                $root.Msg.ContentHead.encode(message.contentHead, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
+            if (message.body != null && Object.hasOwnProperty.call(message, "body"))
+                $root.Msg.MessageBody.encode(message.body, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
+            return writer;
+        };
+
+        /**
+         * Encodes the specified Message message, length delimited. Does not implicitly {@link Msg.Message.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.Message
+         * @static
+         * @param {Msg.IMessage} message Message message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        Message.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a Message message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.Message
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.Message} Message
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        Message.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.Message();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.routingHead = $root.Msg.RoutingHead.decode(reader, reader.uint32());
+                        break;
+                    }
+                case 2: {
+                        message.contentHead = $root.Msg.ContentHead.decode(reader, reader.uint32());
+                        break;
+                    }
+                case 3: {
+                        message.body = $root.Msg.MessageBody.decode(reader, reader.uint32());
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a Message message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.Message
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.Message} Message
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        Message.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for Message
+         * @function getTypeUrl
+         * @memberof Msg.Message
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        Message.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.Message";
+        };
+
+        return Message;
+    })();
+
+    Msg.MessageBody = (function() {
+
+        /**
+         * Properties of a MessageBody.
+         * @memberof Msg
+         * @interface IMessageBody
+         * @property {Msg.IRichText|null} [richText] MessageBody richText
+         * @property {Uint8Array|null} [msgContent] MessageBody msgContent
+         * @property {Uint8Array|null} [msgEncryptContent] MessageBody msgEncryptContent
+         */
+
+        /**
+         * Constructs a new MessageBody.
+         * @memberof Msg
+         * @classdesc Represents a MessageBody.
+         * @implements IMessageBody
+         * @constructor
+         * @param {Msg.IMessageBody=} [properties] Properties to set
+         */
+        function MessageBody(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * MessageBody richText.
+         * @member {Msg.IRichText|null|undefined} richText
+         * @memberof Msg.MessageBody
+         * @instance
+         */
+        MessageBody.prototype.richText = null;
+
+        /**
+         * MessageBody msgContent.
+         * @member {Uint8Array|null|undefined} msgContent
+         * @memberof Msg.MessageBody
+         * @instance
+         */
+        MessageBody.prototype.msgContent = null;
+
+        /**
+         * MessageBody msgEncryptContent.
+         * @member {Uint8Array|null|undefined} msgEncryptContent
+         * @memberof Msg.MessageBody
+         * @instance
+         */
+        MessageBody.prototype.msgEncryptContent = null;
+
+        // OneOf field names bound to virtual getters and setters
+        let $oneOfFields;
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(MessageBody.prototype, "_richText", {
+            get: $util.oneOfGetter($oneOfFields = ["richText"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(MessageBody.prototype, "_msgContent", {
+            get: $util.oneOfGetter($oneOfFields = ["msgContent"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(MessageBody.prototype, "_msgEncryptContent", {
+            get: $util.oneOfGetter($oneOfFields = ["msgEncryptContent"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        /**
+         * Encodes the specified MessageBody message. Does not implicitly {@link Msg.MessageBody.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.MessageBody
+         * @static
+         * @param {Msg.IMessageBody} message MessageBody message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        MessageBody.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.richText != null && Object.hasOwnProperty.call(message, "richText"))
+                $root.Msg.RichText.encode(message.richText, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
+            if (message.msgContent != null && Object.hasOwnProperty.call(message, "msgContent"))
+                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.msgContent);
+            if (message.msgEncryptContent != null && Object.hasOwnProperty.call(message, "msgEncryptContent"))
+                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.msgEncryptContent);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified MessageBody message, length delimited. Does not implicitly {@link Msg.MessageBody.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.MessageBody
+         * @static
+         * @param {Msg.IMessageBody} message MessageBody message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        MessageBody.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a MessageBody message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.MessageBody
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.MessageBody} MessageBody
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        MessageBody.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.MessageBody();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.richText = $root.Msg.RichText.decode(reader, reader.uint32());
+                        break;
+                    }
+                case 2: {
+                        message.msgContent = reader.bytes();
+                        break;
+                    }
+                case 3: {
+                        message.msgEncryptContent = reader.bytes();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a MessageBody message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.MessageBody
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.MessageBody} MessageBody
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        MessageBody.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for MessageBody
+         * @function getTypeUrl
+         * @memberof Msg.MessageBody
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        MessageBody.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.MessageBody";
+        };
+
+        return MessageBody;
+    })();
+
+    Msg.RichText = (function() {
+
+        /**
+         * Properties of a RichText.
+         * @memberof Msg
+         * @interface IRichText
+         * @property {Msg.IAttr|null} [attr] RichText attr
+         * @property {Array.<Msg.IElem>|null} [elems] RichText elems
+         */
+
+        /**
+         * Constructs a new RichText.
+         * @memberof Msg
+         * @classdesc Represents a RichText.
+         * @implements IRichText
+         * @constructor
+         * @param {Msg.IRichText=} [properties] Properties to set
+         */
+        function RichText(properties) {
+            this.elems = [];
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * RichText attr.
+         * @member {Msg.IAttr|null|undefined} attr
+         * @memberof Msg.RichText
+         * @instance
+         */
+        RichText.prototype.attr = null;
+
+        /**
+         * RichText elems.
+         * @member {Array.<Msg.IElem>} elems
+         * @memberof Msg.RichText
+         * @instance
+         */
+        RichText.prototype.elems = $util.emptyArray;
+
+        // OneOf field names bound to virtual getters and setters
+        let $oneOfFields;
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(RichText.prototype, "_attr", {
+            get: $util.oneOfGetter($oneOfFields = ["attr"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        /**
+         * Encodes the specified RichText message. Does not implicitly {@link Msg.RichText.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.RichText
+         * @static
+         * @param {Msg.IRichText} message RichText message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        RichText.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.attr != null && Object.hasOwnProperty.call(message, "attr"))
+                $root.Msg.Attr.encode(message.attr, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
+            if (message.elems != null && message.elems.length)
+                for (let i = 0; i < message.elems.length; ++i)
+                    $root.Msg.Elem.encode(message.elems[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
+            return writer;
+        };
+
+        /**
+         * Encodes the specified RichText message, length delimited. Does not implicitly {@link Msg.RichText.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.RichText
+         * @static
+         * @param {Msg.IRichText} message RichText message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        RichText.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a RichText message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.RichText
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.RichText} RichText
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        RichText.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.RichText();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.attr = $root.Msg.Attr.decode(reader, reader.uint32());
+                        break;
+                    }
+                case 2: {
+                        if (!(message.elems && message.elems.length))
+                            message.elems = [];
+                        message.elems.push($root.Msg.Elem.decode(reader, reader.uint32()));
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a RichText message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.RichText
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.RichText} RichText
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        RichText.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for RichText
+         * @function getTypeUrl
+         * @memberof Msg.RichText
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        RichText.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.RichText";
+        };
+
+        return RichText;
+    })();
+
+    Msg.Elem = (function() {
+
+        /**
+         * Properties of an Elem.
+         * @memberof Msg
+         * @interface IElem
+         * @property {Msg.IText|null} [text] Elem text
+         * @property {Msg.IFace|null} [face] Elem face
+         * @property {Msg.ILightAppElem|null} [lightApp] Elem lightApp
+         * @property {Msg.ICommonElem|null} [commonElem] Elem commonElem
+         */
+
+        /**
+         * Constructs a new Elem.
+         * @memberof Msg
+         * @classdesc Represents an Elem.
+         * @implements IElem
+         * @constructor
+         * @param {Msg.IElem=} [properties] Properties to set
+         */
+        function Elem(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * Elem text.
+         * @member {Msg.IText|null|undefined} text
+         * @memberof Msg.Elem
+         * @instance
+         */
+        Elem.prototype.text = null;
+
+        /**
+         * Elem face.
+         * @member {Msg.IFace|null|undefined} face
+         * @memberof Msg.Elem
+         * @instance
+         */
+        Elem.prototype.face = null;
+
+        /**
+         * Elem lightApp.
+         * @member {Msg.ILightAppElem|null|undefined} lightApp
+         * @memberof Msg.Elem
+         * @instance
+         */
+        Elem.prototype.lightApp = null;
+
+        /**
+         * Elem commonElem.
+         * @member {Msg.ICommonElem|null|undefined} commonElem
+         * @memberof Msg.Elem
+         * @instance
+         */
+        Elem.prototype.commonElem = null;
+
+        // OneOf field names bound to virtual getters and setters
+        let $oneOfFields;
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Elem.prototype, "_text", {
+            get: $util.oneOfGetter($oneOfFields = ["text"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Elem.prototype, "_face", {
+            get: $util.oneOfGetter($oneOfFields = ["face"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Elem.prototype, "_lightApp", {
+            get: $util.oneOfGetter($oneOfFields = ["lightApp"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Elem.prototype, "_commonElem", {
+            get: $util.oneOfGetter($oneOfFields = ["commonElem"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        /**
+         * Encodes the specified Elem message. Does not implicitly {@link Msg.Elem.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.Elem
+         * @static
+         * @param {Msg.IElem} message Elem message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        Elem.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.text != null && Object.hasOwnProperty.call(message, "text"))
+                $root.Msg.Text.encode(message.text, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
+            if (message.face != null && Object.hasOwnProperty.call(message, "face"))
+                $root.Msg.Face.encode(message.face, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
+            if (message.lightApp != null && Object.hasOwnProperty.call(message, "lightApp"))
+                $root.Msg.LightAppElem.encode(message.lightApp, writer.uint32(/* id 51, wireType 2 =*/410).fork()).ldelim();
+            if (message.commonElem != null && Object.hasOwnProperty.call(message, "commonElem"))
+                $root.Msg.CommonElem.encode(message.commonElem, writer.uint32(/* id 53, wireType 2 =*/426).fork()).ldelim();
+            return writer;
+        };
+
+        /**
+         * Encodes the specified Elem message, length delimited. Does not implicitly {@link Msg.Elem.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.Elem
+         * @static
+         * @param {Msg.IElem} message Elem message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        Elem.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes an Elem message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.Elem
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.Elem} Elem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        Elem.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.Elem();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.text = $root.Msg.Text.decode(reader, reader.uint32());
+                        break;
+                    }
+                case 2: {
+                        message.face = $root.Msg.Face.decode(reader, reader.uint32());
+                        break;
+                    }
+                case 51: {
+                        message.lightApp = $root.Msg.LightAppElem.decode(reader, reader.uint32());
+                        break;
+                    }
+                case 53: {
+                        message.commonElem = $root.Msg.CommonElem.decode(reader, reader.uint32());
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes an Elem message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.Elem
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.Elem} Elem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        Elem.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for Elem
+         * @function getTypeUrl
+         * @memberof Msg.Elem
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        Elem.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.Elem";
+        };
+
+        return Elem;
+    })();
+
+    Msg.Text = (function() {
+
+        /**
+         * Properties of a Text.
+         * @memberof Msg
+         * @interface IText
+         * @property {string|null} [str] Text str
+         * @property {string|null} [link] Text link
+         * @property {Uint8Array|null} [attr6Buf] Text attr6Buf
+         * @property {Uint8Array|null} [attr7Buf] Text attr7Buf
+         * @property {Uint8Array|null} [buf] Text buf
+         * @property {Uint8Array|null} [pbReserve] Text pbReserve
+         */
+
+        /**
+         * Constructs a new Text.
+         * @memberof Msg
+         * @classdesc Represents a Text.
+         * @implements IText
+         * @constructor
+         * @param {Msg.IText=} [properties] Properties to set
+         */
+        function Text(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * Text str.
+         * @member {string|null|undefined} str
+         * @memberof Msg.Text
+         * @instance
+         */
+        Text.prototype.str = null;
+
+        /**
+         * Text link.
+         * @member {string|null|undefined} link
+         * @memberof Msg.Text
+         * @instance
+         */
+        Text.prototype.link = null;
+
+        /**
+         * Text attr6Buf.
+         * @member {Uint8Array|null|undefined} attr6Buf
+         * @memberof Msg.Text
+         * @instance
+         */
+        Text.prototype.attr6Buf = null;
+
+        /**
+         * Text attr7Buf.
+         * @member {Uint8Array|null|undefined} attr7Buf
+         * @memberof Msg.Text
+         * @instance
+         */
+        Text.prototype.attr7Buf = null;
+
+        /**
+         * Text buf.
+         * @member {Uint8Array|null|undefined} buf
+         * @memberof Msg.Text
+         * @instance
+         */
+        Text.prototype.buf = null;
+
+        /**
+         * Text pbReserve.
+         * @member {Uint8Array|null|undefined} pbReserve
+         * @memberof Msg.Text
+         * @instance
+         */
+        Text.prototype.pbReserve = null;
+
+        // OneOf field names bound to virtual getters and setters
+        let $oneOfFields;
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Text.prototype, "_str", {
+            get: $util.oneOfGetter($oneOfFields = ["str"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Text.prototype, "_link", {
+            get: $util.oneOfGetter($oneOfFields = ["link"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Text.prototype, "_attr6Buf", {
+            get: $util.oneOfGetter($oneOfFields = ["attr6Buf"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Text.prototype, "_attr7Buf", {
+            get: $util.oneOfGetter($oneOfFields = ["attr7Buf"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Text.prototype, "_buf", {
+            get: $util.oneOfGetter($oneOfFields = ["buf"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Text.prototype, "_pbReserve", {
+            get: $util.oneOfGetter($oneOfFields = ["pbReserve"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        /**
+         * Encodes the specified Text message. Does not implicitly {@link Msg.Text.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.Text
+         * @static
+         * @param {Msg.IText} message Text message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        Text.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.str != null && Object.hasOwnProperty.call(message, "str"))
+                writer.uint32(/* id 1, wireType 2 =*/10).string(message.str);
+            if (message.link != null && Object.hasOwnProperty.call(message, "link"))
+                writer.uint32(/* id 2, wireType 2 =*/18).string(message.link);
+            if (message.attr6Buf != null && Object.hasOwnProperty.call(message, "attr6Buf"))
+                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.attr6Buf);
+            if (message.attr7Buf != null && Object.hasOwnProperty.call(message, "attr7Buf"))
+                writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.attr7Buf);
+            if (message.buf != null && Object.hasOwnProperty.call(message, "buf"))
+                writer.uint32(/* id 11, wireType 2 =*/90).bytes(message.buf);
+            if (message.pbReserve != null && Object.hasOwnProperty.call(message, "pbReserve"))
+                writer.uint32(/* id 12, wireType 2 =*/98).bytes(message.pbReserve);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified Text message, length delimited. Does not implicitly {@link Msg.Text.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.Text
+         * @static
+         * @param {Msg.IText} message Text message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        Text.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a Text message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.Text
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.Text} Text
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        Text.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.Text();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.str = reader.string();
+                        break;
+                    }
+                case 2: {
+                        message.link = reader.string();
+                        break;
+                    }
+                case 3: {
+                        message.attr6Buf = reader.bytes();
+                        break;
+                    }
+                case 4: {
+                        message.attr7Buf = reader.bytes();
+                        break;
+                    }
+                case 11: {
+                        message.buf = reader.bytes();
+                        break;
+                    }
+                case 12: {
+                        message.pbReserve = reader.bytes();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a Text message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.Text
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.Text} Text
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        Text.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for Text
+         * @function getTypeUrl
+         * @memberof Msg.Text
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        Text.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.Text";
+        };
+
+        return Text;
+    })();
+
+    Msg.Face = (function() {
+
+        /**
+         * Properties of a Face.
+         * @memberof Msg
+         * @interface IFace
+         * @property {number|null} [index] Face index
+         * @property {Uint8Array|null} [old] Face old
+         * @property {Uint8Array|null} [buf] Face buf
+         */
+
+        /**
+         * Constructs a new Face.
+         * @memberof Msg
+         * @classdesc Represents a Face.
+         * @implements IFace
+         * @constructor
+         * @param {Msg.IFace=} [properties] Properties to set
+         */
+        function Face(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * Face index.
+         * @member {number|null|undefined} index
+         * @memberof Msg.Face
+         * @instance
+         */
+        Face.prototype.index = null;
+
+        /**
+         * Face old.
+         * @member {Uint8Array|null|undefined} old
+         * @memberof Msg.Face
+         * @instance
+         */
+        Face.prototype.old = null;
+
+        /**
+         * Face buf.
+         * @member {Uint8Array|null|undefined} buf
+         * @memberof Msg.Face
+         * @instance
+         */
+        Face.prototype.buf = null;
+
+        // OneOf field names bound to virtual getters and setters
+        let $oneOfFields;
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Face.prototype, "_index", {
+            get: $util.oneOfGetter($oneOfFields = ["index"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Face.prototype, "_old", {
+            get: $util.oneOfGetter($oneOfFields = ["old"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Face.prototype, "_buf", {
+            get: $util.oneOfGetter($oneOfFields = ["buf"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        /**
+         * Encodes the specified Face message. Does not implicitly {@link Msg.Face.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.Face
+         * @static
+         * @param {Msg.IFace} message Face message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        Face.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.index != null && Object.hasOwnProperty.call(message, "index"))
+                writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.index);
+            if (message.old != null && Object.hasOwnProperty.call(message, "old"))
+                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.old);
+            if (message.buf != null && Object.hasOwnProperty.call(message, "buf"))
+                writer.uint32(/* id 11, wireType 2 =*/90).bytes(message.buf);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified Face message, length delimited. Does not implicitly {@link Msg.Face.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.Face
+         * @static
+         * @param {Msg.IFace} message Face message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        Face.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a Face message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.Face
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.Face} Face
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        Face.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.Face();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.index = reader.uint32();
+                        break;
+                    }
+                case 2: {
+                        message.old = reader.bytes();
+                        break;
+                    }
+                case 11: {
+                        message.buf = reader.bytes();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a Face message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.Face
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.Face} Face
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        Face.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for Face
+         * @function getTypeUrl
+         * @memberof Msg.Face
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        Face.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.Face";
+        };
+
+        return Face;
+    })();
+
+    Msg.LightAppElem = (function() {
+
+        /**
+         * Properties of a LightAppElem.
+         * @memberof Msg
+         * @interface ILightAppElem
+         * @property {Uint8Array|null} [data] LightAppElem data
+         * @property {Uint8Array|null} [msgResid] LightAppElem msgResid
+         */
+
+        /**
+         * Constructs a new LightAppElem.
+         * @memberof Msg
+         * @classdesc Represents a LightAppElem.
+         * @implements ILightAppElem
+         * @constructor
+         * @param {Msg.ILightAppElem=} [properties] Properties to set
+         */
+        function LightAppElem(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * LightAppElem data.
+         * @member {Uint8Array|null|undefined} data
+         * @memberof Msg.LightAppElem
+         * @instance
+         */
+        LightAppElem.prototype.data = null;
+
+        /**
+         * LightAppElem msgResid.
+         * @member {Uint8Array|null|undefined} msgResid
+         * @memberof Msg.LightAppElem
+         * @instance
+         */
+        LightAppElem.prototype.msgResid = null;
+
+        // OneOf field names bound to virtual getters and setters
+        let $oneOfFields;
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(LightAppElem.prototype, "_data", {
+            get: $util.oneOfGetter($oneOfFields = ["data"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(LightAppElem.prototype, "_msgResid", {
+            get: $util.oneOfGetter($oneOfFields = ["msgResid"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        /**
+         * Encodes the specified LightAppElem message. Does not implicitly {@link Msg.LightAppElem.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.LightAppElem
+         * @static
+         * @param {Msg.ILightAppElem} message LightAppElem message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        LightAppElem.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.data != null && Object.hasOwnProperty.call(message, "data"))
+                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.data);
+            if (message.msgResid != null && Object.hasOwnProperty.call(message, "msgResid"))
+                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.msgResid);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified LightAppElem message, length delimited. Does not implicitly {@link Msg.LightAppElem.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.LightAppElem
+         * @static
+         * @param {Msg.ILightAppElem} message LightAppElem message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        LightAppElem.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a LightAppElem message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.LightAppElem
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.LightAppElem} LightAppElem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        LightAppElem.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.LightAppElem();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.data = reader.bytes();
+                        break;
+                    }
+                case 2: {
+                        message.msgResid = reader.bytes();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a LightAppElem message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.LightAppElem
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.LightAppElem} LightAppElem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        LightAppElem.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for LightAppElem
+         * @function getTypeUrl
+         * @memberof Msg.LightAppElem
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        LightAppElem.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.LightAppElem";
+        };
+
+        return LightAppElem;
+    })();
+
+    Msg.CommonElem = (function() {
+
+        /**
+         * Properties of a CommonElem.
+         * @memberof Msg
+         * @interface ICommonElem
+         * @property {number} serviceType CommonElem serviceType
+         * @property {Uint8Array|null} [pbElem] CommonElem pbElem
+         * @property {number|null} [businessType] CommonElem businessType
+         */
+
+        /**
+         * Constructs a new CommonElem.
+         * @memberof Msg
+         * @classdesc Represents a CommonElem.
+         * @implements ICommonElem
+         * @constructor
+         * @param {Msg.ICommonElem=} [properties] Properties to set
+         */
+        function CommonElem(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * CommonElem serviceType.
+         * @member {number} serviceType
+         * @memberof Msg.CommonElem
+         * @instance
+         */
+        CommonElem.prototype.serviceType = 0;
+
+        /**
+         * CommonElem pbElem.
+         * @member {Uint8Array|null|undefined} pbElem
+         * @memberof Msg.CommonElem
+         * @instance
+         */
+        CommonElem.prototype.pbElem = null;
+
+        /**
+         * CommonElem businessType.
+         * @member {number|null|undefined} businessType
+         * @memberof Msg.CommonElem
+         * @instance
+         */
+        CommonElem.prototype.businessType = null;
+
+        // OneOf field names bound to virtual getters and setters
+        let $oneOfFields;
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(CommonElem.prototype, "_pbElem", {
+            get: $util.oneOfGetter($oneOfFields = ["pbElem"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(CommonElem.prototype, "_businessType", {
+            get: $util.oneOfGetter($oneOfFields = ["businessType"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        /**
+         * Encodes the specified CommonElem message. Does not implicitly {@link Msg.CommonElem.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.CommonElem
+         * @static
+         * @param {Msg.ICommonElem} message CommonElem message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        CommonElem.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.serviceType);
+            if (message.pbElem != null && Object.hasOwnProperty.call(message, "pbElem"))
+                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.pbElem);
+            if (message.businessType != null && Object.hasOwnProperty.call(message, "businessType"))
+                writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.businessType);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified CommonElem message, length delimited. Does not implicitly {@link Msg.CommonElem.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.CommonElem
+         * @static
+         * @param {Msg.ICommonElem} message CommonElem message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        CommonElem.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a CommonElem message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.CommonElem
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.CommonElem} CommonElem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        CommonElem.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.CommonElem();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.serviceType = reader.uint32();
+                        break;
+                    }
+                case 2: {
+                        message.pbElem = reader.bytes();
+                        break;
+                    }
+                case 3: {
+                        message.businessType = reader.uint32();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            if (!message.hasOwnProperty("serviceType"))
+                throw $util.ProtocolError("missing required 'serviceType'", { instance: message });
+            return message;
+        };
+
+        /**
+         * Decodes a CommonElem message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.CommonElem
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.CommonElem} CommonElem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        CommonElem.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for CommonElem
+         * @function getTypeUrl
+         * @memberof Msg.CommonElem
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        CommonElem.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.CommonElem";
+        };
+
+        return CommonElem;
+    })();
+
+    Msg.Attr = (function() {
+
+        /**
+         * Properties of an Attr.
+         * @memberof Msg
+         * @interface IAttr
+         * @property {number|null} [codePage] Attr codePage
+         * @property {number|null} [time] Attr time
+         * @property {number|null} [random] Attr random
+         * @property {number|null} [color] Attr color
+         * @property {number|null} [size] Attr size
+         * @property {number|null} [effect] Attr effect
+         * @property {number|null} [charSet] Attr charSet
+         * @property {number|null} [pitchAndFamily] Attr pitchAndFamily
+         * @property {string|null} [fontName] Attr fontName
+         * @property {Uint8Array|null} [reserveData] Attr reserveData
+         */
+
+        /**
+         * Constructs a new Attr.
+         * @memberof Msg
+         * @classdesc Represents an Attr.
+         * @implements IAttr
+         * @constructor
+         * @param {Msg.IAttr=} [properties] Properties to set
+         */
+        function Attr(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * Attr codePage.
+         * @member {number|null|undefined} codePage
+         * @memberof Msg.Attr
+         * @instance
+         */
+        Attr.prototype.codePage = null;
+
+        /**
+         * Attr time.
+         * @member {number|null|undefined} time
+         * @memberof Msg.Attr
+         * @instance
+         */
+        Attr.prototype.time = null;
+
+        /**
+         * Attr random.
+         * @member {number|null|undefined} random
+         * @memberof Msg.Attr
+         * @instance
+         */
+        Attr.prototype.random = null;
+
+        /**
+         * Attr color.
+         * @member {number|null|undefined} color
+         * @memberof Msg.Attr
+         * @instance
+         */
+        Attr.prototype.color = null;
+
+        /**
+         * Attr size.
+         * @member {number|null|undefined} size
+         * @memberof Msg.Attr
+         * @instance
+         */
+        Attr.prototype.size = null;
+
+        /**
+         * Attr effect.
+         * @member {number|null|undefined} effect
+         * @memberof Msg.Attr
+         * @instance
+         */
+        Attr.prototype.effect = null;
+
+        /**
+         * Attr charSet.
+         * @member {number|null|undefined} charSet
+         * @memberof Msg.Attr
+         * @instance
+         */
+        Attr.prototype.charSet = null;
+
+        /**
+         * Attr pitchAndFamily.
+         * @member {number|null|undefined} pitchAndFamily
+         * @memberof Msg.Attr
+         * @instance
+         */
+        Attr.prototype.pitchAndFamily = null;
+
+        /**
+         * Attr fontName.
+         * @member {string|null|undefined} fontName
+         * @memberof Msg.Attr
+         * @instance
+         */
+        Attr.prototype.fontName = null;
+
+        /**
+         * Attr reserveData.
+         * @member {Uint8Array|null|undefined} reserveData
+         * @memberof Msg.Attr
+         * @instance
+         */
+        Attr.prototype.reserveData = null;
+
+        // OneOf field names bound to virtual getters and setters
+        let $oneOfFields;
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Attr.prototype, "_codePage", {
+            get: $util.oneOfGetter($oneOfFields = ["codePage"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Attr.prototype, "_time", {
+            get: $util.oneOfGetter($oneOfFields = ["time"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Attr.prototype, "_random", {
+            get: $util.oneOfGetter($oneOfFields = ["random"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Attr.prototype, "_color", {
+            get: $util.oneOfGetter($oneOfFields = ["color"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Attr.prototype, "_size", {
+            get: $util.oneOfGetter($oneOfFields = ["size"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Attr.prototype, "_effect", {
+            get: $util.oneOfGetter($oneOfFields = ["effect"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Attr.prototype, "_charSet", {
+            get: $util.oneOfGetter($oneOfFields = ["charSet"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Attr.prototype, "_pitchAndFamily", {
+            get: $util.oneOfGetter($oneOfFields = ["pitchAndFamily"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Attr.prototype, "_fontName", {
+            get: $util.oneOfGetter($oneOfFields = ["fontName"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        // Virtual OneOf for proto3 optional field
+        Object.defineProperty(Attr.prototype, "_reserveData", {
+            get: $util.oneOfGetter($oneOfFields = ["reserveData"]),
+            set: $util.oneOfSetter($oneOfFields)
+        });
+
+        /**
+         * Encodes the specified Attr message. Does not implicitly {@link Msg.Attr.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.Attr
+         * @static
+         * @param {Msg.IAttr} message Attr message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        Attr.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.codePage != null && Object.hasOwnProperty.call(message, "codePage"))
+                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.codePage);
+            if (message.time != null && Object.hasOwnProperty.call(message, "time"))
+                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.time);
+            if (message.random != null && Object.hasOwnProperty.call(message, "random"))
+                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.random);
+            if (message.color != null && Object.hasOwnProperty.call(message, "color"))
+                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.color);
+            if (message.size != null && Object.hasOwnProperty.call(message, "size"))
+                writer.uint32(/* id 5, wireType 0 =*/40).int32(message.size);
+            if (message.effect != null && Object.hasOwnProperty.call(message, "effect"))
+                writer.uint32(/* id 6, wireType 0 =*/48).int32(message.effect);
+            if (message.charSet != null && Object.hasOwnProperty.call(message, "charSet"))
+                writer.uint32(/* id 7, wireType 0 =*/56).int32(message.charSet);
+            if (message.pitchAndFamily != null && Object.hasOwnProperty.call(message, "pitchAndFamily"))
+                writer.uint32(/* id 8, wireType 0 =*/64).int32(message.pitchAndFamily);
+            if (message.fontName != null && Object.hasOwnProperty.call(message, "fontName"))
+                writer.uint32(/* id 9, wireType 2 =*/74).string(message.fontName);
+            if (message.reserveData != null && Object.hasOwnProperty.call(message, "reserveData"))
+                writer.uint32(/* id 10, wireType 2 =*/82).bytes(message.reserveData);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified Attr message, length delimited. Does not implicitly {@link Msg.Attr.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.Attr
+         * @static
+         * @param {Msg.IAttr} message Attr message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        Attr.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes an Attr message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.Attr
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.Attr} Attr
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        Attr.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.Attr();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.codePage = reader.int32();
+                        break;
+                    }
+                case 2: {
+                        message.time = reader.int32();
+                        break;
+                    }
+                case 3: {
+                        message.random = reader.int32();
+                        break;
+                    }
+                case 4: {
+                        message.color = reader.int32();
+                        break;
+                    }
+                case 5: {
+                        message.size = reader.int32();
+                        break;
+                    }
+                case 6: {
+                        message.effect = reader.int32();
+                        break;
+                    }
+                case 7: {
+                        message.charSet = reader.int32();
+                        break;
+                    }
+                case 8: {
+                        message.pitchAndFamily = reader.int32();
+                        break;
+                    }
+                case 9: {
+                        message.fontName = reader.string();
+                        break;
+                    }
+                case 10: {
+                        message.reserveData = reader.bytes();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes an Attr message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.Attr
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.Attr} Attr
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        Attr.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for Attr
+         * @function getTypeUrl
+         * @memberof Msg.Attr
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        Attr.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.Attr";
+        };
+
+        return Attr;
+    })();
+
+    Msg.MarkdownElem = (function() {
+
+        /**
+         * Properties of a MarkdownElem.
+         * @memberof Msg
+         * @interface IMarkdownElem
+         * @property {string|null} [content] MarkdownElem content
+         */
+
+        /**
+         * Constructs a new MarkdownElem.
+         * @memberof Msg
+         * @classdesc Represents a MarkdownElem.
+         * @implements IMarkdownElem
+         * @constructor
+         * @param {Msg.IMarkdownElem=} [properties] Properties to set
+         */
+        function MarkdownElem(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * MarkdownElem content.
+         * @member {string} content
+         * @memberof Msg.MarkdownElem
+         * @instance
+         */
+        MarkdownElem.prototype.content = "";
+
+        /**
+         * Encodes the specified MarkdownElem message. Does not implicitly {@link Msg.MarkdownElem.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.MarkdownElem
+         * @static
+         * @param {Msg.IMarkdownElem} message MarkdownElem message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        MarkdownElem.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.content != null && Object.hasOwnProperty.call(message, "content"))
+                writer.uint32(/* id 1, wireType 2 =*/10).string(message.content);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified MarkdownElem message, length delimited. Does not implicitly {@link Msg.MarkdownElem.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.MarkdownElem
+         * @static
+         * @param {Msg.IMarkdownElem} message MarkdownElem message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        MarkdownElem.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a MarkdownElem message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.MarkdownElem
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.MarkdownElem} MarkdownElem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        MarkdownElem.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.MarkdownElem();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.content = reader.string();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a MarkdownElem message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.MarkdownElem
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.MarkdownElem} MarkdownElem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        MarkdownElem.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for MarkdownElem
+         * @function getTypeUrl
+         * @memberof Msg.MarkdownElem
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        MarkdownElem.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.MarkdownElem";
+        };
+
+        return MarkdownElem;
+    })();
+
+    Msg.PbMultiMsgItem = (function() {
+
+        /**
+         * Properties of a PbMultiMsgItem.
+         * @memberof Msg
+         * @interface IPbMultiMsgItem
+         * @property {string|null} [fileName] PbMultiMsgItem fileName
+         * @property {Msg.IPbMultiMsgNew|null} [buffer] PbMultiMsgItem buffer
+         */
+
+        /**
+         * Constructs a new PbMultiMsgItem.
+         * @memberof Msg
+         * @classdesc Represents a PbMultiMsgItem.
+         * @implements IPbMultiMsgItem
+         * @constructor
+         * @param {Msg.IPbMultiMsgItem=} [properties] Properties to set
+         */
+        function PbMultiMsgItem(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * PbMultiMsgItem fileName.
+         * @member {string} fileName
+         * @memberof Msg.PbMultiMsgItem
+         * @instance
+         */
+        PbMultiMsgItem.prototype.fileName = "";
+
+        /**
+         * PbMultiMsgItem buffer.
+         * @member {Msg.IPbMultiMsgNew|null|undefined} buffer
+         * @memberof Msg.PbMultiMsgItem
+         * @instance
+         */
+        PbMultiMsgItem.prototype.buffer = null;
+
+        /**
+         * Encodes the specified PbMultiMsgItem message. Does not implicitly {@link Msg.PbMultiMsgItem.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.PbMultiMsgItem
+         * @static
+         * @param {Msg.IPbMultiMsgItem} message PbMultiMsgItem message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        PbMultiMsgItem.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.fileName != null && Object.hasOwnProperty.call(message, "fileName"))
+                writer.uint32(/* id 1, wireType 2 =*/10).string(message.fileName);
+            if (message.buffer != null && Object.hasOwnProperty.call(message, "buffer"))
+                $root.Msg.PbMultiMsgNew.encode(message.buffer, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
+            return writer;
+        };
+
+        /**
+         * Encodes the specified PbMultiMsgItem message, length delimited. Does not implicitly {@link Msg.PbMultiMsgItem.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.PbMultiMsgItem
+         * @static
+         * @param {Msg.IPbMultiMsgItem} message PbMultiMsgItem message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        PbMultiMsgItem.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a PbMultiMsgItem message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.PbMultiMsgItem
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.PbMultiMsgItem} PbMultiMsgItem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        PbMultiMsgItem.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.PbMultiMsgItem();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.fileName = reader.string();
+                        break;
+                    }
+                case 2: {
+                        message.buffer = $root.Msg.PbMultiMsgNew.decode(reader, reader.uint32());
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a PbMultiMsgItem message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.PbMultiMsgItem
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.PbMultiMsgItem} PbMultiMsgItem
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        PbMultiMsgItem.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for PbMultiMsgItem
+         * @function getTypeUrl
+         * @memberof Msg.PbMultiMsgItem
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        PbMultiMsgItem.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.PbMultiMsgItem";
+        };
+
+        return PbMultiMsgItem;
+    })();
+
+    Msg.PbMultiMsgNew = (function() {
+
+        /**
+         * Properties of a PbMultiMsgNew.
+         * @memberof Msg
+         * @interface IPbMultiMsgNew
+         * @property {Array.<Msg.IMessage>|null} [msg] PbMultiMsgNew msg
+         */
+
+        /**
+         * Constructs a new PbMultiMsgNew.
+         * @memberof Msg
+         * @classdesc Represents a PbMultiMsgNew.
+         * @implements IPbMultiMsgNew
+         * @constructor
+         * @param {Msg.IPbMultiMsgNew=} [properties] Properties to set
+         */
+        function PbMultiMsgNew(properties) {
+            this.msg = [];
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * PbMultiMsgNew msg.
+         * @member {Array.<Msg.IMessage>} msg
+         * @memberof Msg.PbMultiMsgNew
+         * @instance
+         */
+        PbMultiMsgNew.prototype.msg = $util.emptyArray;
+
+        /**
+         * Encodes the specified PbMultiMsgNew message. Does not implicitly {@link Msg.PbMultiMsgNew.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.PbMultiMsgNew
+         * @static
+         * @param {Msg.IPbMultiMsgNew} message PbMultiMsgNew message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        PbMultiMsgNew.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.msg != null && message.msg.length)
+                for (let i = 0; i < message.msg.length; ++i)
+                    $root.Msg.Message.encode(message.msg[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
+            return writer;
+        };
+
+        /**
+         * Encodes the specified PbMultiMsgNew message, length delimited. Does not implicitly {@link Msg.PbMultiMsgNew.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.PbMultiMsgNew
+         * @static
+         * @param {Msg.IPbMultiMsgNew} message PbMultiMsgNew message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        PbMultiMsgNew.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a PbMultiMsgNew message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.PbMultiMsgNew
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.PbMultiMsgNew} PbMultiMsgNew
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        PbMultiMsgNew.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.PbMultiMsgNew();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        if (!(message.msg && message.msg.length))
+                            message.msg = [];
+                        message.msg.push($root.Msg.Message.decode(reader, reader.uint32()));
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a PbMultiMsgNew message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.PbMultiMsgNew
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.PbMultiMsgNew} PbMultiMsgNew
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        PbMultiMsgNew.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for PbMultiMsgNew
+         * @function getTypeUrl
+         * @memberof Msg.PbMultiMsgNew
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        PbMultiMsgNew.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.PbMultiMsgNew";
+        };
+
+        return PbMultiMsgNew;
+    })();
+
+    Msg.PbMultiMsgTransmit = (function() {
+
+        /**
+         * Properties of a PbMultiMsgTransmit.
+         * @memberof Msg
+         * @interface IPbMultiMsgTransmit
+         * @property {Array.<Msg.IMessage>|null} [msg] PbMultiMsgTransmit msg
+         * @property {Array.<Msg.IPbMultiMsgItem>|null} [pbItemList] PbMultiMsgTransmit pbItemList
+         */
+
+        /**
+         * Constructs a new PbMultiMsgTransmit.
+         * @memberof Msg
+         * @classdesc Represents a PbMultiMsgTransmit.
+         * @implements IPbMultiMsgTransmit
+         * @constructor
+         * @param {Msg.IPbMultiMsgTransmit=} [properties] Properties to set
+         */
+        function PbMultiMsgTransmit(properties) {
+            this.msg = [];
+            this.pbItemList = [];
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * PbMultiMsgTransmit msg.
+         * @member {Array.<Msg.IMessage>} msg
+         * @memberof Msg.PbMultiMsgTransmit
+         * @instance
+         */
+        PbMultiMsgTransmit.prototype.msg = $util.emptyArray;
+
+        /**
+         * PbMultiMsgTransmit pbItemList.
+         * @member {Array.<Msg.IPbMultiMsgItem>} pbItemList
+         * @memberof Msg.PbMultiMsgTransmit
+         * @instance
+         */
+        PbMultiMsgTransmit.prototype.pbItemList = $util.emptyArray;
+
+        /**
+         * Encodes the specified PbMultiMsgTransmit message. Does not implicitly {@link Msg.PbMultiMsgTransmit.verify|verify} messages.
+         * @function encode
+         * @memberof Msg.PbMultiMsgTransmit
+         * @static
+         * @param {Msg.IPbMultiMsgTransmit} message PbMultiMsgTransmit message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        PbMultiMsgTransmit.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.msg != null && message.msg.length)
+                for (let i = 0; i < message.msg.length; ++i)
+                    $root.Msg.Message.encode(message.msg[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
+            if (message.pbItemList != null && message.pbItemList.length)
+                for (let i = 0; i < message.pbItemList.length; ++i)
+                    $root.Msg.PbMultiMsgItem.encode(message.pbItemList[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
+            return writer;
+        };
+
+        /**
+         * Encodes the specified PbMultiMsgTransmit message, length delimited. Does not implicitly {@link Msg.PbMultiMsgTransmit.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof Msg.PbMultiMsgTransmit
+         * @static
+         * @param {Msg.IPbMultiMsgTransmit} message PbMultiMsgTransmit message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        PbMultiMsgTransmit.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a PbMultiMsgTransmit message from the specified reader or buffer.
+         * @function decode
+         * @memberof Msg.PbMultiMsgTransmit
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {Msg.PbMultiMsgTransmit} PbMultiMsgTransmit
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        PbMultiMsgTransmit.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Msg.PbMultiMsgTransmit();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        if (!(message.msg && message.msg.length))
+                            message.msg = [];
+                        message.msg.push($root.Msg.Message.decode(reader, reader.uint32()));
+                        break;
+                    }
+                case 2: {
+                        if (!(message.pbItemList && message.pbItemList.length))
+                            message.pbItemList = [];
+                        message.pbItemList.push($root.Msg.PbMultiMsgItem.decode(reader, reader.uint32()));
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a PbMultiMsgTransmit message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof Msg.PbMultiMsgTransmit
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {Msg.PbMultiMsgTransmit} PbMultiMsgTransmit
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        PbMultiMsgTransmit.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for PbMultiMsgTransmit
+         * @function getTypeUrl
+         * @memberof Msg.PbMultiMsgTransmit
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        PbMultiMsgTransmit.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/Msg.PbMultiMsgTransmit";
+        };
+
+        return PbMultiMsgTransmit;
+    })();
+
+    return Msg;
+})();
+
+export const RichMedia = $root.RichMedia = (() => {
+
+    /**
+     * Namespace RichMedia.
+     * @exports RichMedia
+     * @namespace
+     */
+    const RichMedia = {};
+
+    RichMedia.MsgInfo = (function() {
+
+        /**
+         * Properties of a MsgInfo.
+         * @memberof RichMedia
+         * @interface IMsgInfo
+         * @property {Array.<RichMedia.IMsgInfoBody>|null} [msgInfoBody] MsgInfo msgInfoBody
+         * @property {RichMedia.IExtBizInfo|null} [extBizInfo] MsgInfo extBizInfo
+         */
+
+        /**
+         * Constructs a new MsgInfo.
+         * @memberof RichMedia
+         * @classdesc Represents a MsgInfo.
+         * @implements IMsgInfo
+         * @constructor
+         * @param {RichMedia.IMsgInfo=} [properties] Properties to set
+         */
+        function MsgInfo(properties) {
+            this.msgInfoBody = [];
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * MsgInfo msgInfoBody.
+         * @member {Array.<RichMedia.IMsgInfoBody>} msgInfoBody
+         * @memberof RichMedia.MsgInfo
+         * @instance
+         */
+        MsgInfo.prototype.msgInfoBody = $util.emptyArray;
+
+        /**
+         * MsgInfo extBizInfo.
+         * @member {RichMedia.IExtBizInfo|null|undefined} extBizInfo
+         * @memberof RichMedia.MsgInfo
+         * @instance
+         */
+        MsgInfo.prototype.extBizInfo = null;
+
+        /**
+         * Encodes the specified MsgInfo message. Does not implicitly {@link RichMedia.MsgInfo.verify|verify} messages.
+         * @function encode
+         * @memberof RichMedia.MsgInfo
+         * @static
+         * @param {RichMedia.IMsgInfo} message MsgInfo message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        MsgInfo.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.msgInfoBody != null && message.msgInfoBody.length)
+                for (let i = 0; i < message.msgInfoBody.length; ++i)
+                    $root.RichMedia.MsgInfoBody.encode(message.msgInfoBody[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
+            if (message.extBizInfo != null && Object.hasOwnProperty.call(message, "extBizInfo"))
+                $root.RichMedia.ExtBizInfo.encode(message.extBizInfo, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
+            return writer;
+        };
+
+        /**
+         * Encodes the specified MsgInfo message, length delimited. Does not implicitly {@link RichMedia.MsgInfo.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof RichMedia.MsgInfo
+         * @static
+         * @param {RichMedia.IMsgInfo} message MsgInfo message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        MsgInfo.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a MsgInfo message from the specified reader or buffer.
+         * @function decode
+         * @memberof RichMedia.MsgInfo
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {RichMedia.MsgInfo} MsgInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        MsgInfo.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.RichMedia.MsgInfo();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        if (!(message.msgInfoBody && message.msgInfoBody.length))
+                            message.msgInfoBody = [];
+                        message.msgInfoBody.push($root.RichMedia.MsgInfoBody.decode(reader, reader.uint32()));
+                        break;
+                    }
+                case 2: {
+                        message.extBizInfo = $root.RichMedia.ExtBizInfo.decode(reader, reader.uint32());
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a MsgInfo message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof RichMedia.MsgInfo
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {RichMedia.MsgInfo} MsgInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        MsgInfo.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for MsgInfo
+         * @function getTypeUrl
+         * @memberof RichMedia.MsgInfo
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        MsgInfo.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/RichMedia.MsgInfo";
+        };
+
+        return MsgInfo;
+    })();
+
+    RichMedia.MsgInfoBody = (function() {
+
+        /**
+         * Properties of a MsgInfoBody.
+         * @memberof RichMedia
+         * @interface IMsgInfoBody
+         * @property {RichMedia.IIndexNode|null} [index] MsgInfoBody index
+         * @property {RichMedia.IPicInfo|null} [pic] MsgInfoBody pic
+         * @property {boolean|null} [fileExist] MsgInfoBody fileExist
+         */
+
+        /**
+         * Constructs a new MsgInfoBody.
+         * @memberof RichMedia
+         * @classdesc Represents a MsgInfoBody.
+         * @implements IMsgInfoBody
+         * @constructor
+         * @param {RichMedia.IMsgInfoBody=} [properties] Properties to set
+         */
+        function MsgInfoBody(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * MsgInfoBody index.
+         * @member {RichMedia.IIndexNode|null|undefined} index
+         * @memberof RichMedia.MsgInfoBody
+         * @instance
+         */
+        MsgInfoBody.prototype.index = null;
+
+        /**
+         * MsgInfoBody pic.
+         * @member {RichMedia.IPicInfo|null|undefined} pic
+         * @memberof RichMedia.MsgInfoBody
+         * @instance
+         */
+        MsgInfoBody.prototype.pic = null;
+
+        /**
+         * MsgInfoBody fileExist.
+         * @member {boolean} fileExist
+         * @memberof RichMedia.MsgInfoBody
+         * @instance
+         */
+        MsgInfoBody.prototype.fileExist = false;
+
+        /**
+         * Encodes the specified MsgInfoBody message. Does not implicitly {@link RichMedia.MsgInfoBody.verify|verify} messages.
+         * @function encode
+         * @memberof RichMedia.MsgInfoBody
+         * @static
+         * @param {RichMedia.IMsgInfoBody} message MsgInfoBody message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        MsgInfoBody.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.index != null && Object.hasOwnProperty.call(message, "index"))
+                $root.RichMedia.IndexNode.encode(message.index, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
+            if (message.pic != null && Object.hasOwnProperty.call(message, "pic"))
+                $root.RichMedia.PicInfo.encode(message.pic, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
+            if (message.fileExist != null && Object.hasOwnProperty.call(message, "fileExist"))
+                writer.uint32(/* id 5, wireType 0 =*/40).bool(message.fileExist);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified MsgInfoBody message, length delimited. Does not implicitly {@link RichMedia.MsgInfoBody.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof RichMedia.MsgInfoBody
+         * @static
+         * @param {RichMedia.IMsgInfoBody} message MsgInfoBody message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        MsgInfoBody.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a MsgInfoBody message from the specified reader or buffer.
+         * @function decode
+         * @memberof RichMedia.MsgInfoBody
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {RichMedia.MsgInfoBody} MsgInfoBody
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        MsgInfoBody.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.RichMedia.MsgInfoBody();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.index = $root.RichMedia.IndexNode.decode(reader, reader.uint32());
+                        break;
+                    }
+                case 2: {
+                        message.pic = $root.RichMedia.PicInfo.decode(reader, reader.uint32());
+                        break;
+                    }
+                case 5: {
+                        message.fileExist = reader.bool();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a MsgInfoBody message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof RichMedia.MsgInfoBody
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {RichMedia.MsgInfoBody} MsgInfoBody
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        MsgInfoBody.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for MsgInfoBody
+         * @function getTypeUrl
+         * @memberof RichMedia.MsgInfoBody
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        MsgInfoBody.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/RichMedia.MsgInfoBody";
+        };
+
+        return MsgInfoBody;
+    })();
+
+    RichMedia.IndexNode = (function() {
+
+        /**
+         * Properties of an IndexNode.
+         * @memberof RichMedia
+         * @interface IIndexNode
+         * @property {RichMedia.IFileInfo|null} [info] IndexNode info
+         * @property {string|null} [fileUuid] IndexNode fileUuid
+         * @property {number|null} [storeID] IndexNode storeID
+         * @property {number|null} [uploadTime] IndexNode uploadTime
+         * @property {number|null} [expire] IndexNode expire
+         * @property {number|null} [type] IndexNode type
+         */
+
+        /**
+         * Constructs a new IndexNode.
+         * @memberof RichMedia
+         * @classdesc Represents an IndexNode.
+         * @implements IIndexNode
+         * @constructor
+         * @param {RichMedia.IIndexNode=} [properties] Properties to set
+         */
+        function IndexNode(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * IndexNode info.
+         * @member {RichMedia.IFileInfo|null|undefined} info
+         * @memberof RichMedia.IndexNode
+         * @instance
+         */
+        IndexNode.prototype.info = null;
+
+        /**
+         * IndexNode fileUuid.
+         * @member {string} fileUuid
+         * @memberof RichMedia.IndexNode
+         * @instance
+         */
+        IndexNode.prototype.fileUuid = "";
+
+        /**
+         * IndexNode storeID.
+         * @member {number} storeID
+         * @memberof RichMedia.IndexNode
+         * @instance
+         */
+        IndexNode.prototype.storeID = 0;
+
+        /**
+         * IndexNode uploadTime.
+         * @member {number} uploadTime
+         * @memberof RichMedia.IndexNode
+         * @instance
+         */
+        IndexNode.prototype.uploadTime = 0;
+
+        /**
+         * IndexNode expire.
+         * @member {number} expire
+         * @memberof RichMedia.IndexNode
+         * @instance
+         */
+        IndexNode.prototype.expire = 0;
+
+        /**
+         * IndexNode type.
+         * @member {number} type
+         * @memberof RichMedia.IndexNode
+         * @instance
+         */
+        IndexNode.prototype.type = 0;
+
+        /**
+         * Encodes the specified IndexNode message. Does not implicitly {@link RichMedia.IndexNode.verify|verify} messages.
+         * @function encode
+         * @memberof RichMedia.IndexNode
+         * @static
+         * @param {RichMedia.IIndexNode} message IndexNode message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        IndexNode.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.info != null && Object.hasOwnProperty.call(message, "info"))
+                $root.RichMedia.FileInfo.encode(message.info, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
+            if (message.fileUuid != null && Object.hasOwnProperty.call(message, "fileUuid"))
+                writer.uint32(/* id 2, wireType 2 =*/18).string(message.fileUuid);
+            if (message.storeID != null && Object.hasOwnProperty.call(message, "storeID"))
+                writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.storeID);
+            if (message.uploadTime != null && Object.hasOwnProperty.call(message, "uploadTime"))
+                writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.uploadTime);
+            if (message.expire != null && Object.hasOwnProperty.call(message, "expire"))
+                writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.expire);
+            if (message.type != null && Object.hasOwnProperty.call(message, "type"))
+                writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.type);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified IndexNode message, length delimited. Does not implicitly {@link RichMedia.IndexNode.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof RichMedia.IndexNode
+         * @static
+         * @param {RichMedia.IIndexNode} message IndexNode message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        IndexNode.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes an IndexNode message from the specified reader or buffer.
+         * @function decode
+         * @memberof RichMedia.IndexNode
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {RichMedia.IndexNode} IndexNode
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        IndexNode.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.RichMedia.IndexNode();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.info = $root.RichMedia.FileInfo.decode(reader, reader.uint32());
+                        break;
+                    }
+                case 2: {
+                        message.fileUuid = reader.string();
+                        break;
+                    }
+                case 3: {
+                        message.storeID = reader.uint32();
+                        break;
+                    }
+                case 4: {
+                        message.uploadTime = reader.uint32();
+                        break;
+                    }
+                case 5: {
+                        message.expire = reader.uint32();
+                        break;
+                    }
+                case 6: {
+                        message.type = reader.uint32();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes an IndexNode message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof RichMedia.IndexNode
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {RichMedia.IndexNode} IndexNode
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        IndexNode.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for IndexNode
+         * @function getTypeUrl
+         * @memberof RichMedia.IndexNode
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        IndexNode.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/RichMedia.IndexNode";
+        };
+
+        return IndexNode;
+    })();
+
+    RichMedia.FileInfo = (function() {
+
+        /**
+         * Properties of a FileInfo.
+         * @memberof RichMedia
+         * @interface IFileInfo
+         * @property {number|null} [fileSize] FileInfo fileSize
+         * @property {string|null} [md5HexStr] FileInfo md5HexStr
+         * @property {string|null} [sha1HexStr] FileInfo sha1HexStr
+         * @property {string|null} [fileName] FileInfo fileName
+         * @property {RichMedia.IFileType|null} [fileType] FileInfo fileType
+         * @property {number|null} [width] FileInfo width
+         * @property {number|null} [height] FileInfo height
+         * @property {number|null} [time] FileInfo time
+         * @property {number|null} [original] FileInfo original
+         */
+
+        /**
+         * Constructs a new FileInfo.
+         * @memberof RichMedia
+         * @classdesc Represents a FileInfo.
+         * @implements IFileInfo
+         * @constructor
+         * @param {RichMedia.IFileInfo=} [properties] Properties to set
+         */
+        function FileInfo(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * FileInfo fileSize.
+         * @member {number} fileSize
+         * @memberof RichMedia.FileInfo
+         * @instance
+         */
+        FileInfo.prototype.fileSize = 0;
+
+        /**
+         * FileInfo md5HexStr.
+         * @member {string} md5HexStr
+         * @memberof RichMedia.FileInfo
+         * @instance
+         */
+        FileInfo.prototype.md5HexStr = "";
+
+        /**
+         * FileInfo sha1HexStr.
+         * @member {string} sha1HexStr
+         * @memberof RichMedia.FileInfo
+         * @instance
+         */
+        FileInfo.prototype.sha1HexStr = "";
+
+        /**
+         * FileInfo fileName.
+         * @member {string} fileName
+         * @memberof RichMedia.FileInfo
+         * @instance
+         */
+        FileInfo.prototype.fileName = "";
+
+        /**
+         * FileInfo fileType.
+         * @member {RichMedia.IFileType|null|undefined} fileType
+         * @memberof RichMedia.FileInfo
+         * @instance
+         */
+        FileInfo.prototype.fileType = null;
+
+        /**
+         * FileInfo width.
+         * @member {number} width
+         * @memberof RichMedia.FileInfo
+         * @instance
+         */
+        FileInfo.prototype.width = 0;
+
+        /**
+         * FileInfo height.
+         * @member {number} height
+         * @memberof RichMedia.FileInfo
+         * @instance
+         */
+        FileInfo.prototype.height = 0;
+
+        /**
+         * FileInfo time.
+         * @member {number} time
+         * @memberof RichMedia.FileInfo
+         * @instance
+         */
+        FileInfo.prototype.time = 0;
+
+        /**
+         * FileInfo original.
+         * @member {number} original
+         * @memberof RichMedia.FileInfo
+         * @instance
+         */
+        FileInfo.prototype.original = 0;
+
+        /**
+         * Encodes the specified FileInfo message. Does not implicitly {@link RichMedia.FileInfo.verify|verify} messages.
+         * @function encode
+         * @memberof RichMedia.FileInfo
+         * @static
+         * @param {RichMedia.IFileInfo} message FileInfo message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        FileInfo.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.fileSize != null && Object.hasOwnProperty.call(message, "fileSize"))
+                writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.fileSize);
+            if (message.md5HexStr != null && Object.hasOwnProperty.call(message, "md5HexStr"))
+                writer.uint32(/* id 2, wireType 2 =*/18).string(message.md5HexStr);
+            if (message.sha1HexStr != null && Object.hasOwnProperty.call(message, "sha1HexStr"))
+                writer.uint32(/* id 3, wireType 2 =*/26).string(message.sha1HexStr);
+            if (message.fileName != null && Object.hasOwnProperty.call(message, "fileName"))
+                writer.uint32(/* id 4, wireType 2 =*/34).string(message.fileName);
+            if (message.fileType != null && Object.hasOwnProperty.call(message, "fileType"))
+                $root.RichMedia.FileType.encode(message.fileType, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
+            if (message.width != null && Object.hasOwnProperty.call(message, "width"))
+                writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.width);
+            if (message.height != null && Object.hasOwnProperty.call(message, "height"))
+                writer.uint32(/* id 7, wireType 0 =*/56).uint32(message.height);
+            if (message.time != null && Object.hasOwnProperty.call(message, "time"))
+                writer.uint32(/* id 8, wireType 0 =*/64).uint32(message.time);
+            if (message.original != null && Object.hasOwnProperty.call(message, "original"))
+                writer.uint32(/* id 9, wireType 0 =*/72).uint32(message.original);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified FileInfo message, length delimited. Does not implicitly {@link RichMedia.FileInfo.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof RichMedia.FileInfo
+         * @static
+         * @param {RichMedia.IFileInfo} message FileInfo message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        FileInfo.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a FileInfo message from the specified reader or buffer.
+         * @function decode
+         * @memberof RichMedia.FileInfo
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {RichMedia.FileInfo} FileInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        FileInfo.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.RichMedia.FileInfo();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.fileSize = reader.uint32();
+                        break;
+                    }
+                case 2: {
+                        message.md5HexStr = reader.string();
+                        break;
+                    }
+                case 3: {
+                        message.sha1HexStr = reader.string();
+                        break;
+                    }
+                case 4: {
+                        message.fileName = reader.string();
+                        break;
+                    }
+                case 5: {
+                        message.fileType = $root.RichMedia.FileType.decode(reader, reader.uint32());
+                        break;
+                    }
+                case 6: {
+                        message.width = reader.uint32();
+                        break;
+                    }
+                case 7: {
+                        message.height = reader.uint32();
+                        break;
+                    }
+                case 8: {
+                        message.time = reader.uint32();
+                        break;
+                    }
+                case 9: {
+                        message.original = reader.uint32();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a FileInfo message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof RichMedia.FileInfo
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {RichMedia.FileInfo} FileInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        FileInfo.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for FileInfo
+         * @function getTypeUrl
+         * @memberof RichMedia.FileInfo
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        FileInfo.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/RichMedia.FileInfo";
+        };
+
+        return FileInfo;
+    })();
+
+    RichMedia.FileType = (function() {
+
+        /**
+         * Properties of a FileType.
+         * @memberof RichMedia
+         * @interface IFileType
+         * @property {number|null} [type] FileType type
+         * @property {number|null} [picFormat] FileType picFormat
+         * @property {number|null} [videoFormat] FileType videoFormat
+         * @property {number|null} [pttFormat] FileType pttFormat
+         */
+
+        /**
+         * Constructs a new FileType.
+         * @memberof RichMedia
+         * @classdesc Represents a FileType.
+         * @implements IFileType
+         * @constructor
+         * @param {RichMedia.IFileType=} [properties] Properties to set
+         */
+        function FileType(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * FileType type.
+         * @member {number} type
+         * @memberof RichMedia.FileType
+         * @instance
+         */
+        FileType.prototype.type = 0;
+
+        /**
+         * FileType picFormat.
+         * @member {number} picFormat
+         * @memberof RichMedia.FileType
+         * @instance
+         */
+        FileType.prototype.picFormat = 0;
+
+        /**
+         * FileType videoFormat.
+         * @member {number} videoFormat
+         * @memberof RichMedia.FileType
+         * @instance
+         */
+        FileType.prototype.videoFormat = 0;
+
+        /**
+         * FileType pttFormat.
+         * @member {number} pttFormat
+         * @memberof RichMedia.FileType
+         * @instance
+         */
+        FileType.prototype.pttFormat = 0;
+
+        /**
+         * Encodes the specified FileType message. Does not implicitly {@link RichMedia.FileType.verify|verify} messages.
+         * @function encode
+         * @memberof RichMedia.FileType
+         * @static
+         * @param {RichMedia.IFileType} message FileType message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        FileType.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.type != null && Object.hasOwnProperty.call(message, "type"))
+                writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.type);
+            if (message.picFormat != null && Object.hasOwnProperty.call(message, "picFormat"))
+                writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.picFormat);
+            if (message.videoFormat != null && Object.hasOwnProperty.call(message, "videoFormat"))
+                writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.videoFormat);
+            if (message.pttFormat != null && Object.hasOwnProperty.call(message, "pttFormat"))
+                writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.pttFormat);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified FileType message, length delimited. Does not implicitly {@link RichMedia.FileType.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof RichMedia.FileType
+         * @static
+         * @param {RichMedia.IFileType} message FileType message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        FileType.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a FileType message from the specified reader or buffer.
+         * @function decode
+         * @memberof RichMedia.FileType
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {RichMedia.FileType} FileType
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        FileType.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.RichMedia.FileType();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.type = reader.uint32();
+                        break;
+                    }
+                case 2: {
+                        message.picFormat = reader.uint32();
+                        break;
+                    }
+                case 3: {
+                        message.videoFormat = reader.uint32();
+                        break;
+                    }
+                case 4: {
+                        message.pttFormat = reader.uint32();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a FileType message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof RichMedia.FileType
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {RichMedia.FileType} FileType
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        FileType.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for FileType
+         * @function getTypeUrl
+         * @memberof RichMedia.FileType
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        FileType.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/RichMedia.FileType";
+        };
+
+        return FileType;
+    })();
+
+    RichMedia.PicInfo = (function() {
+
+        /**
+         * Properties of a PicInfo.
+         * @memberof RichMedia
+         * @interface IPicInfo
+         * @property {string|null} [urlPath] PicInfo urlPath
+         * @property {RichMedia.IPicUrlExtParams|null} [ext] PicInfo ext
+         * @property {string|null} [domain] PicInfo domain
+         */
+
+        /**
+         * Constructs a new PicInfo.
+         * @memberof RichMedia
+         * @classdesc Represents a PicInfo.
+         * @implements IPicInfo
+         * @constructor
+         * @param {RichMedia.IPicInfo=} [properties] Properties to set
+         */
+        function PicInfo(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * PicInfo urlPath.
+         * @member {string} urlPath
+         * @memberof RichMedia.PicInfo
+         * @instance
+         */
+        PicInfo.prototype.urlPath = "";
+
+        /**
+         * PicInfo ext.
+         * @member {RichMedia.IPicUrlExtParams|null|undefined} ext
+         * @memberof RichMedia.PicInfo
+         * @instance
+         */
+        PicInfo.prototype.ext = null;
+
+        /**
+         * PicInfo domain.
+         * @member {string} domain
+         * @memberof RichMedia.PicInfo
+         * @instance
+         */
+        PicInfo.prototype.domain = "";
+
+        /**
+         * Encodes the specified PicInfo message. Does not implicitly {@link RichMedia.PicInfo.verify|verify} messages.
+         * @function encode
+         * @memberof RichMedia.PicInfo
+         * @static
+         * @param {RichMedia.IPicInfo} message PicInfo message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        PicInfo.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.urlPath != null && Object.hasOwnProperty.call(message, "urlPath"))
+                writer.uint32(/* id 1, wireType 2 =*/10).string(message.urlPath);
+            if (message.ext != null && Object.hasOwnProperty.call(message, "ext"))
+                $root.RichMedia.PicUrlExtParams.encode(message.ext, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
+            if (message.domain != null && Object.hasOwnProperty.call(message, "domain"))
+                writer.uint32(/* id 3, wireType 2 =*/26).string(message.domain);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified PicInfo message, length delimited. Does not implicitly {@link RichMedia.PicInfo.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof RichMedia.PicInfo
+         * @static
+         * @param {RichMedia.IPicInfo} message PicInfo message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        PicInfo.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a PicInfo message from the specified reader or buffer.
+         * @function decode
+         * @memberof RichMedia.PicInfo
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {RichMedia.PicInfo} PicInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        PicInfo.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.RichMedia.PicInfo();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.urlPath = reader.string();
+                        break;
+                    }
+                case 2: {
+                        message.ext = $root.RichMedia.PicUrlExtParams.decode(reader, reader.uint32());
+                        break;
+                    }
+                case 3: {
+                        message.domain = reader.string();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a PicInfo message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof RichMedia.PicInfo
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {RichMedia.PicInfo} PicInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        PicInfo.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for PicInfo
+         * @function getTypeUrl
+         * @memberof RichMedia.PicInfo
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        PicInfo.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/RichMedia.PicInfo";
+        };
+
+        return PicInfo;
+    })();
+
+    RichMedia.PicUrlExtParams = (function() {
+
+        /**
+         * Properties of a PicUrlExtParams.
+         * @memberof RichMedia
+         * @interface IPicUrlExtParams
+         * @property {string|null} [originalParam] PicUrlExtParams originalParam
+         * @property {string|null} [bigParam] PicUrlExtParams bigParam
+         * @property {string|null} [thumbParam] PicUrlExtParams thumbParam
+         */
+
+        /**
+         * Constructs a new PicUrlExtParams.
+         * @memberof RichMedia
+         * @classdesc Represents a PicUrlExtParams.
+         * @implements IPicUrlExtParams
+         * @constructor
+         * @param {RichMedia.IPicUrlExtParams=} [properties] Properties to set
+         */
+        function PicUrlExtParams(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * PicUrlExtParams originalParam.
+         * @member {string} originalParam
+         * @memberof RichMedia.PicUrlExtParams
+         * @instance
+         */
+        PicUrlExtParams.prototype.originalParam = "";
+
+        /**
+         * PicUrlExtParams bigParam.
+         * @member {string} bigParam
+         * @memberof RichMedia.PicUrlExtParams
+         * @instance
+         */
+        PicUrlExtParams.prototype.bigParam = "";
+
+        /**
+         * PicUrlExtParams thumbParam.
+         * @member {string} thumbParam
+         * @memberof RichMedia.PicUrlExtParams
+         * @instance
+         */
+        PicUrlExtParams.prototype.thumbParam = "";
+
+        /**
+         * Encodes the specified PicUrlExtParams message. Does not implicitly {@link RichMedia.PicUrlExtParams.verify|verify} messages.
+         * @function encode
+         * @memberof RichMedia.PicUrlExtParams
+         * @static
+         * @param {RichMedia.IPicUrlExtParams} message PicUrlExtParams message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        PicUrlExtParams.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.originalParam != null && Object.hasOwnProperty.call(message, "originalParam"))
+                writer.uint32(/* id 1, wireType 2 =*/10).string(message.originalParam);
+            if (message.bigParam != null && Object.hasOwnProperty.call(message, "bigParam"))
+                writer.uint32(/* id 2, wireType 2 =*/18).string(message.bigParam);
+            if (message.thumbParam != null && Object.hasOwnProperty.call(message, "thumbParam"))
+                writer.uint32(/* id 3, wireType 2 =*/26).string(message.thumbParam);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified PicUrlExtParams message, length delimited. Does not implicitly {@link RichMedia.PicUrlExtParams.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof RichMedia.PicUrlExtParams
+         * @static
+         * @param {RichMedia.IPicUrlExtParams} message PicUrlExtParams message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        PicUrlExtParams.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a PicUrlExtParams message from the specified reader or buffer.
+         * @function decode
+         * @memberof RichMedia.PicUrlExtParams
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {RichMedia.PicUrlExtParams} PicUrlExtParams
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        PicUrlExtParams.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.RichMedia.PicUrlExtParams();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.originalParam = reader.string();
+                        break;
+                    }
+                case 2: {
+                        message.bigParam = reader.string();
+                        break;
+                    }
+                case 3: {
+                        message.thumbParam = reader.string();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a PicUrlExtParams message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof RichMedia.PicUrlExtParams
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {RichMedia.PicUrlExtParams} PicUrlExtParams
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        PicUrlExtParams.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for PicUrlExtParams
+         * @function getTypeUrl
+         * @memberof RichMedia.PicUrlExtParams
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        PicUrlExtParams.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/RichMedia.PicUrlExtParams";
+        };
+
+        return PicUrlExtParams;
+    })();
+
+    RichMedia.ExtBizInfo = (function() {
+
+        /**
+         * Properties of an ExtBizInfo.
+         * @memberof RichMedia
+         * @interface IExtBizInfo
+         * @property {RichMedia.IPicExtBizInfo|null} [pic] ExtBizInfo pic
+         * @property {RichMedia.IVideoExtBizInfo|null} [video] ExtBizInfo video
+         * @property {number|null} [busiType] ExtBizInfo busiType
+         */
+
+        /**
+         * Constructs a new ExtBizInfo.
+         * @memberof RichMedia
+         * @classdesc Represents an ExtBizInfo.
+         * @implements IExtBizInfo
+         * @constructor
+         * @param {RichMedia.IExtBizInfo=} [properties] Properties to set
+         */
+        function ExtBizInfo(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * ExtBizInfo pic.
+         * @member {RichMedia.IPicExtBizInfo|null|undefined} pic
+         * @memberof RichMedia.ExtBizInfo
+         * @instance
+         */
+        ExtBizInfo.prototype.pic = null;
+
+        /**
+         * ExtBizInfo video.
+         * @member {RichMedia.IVideoExtBizInfo|null|undefined} video
+         * @memberof RichMedia.ExtBizInfo
+         * @instance
+         */
+        ExtBizInfo.prototype.video = null;
+
+        /**
+         * ExtBizInfo busiType.
+         * @member {number} busiType
+         * @memberof RichMedia.ExtBizInfo
+         * @instance
+         */
+        ExtBizInfo.prototype.busiType = 0;
+
+        /**
+         * Encodes the specified ExtBizInfo message. Does not implicitly {@link RichMedia.ExtBizInfo.verify|verify} messages.
+         * @function encode
+         * @memberof RichMedia.ExtBizInfo
+         * @static
+         * @param {RichMedia.IExtBizInfo} message ExtBizInfo message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        ExtBizInfo.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.pic != null && Object.hasOwnProperty.call(message, "pic"))
+                $root.RichMedia.PicExtBizInfo.encode(message.pic, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
+            if (message.video != null && Object.hasOwnProperty.call(message, "video"))
+                $root.RichMedia.VideoExtBizInfo.encode(message.video, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
+            if (message.busiType != null && Object.hasOwnProperty.call(message, "busiType"))
+                writer.uint32(/* id 10, wireType 0 =*/80).uint32(message.busiType);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified ExtBizInfo message, length delimited. Does not implicitly {@link RichMedia.ExtBizInfo.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof RichMedia.ExtBizInfo
+         * @static
+         * @param {RichMedia.IExtBizInfo} message ExtBizInfo message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        ExtBizInfo.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes an ExtBizInfo message from the specified reader or buffer.
+         * @function decode
+         * @memberof RichMedia.ExtBizInfo
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {RichMedia.ExtBizInfo} ExtBizInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        ExtBizInfo.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.RichMedia.ExtBizInfo();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.pic = $root.RichMedia.PicExtBizInfo.decode(reader, reader.uint32());
+                        break;
+                    }
+                case 2: {
+                        message.video = $root.RichMedia.VideoExtBizInfo.decode(reader, reader.uint32());
+                        break;
+                    }
+                case 10: {
+                        message.busiType = reader.uint32();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes an ExtBizInfo message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof RichMedia.ExtBizInfo
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {RichMedia.ExtBizInfo} ExtBizInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        ExtBizInfo.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for ExtBizInfo
+         * @function getTypeUrl
+         * @memberof RichMedia.ExtBizInfo
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        ExtBizInfo.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/RichMedia.ExtBizInfo";
+        };
+
+        return ExtBizInfo;
+    })();
+
+    RichMedia.PicExtBizInfo = (function() {
+
+        /**
+         * Properties of a PicExtBizInfo.
+         * @memberof RichMedia
+         * @interface IPicExtBizInfo
+         * @property {number|null} [bizType] PicExtBizInfo bizType
+         * @property {string|null} [summary] PicExtBizInfo summary
+         */
+
+        /**
+         * Constructs a new PicExtBizInfo.
+         * @memberof RichMedia
+         * @classdesc Represents a PicExtBizInfo.
+         * @implements IPicExtBizInfo
+         * @constructor
+         * @param {RichMedia.IPicExtBizInfo=} [properties] Properties to set
+         */
+        function PicExtBizInfo(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * PicExtBizInfo bizType.
+         * @member {number} bizType
+         * @memberof RichMedia.PicExtBizInfo
+         * @instance
+         */
+        PicExtBizInfo.prototype.bizType = 0;
+
+        /**
+         * PicExtBizInfo summary.
+         * @member {string} summary
+         * @memberof RichMedia.PicExtBizInfo
+         * @instance
+         */
+        PicExtBizInfo.prototype.summary = "";
+
+        /**
+         * Encodes the specified PicExtBizInfo message. Does not implicitly {@link RichMedia.PicExtBizInfo.verify|verify} messages.
+         * @function encode
+         * @memberof RichMedia.PicExtBizInfo
+         * @static
+         * @param {RichMedia.IPicExtBizInfo} message PicExtBizInfo message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        PicExtBizInfo.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.bizType != null && Object.hasOwnProperty.call(message, "bizType"))
+                writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.bizType);
+            if (message.summary != null && Object.hasOwnProperty.call(message, "summary"))
+                writer.uint32(/* id 2, wireType 2 =*/18).string(message.summary);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified PicExtBizInfo message, length delimited. Does not implicitly {@link RichMedia.PicExtBizInfo.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof RichMedia.PicExtBizInfo
+         * @static
+         * @param {RichMedia.IPicExtBizInfo} message PicExtBizInfo message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        PicExtBizInfo.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a PicExtBizInfo message from the specified reader or buffer.
+         * @function decode
+         * @memberof RichMedia.PicExtBizInfo
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {RichMedia.PicExtBizInfo} PicExtBizInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        PicExtBizInfo.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.RichMedia.PicExtBizInfo();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1: {
+                        message.bizType = reader.uint32();
+                        break;
+                    }
+                case 2: {
+                        message.summary = reader.string();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a PicExtBizInfo message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof RichMedia.PicExtBizInfo
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {RichMedia.PicExtBizInfo} PicExtBizInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        PicExtBizInfo.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for PicExtBizInfo
+         * @function getTypeUrl
+         * @memberof RichMedia.PicExtBizInfo
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        PicExtBizInfo.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/RichMedia.PicExtBizInfo";
+        };
+
+        return PicExtBizInfo;
+    })();
+
+    RichMedia.VideoExtBizInfo = (function() {
+
+        /**
+         * Properties of a VideoExtBizInfo.
+         * @memberof RichMedia
+         * @interface IVideoExtBizInfo
+         * @property {Uint8Array|null} [pbReserve] VideoExtBizInfo pbReserve
+         */
+
+        /**
+         * Constructs a new VideoExtBizInfo.
+         * @memberof RichMedia
+         * @classdesc Represents a VideoExtBizInfo.
+         * @implements IVideoExtBizInfo
+         * @constructor
+         * @param {RichMedia.IVideoExtBizInfo=} [properties] Properties to set
+         */
+        function VideoExtBizInfo(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * VideoExtBizInfo pbReserve.
+         * @member {Uint8Array} pbReserve
+         * @memberof RichMedia.VideoExtBizInfo
+         * @instance
+         */
+        VideoExtBizInfo.prototype.pbReserve = $util.newBuffer([]);
+
+        /**
+         * Encodes the specified VideoExtBizInfo message. Does not implicitly {@link RichMedia.VideoExtBizInfo.verify|verify} messages.
+         * @function encode
+         * @memberof RichMedia.VideoExtBizInfo
+         * @static
+         * @param {RichMedia.IVideoExtBizInfo} message VideoExtBizInfo message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        VideoExtBizInfo.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.pbReserve != null && Object.hasOwnProperty.call(message, "pbReserve"))
+                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.pbReserve);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified VideoExtBizInfo message, length delimited. Does not implicitly {@link RichMedia.VideoExtBizInfo.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof RichMedia.VideoExtBizInfo
+         * @static
+         * @param {RichMedia.IVideoExtBizInfo} message VideoExtBizInfo message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        VideoExtBizInfo.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a VideoExtBizInfo message from the specified reader or buffer.
+         * @function decode
+         * @memberof RichMedia.VideoExtBizInfo
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {RichMedia.VideoExtBizInfo} VideoExtBizInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        VideoExtBizInfo.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.RichMedia.VideoExtBizInfo();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 3: {
+                        message.pbReserve = reader.bytes();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a VideoExtBizInfo message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof RichMedia.VideoExtBizInfo
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {RichMedia.VideoExtBizInfo} VideoExtBizInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        VideoExtBizInfo.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for VideoExtBizInfo
+         * @function getTypeUrl
+         * @memberof RichMedia.VideoExtBizInfo
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        VideoExtBizInfo.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/RichMedia.VideoExtBizInfo";
+        };
+
+        return VideoExtBizInfo;
+    })();
+
+    RichMedia.PicFileIdInfo = (function() {
+
+        /**
+         * Properties of a PicFileIdInfo.
+         * @memberof RichMedia
+         * @interface IPicFileIdInfo
+         * @property {Uint8Array|null} [sha1] PicFileIdInfo sha1
+         * @property {number|null} [size] PicFileIdInfo size
+         * @property {number|null} [appid] PicFileIdInfo appid
+         * @property {number|null} [time] PicFileIdInfo time
+         * @property {number|null} [expire] PicFileIdInfo expire
+         */
+
+        /**
+         * Constructs a new PicFileIdInfo.
+         * @memberof RichMedia
+         * @classdesc Represents a PicFileIdInfo.
+         * @implements IPicFileIdInfo
+         * @constructor
+         * @param {RichMedia.IPicFileIdInfo=} [properties] Properties to set
+         */
+        function PicFileIdInfo(properties) {
+            if (properties)
+                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * PicFileIdInfo sha1.
+         * @member {Uint8Array} sha1
+         * @memberof RichMedia.PicFileIdInfo
+         * @instance
+         */
+        PicFileIdInfo.prototype.sha1 = $util.newBuffer([]);
+
+        /**
+         * PicFileIdInfo size.
+         * @member {number} size
+         * @memberof RichMedia.PicFileIdInfo
+         * @instance
+         */
+        PicFileIdInfo.prototype.size = 0;
+
+        /**
+         * PicFileIdInfo appid.
+         * @member {number} appid
+         * @memberof RichMedia.PicFileIdInfo
+         * @instance
+         */
+        PicFileIdInfo.prototype.appid = 0;
+
+        /**
+         * PicFileIdInfo time.
+         * @member {number} time
+         * @memberof RichMedia.PicFileIdInfo
+         * @instance
+         */
+        PicFileIdInfo.prototype.time = 0;
+
+        /**
+         * PicFileIdInfo expire.
+         * @member {number} expire
+         * @memberof RichMedia.PicFileIdInfo
+         * @instance
+         */
+        PicFileIdInfo.prototype.expire = 0;
+
+        /**
+         * Encodes the specified PicFileIdInfo message. Does not implicitly {@link RichMedia.PicFileIdInfo.verify|verify} messages.
+         * @function encode
+         * @memberof RichMedia.PicFileIdInfo
+         * @static
+         * @param {RichMedia.IPicFileIdInfo} message PicFileIdInfo message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        PicFileIdInfo.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.sha1 != null && Object.hasOwnProperty.call(message, "sha1"))
+                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.sha1);
+            if (message.size != null && Object.hasOwnProperty.call(message, "size"))
+                writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.size);
+            if (message.appid != null && Object.hasOwnProperty.call(message, "appid"))
+                writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.appid);
+            if (message.time != null && Object.hasOwnProperty.call(message, "time"))
+                writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.time);
+            if (message.expire != null && Object.hasOwnProperty.call(message, "expire"))
+                writer.uint32(/* id 10, wireType 0 =*/80).uint32(message.expire);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified PicFileIdInfo message, length delimited. Does not implicitly {@link RichMedia.PicFileIdInfo.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof RichMedia.PicFileIdInfo
+         * @static
+         * @param {RichMedia.IPicFileIdInfo} message PicFileIdInfo message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        PicFileIdInfo.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes a PicFileIdInfo message from the specified reader or buffer.
+         * @function decode
+         * @memberof RichMedia.PicFileIdInfo
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {RichMedia.PicFileIdInfo} PicFileIdInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        PicFileIdInfo.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.RichMedia.PicFileIdInfo();
+            while (reader.pos < end) {
+                let tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 2: {
+                        message.sha1 = reader.bytes();
+                        break;
+                    }
+                case 3: {
+                        message.size = reader.uint32();
+                        break;
+                    }
+                case 4: {
+                        message.appid = reader.uint32();
+                        break;
+                    }
+                case 5: {
+                        message.time = reader.uint32();
+                        break;
+                    }
+                case 10: {
+                        message.expire = reader.uint32();
+                        break;
+                    }
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes a PicFileIdInfo message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof RichMedia.PicFileIdInfo
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {RichMedia.PicFileIdInfo} PicFileIdInfo
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        PicFileIdInfo.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Gets the default type url for PicFileIdInfo
+         * @function getTypeUrl
+         * @memberof RichMedia.PicFileIdInfo
+         * @static
+         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
+         * @returns {string} The default type url
+         */
+        PicFileIdInfo.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
+            if (typeUrlPrefix === undefined) {
+                typeUrlPrefix = "type.googleapis.com";
+            }
+            return typeUrlPrefix + "/RichMedia.PicFileIdInfo";
+        };
+
+        return PicFileIdInfo;
+    })();
+
+    return RichMedia;
+})();
+
 export { $root as default };
diff --git a/src/ntqqapi/proto/message.proto b/src/ntqqapi/proto/message.proto
new file mode 100644
index 0000000..5434f71
--- /dev/null
+++ b/src/ntqqapi/proto/message.proto
@@ -0,0 +1,134 @@
+syntax = "proto3";
+package Msg;
+
+message RoutingHead {
+  optional uint64 fromUin = 1;
+  optional string fromUid = 2;
+  optional uint32 fromAppid = 3;
+  optional uint32 fromInstid = 4;
+  optional uint64 toUin = 5;
+  optional string toUid = 6;
+  optional C2c c2c = 7;
+  optional Group group = 8;
+}
+
+message C2c {
+  optional string friendName = 6;
+}
+
+message Group {
+  optional uint64 groupCode = 1;
+  optional uint32 groupType = 2;
+  optional uint64 groupInfoSeq = 3;
+  optional string groupCard = 4;
+  optional uint32 groupCardType = 5;
+  optional uint32 groupLevel = 6;
+  optional string groupName = 7;
+  optional string extGroupKeyInfo = 8;
+  optional uint32 msgFlag = 9;
+}
+
+message ContentHead {
+  optional uint64 msgType = 1;
+  optional uint64 subType = 2;
+  optional uint32 c2cCmd = 3;
+  optional uint64 random = 4;
+  optional uint64 msgSeq = 5;
+  optional uint64 msgTime = 6;
+  optional uint32 pkgNum = 7;
+  optional uint32 pkgIndex = 8;
+  optional uint32 divSeq = 9;
+  optional uint32 autoReply = 10;
+  optional uint64 ntMsgSeq = 11;
+  optional uint64 msgUid = 12;
+  optional ContentHeadField15 field15 = 15;
+}
+
+message ContentHeadField15 {
+  optional uint32 field1 = 1;
+  optional uint32 field2 = 2;
+  optional uint32 field3 = 3;
+  optional string field4 = 4;
+  optional string field5 = 5;
+}
+
+message Message {
+  optional RoutingHead routingHead = 1;
+  optional ContentHead contentHead = 2;
+  optional MessageBody body = 3;
+}
+
+message MessageBody {
+  optional RichText richText = 1;
+  optional bytes msgContent = 2;
+  optional bytes msgEncryptContent = 3;
+}
+
+message RichText {
+  optional Attr attr = 1;
+  repeated Elem elems = 2;
+}
+
+message Elem {
+  optional Text text = 1;
+  optional Face face = 2;
+  optional LightAppElem lightApp = 51;
+  optional CommonElem commonElem = 53;
+}
+
+message Text {
+  optional string str = 1;
+  optional string link = 2;
+  optional bytes attr6Buf = 3;
+  optional bytes attr7Buf = 4;
+  optional bytes buf = 11;
+  optional bytes pbReserve = 12;
+}
+
+message Face {
+  optional uint32 index = 1;
+  optional bytes old = 2;
+  optional bytes buf = 11;
+}
+
+message LightAppElem {
+  optional bytes data = 1;
+  optional bytes msgResid = 2;
+}
+
+message CommonElem {
+  required uint32 serviceType = 1;
+  optional bytes pbElem = 2;
+  optional uint32 businessType = 3;
+}
+
+message Attr {
+  optional int32 codePage = 1;
+  optional int32 time = 2;
+  optional int32 random = 3;
+  optional int32 color = 4;
+  optional int32 size = 5;
+  optional int32 effect = 6;
+  optional int32 charSet = 7;
+  optional int32 pitchAndFamily = 8;
+  optional string fontName = 9;
+  optional bytes reserveData = 10;
+}
+
+message MarkdownElem {
+  string content = 1;
+}
+
+message PbMultiMsgItem {
+  string fileName = 1;
+  PbMultiMsgNew buffer = 2;
+}
+
+message PbMultiMsgNew {
+  repeated Message msg = 1;
+}
+
+message PbMultiMsgTransmit {
+  repeated Message msg = 1;
+  repeated PbMultiMsgItem pbItemList = 2;
+}
diff --git a/src/ntqqapi/proto/richMedia.proto b/src/ntqqapi/proto/richMedia.proto
new file mode 100644
index 0000000..94be8ec
--- /dev/null
+++ b/src/ntqqapi/proto/richMedia.proto
@@ -0,0 +1,76 @@
+syntax = "proto3";
+package RichMedia;
+
+message MsgInfo {
+  repeated MsgInfoBody msgInfoBody = 1;
+  ExtBizInfo extBizInfo = 2;
+}
+
+message MsgInfoBody {
+  IndexNode index = 1;
+  PicInfo pic = 2;
+  bool fileExist = 5;
+}
+
+message IndexNode {
+  FileInfo info = 1;
+  string fileUuid = 2;
+  uint32 storeID = 3;
+  uint32 uploadTime = 4;
+  uint32 expire = 5;
+  uint32 type = 6; //0
+}
+
+message FileInfo {
+  uint32 fileSize = 1;
+  string md5HexStr = 2;
+  string sha1HexStr = 3;
+  string fileName = 4;
+  FileType fileType = 5;
+  uint32 width = 6;
+  uint32 height = 7;
+  uint32 time = 8;
+  uint32 original = 9;
+}
+
+message FileType {
+  uint32 type = 1;
+  uint32 picFormat = 2;
+  uint32 videoFormat = 3;
+  uint32 pttFormat = 4;
+}
+
+message PicInfo {
+  string urlPath = 1;
+  PicUrlExtParams ext = 2;
+  string domain = 3;
+}
+
+message PicUrlExtParams {
+  string originalParam = 1;
+  string bigParam = 2;
+  string thumbParam = 3;
+}
+
+message ExtBizInfo {
+  PicExtBizInfo pic = 1;
+  VideoExtBizInfo video = 2;
+  uint32 busiType = 10;
+}
+
+message PicExtBizInfo {
+  uint32 bizType = 1;
+  string summary = 2;
+}
+
+message VideoExtBizInfo {
+  bytes pbReserve = 3;
+}
+
+message PicFileIdInfo {
+  bytes sha1 = 2;
+  uint32 size = 3;
+  uint32 appid = 4;
+  uint32 time = 5;
+  uint32 expire = 10;
+}
diff --git a/src/ntqqapi/proto/systemMessage.proto b/src/ntqqapi/proto/systemMessage.proto
deleted file mode 100644
index 13cdb9b..0000000
--- a/src/ntqqapi/proto/systemMessage.proto
+++ /dev/null
@@ -1,29 +0,0 @@
-syntax = "proto3";
-package SysMsg;
-
-message SystemMessage {
-  repeated SystemMessageHeader header = 1;
-  repeated SystemMessageMsgSpec msgSpec = 2;
-  SystemMessageBodyWrapper bodyWrapper = 3;
-}
-
-message SystemMessageHeader {
-  uint32 peerUin = 1;
-  //string peerUid = 2;
-  uint32 uin = 5;
-  optional string uid = 6;
-}
-
-message SystemMessageMsgSpec {
-  uint32 msgType = 1;
-  optional uint32 subType = 2;
-  optional uint32 subSubType = 3;
-  uint32 msgSeq = 5;
-  uint32 time = 6;
-  //uint64 msgId = 12;
-  optional uint32 other = 13;
-}
-
-message SystemMessageBodyWrapper {
-  bytes body = 2;
-}
diff --git a/src/ntqqapi/types/msg.ts b/src/ntqqapi/types/msg.ts
index 8f1ba94..d01f4e7 100644
--- a/src/ntqqapi/types/msg.ts
+++ b/src/ntqqapi/types/msg.ts
@@ -80,7 +80,7 @@ export interface SendVideoElement {
 export interface SendArkElement {
   elementType: ElementType.Ark
   elementId: ''
-  arkElement: ArkElement
+  arkElement: Partial<ArkElement>
 }
 
 export type SendMessageElement =
@@ -587,3 +587,31 @@ export interface GetFileListParam {
   showOnlinedocFolder: number
   folderId?: string
 }
+
+export interface RichMediaUploadCompleteNotify {
+  fileId: string
+  fileDownType: number
+  filePath: string
+  totalSize: string
+  trasferStatus: number
+  commonFileInfo: {
+    uuid: string
+    fileName: string
+    fileSize: string
+    md5: string
+    sha: string
+  }
+}
+
+export enum RMBizType {
+  Unknown,
+  C2CFile,
+  GroupFile,
+  C2CPic,
+  GroupPic,
+  DiscPic,
+  C2CVideo,
+  GroupVideo,
+  C2CPtt,
+  GroupPtt,
+}
diff --git a/src/onebot11/action/go-cqhttp/SendForwardMsg.ts b/src/onebot11/action/go-cqhttp/SendForwardMsg.ts
index d4f184f..818ba42 100644
--- a/src/onebot11/action/go-cqhttp/SendForwardMsg.ts
+++ b/src/onebot11/action/go-cqhttp/SendForwardMsg.ts
@@ -1,11 +1,13 @@
 import { unlink } from 'node:fs/promises'
-import { OB11MessageNode } from '../../types'
+import { OB11MessageData, OB11MessageNode } from '../../types'
 import { ActionName } from '../types'
 import { BaseAction, Schema } from '../BaseAction'
 import { Peer } from '@/ntqqapi/types/msg'
 import { ChatType, ElementType, RawMessage, SendMessageElement } from '@/ntqqapi/types'
 import { selfInfo } from '@/common/globalVars'
-import { convertMessage2List, createSendElements, sendMsg, createPeer, CreatePeerMode } from '../../helper/createMessage'
+import { message2List, createSendElements, sendMsg, createPeer, CreatePeerMode } from '../../helper/createMessage'
+import { MessageEncoder } from '@/onebot11/helper/createMultiMessage'
+import { Msg } from '@/ntqqapi/proto/compiled'
 
 interface Payload {
   user_id?: string | number
@@ -42,11 +44,91 @@ export class SendForwardMsg extends BaseAction<Payload, Response> {
       contextMode = CreatePeerMode.Private
     }
     const peer = await createPeer(this.ctx, payload, contextMode)
-    const msg = await this.handleForwardNode(peer, messages)
+
+    const nodes = this.parseNodeContent(messages)
+    let fake = true
+    for (const node of nodes) {
+      if (node.data.id) {
+        fake = false
+        break
+      }
+      if (node.data.content?.some(e => {
+        return !MessageEncoder.support.includes(e.type)
+      })) {
+        fake = false
+        break
+      }
+    }
+
+    let msg: RawMessage
+    if (fake && this.ctx.app.native.activated) {
+      msg = await this.handleFakeForwardNode(peer, nodes)
+    } else {
+      msg = await this.handleForwardNode(peer, nodes)
+    }
     const msgShortId = this.ctx.store.createMsgShortId({ chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId)
     return { message_id: msgShortId }
   }
 
+  private parseNodeContent(nodes: OB11MessageNode[]) {
+    return nodes.map(e => {
+      return {
+        type: e.type,
+        data: {
+          ...e.data,
+          content: e.data.content ? message2List(e.data.content) : undefined
+        }
+      }
+    })
+  }
+
+  private async handleFakeForwardNode(peer: Peer, nodes: OB11MessageNode[]) {
+    const encoder = new MessageEncoder(this.ctx, peer)
+    const raw = await encoder.generate(nodes)
+    const transmit = Msg.PbMultiMsgTransmit.encode({ pbItemList: raw.multiMsgItems }).finish()
+    const resid = await this.ctx.app.native.uploadForward(peer, transmit.subarray(1))
+    const uuid = crypto.randomUUID()
+    try {
+      const msg = await this.ctx.ntMsgApi.sendMsg(peer, [{
+        elementType: 10,
+        elementId: '',
+        arkElement: {
+          bytesData: JSON.stringify({
+            app: 'com.tencent.multimsg',
+            config: {
+              autosize: 1,
+              forward: 1,
+              round: 1,
+              type: 'normal',
+              width: 300
+            },
+            desc: '[聊天记录]',
+            extra: JSON.stringify({
+              filename: uuid,
+              tsum: raw.tsum,
+            }),
+            meta: {
+              detail: {
+                news: raw.news,
+                resid,
+                source: raw.source,
+                summary: raw.summary,
+                uniseq: uuid,
+              }
+            },
+            prompt: '[聊天记录]',
+            ver: '0.0.0.5',
+            view: 'contact'
+          })
+        }
+      }], 1800)
+      return msg!
+    } catch (e) {
+      this.ctx.logger.error('合并转发失败', e)
+      throw new Error(`发送伪造合并转发消息失败 (res_id: ${resid} `)
+    }
+  }
+
   private async cloneMsg(msg: RawMessage): Promise<RawMessage | undefined> {
     this.ctx.logger.info('克隆的目标消息', msg)
     const sendElements: SendMessageElement[] = []
@@ -96,7 +178,7 @@ export class SendForwardMsg extends BaseAction<Payload, Response> {
         try {
           const { sendElements, deleteAfterSentFiles } = await createSendElements(
             this.ctx,
-            convertMessage2List(messageNode.data.content),
+            messageNode.data.content as OB11MessageData[],
             destPeer
           )
           this.ctx.logger.info('开始生成转发节点', sendElements)
diff --git a/src/onebot11/action/msg/SendMsg.ts b/src/onebot11/action/msg/SendMsg.ts
index 7e76de3..9499491 100644
--- a/src/onebot11/action/msg/SendMsg.ts
+++ b/src/onebot11/action/msg/SendMsg.ts
@@ -9,7 +9,7 @@ import {
 import { BaseAction } from '../BaseAction'
 import { ActionName } from '../types'
 import { CustomMusicSignPostData, IdMusicSignPostData, MusicSign, MusicSignPostData } from '@/common/utils/sign'
-import { convertMessage2List, createSendElements, sendMsg, createPeer, CreatePeerMode } from '../../helper/createMessage'
+import { message2List, createSendElements, sendMsg, createPeer, CreatePeerMode } from '../../helper/createMessage'
 
 interface ReturnData {
   message_id: number
@@ -26,14 +26,14 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnData> {
       contextMode = CreatePeerMode.Private
     }
     const peer = await createPeer(this.ctx, payload, contextMode)
-    const messages = convertMessage2List(
+    const messages = message2List(
       payload.message,
       payload.auto_escape === true || payload.auto_escape === 'true',
     )
-    if (this.getSpecialMsgNum(messages, OB11MessageDataType.node)) {
+    if (this.getSpecialMsgNum(messages, OB11MessageDataType.Node)) {
       throw new Error('请使用 /send_group_forward_msg 或 /send_private_forward_msg 进行合并转发')
     }
-    else if (this.getSpecialMsgNum(messages, OB11MessageDataType.music)) {
+    else if (this.getSpecialMsgNum(messages, OB11MessageDataType.Music)) {
       const music = messages[0] as OB11MessageMusic
       if (music) {
         const { musicSignUrl } = this.adapter.config
@@ -78,7 +78,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnData> {
           throw `签名音乐消息失败:${e}`
         }
         messages[0] = {
-          type: OB11MessageDataType.json,
+          type: OB11MessageDataType.Json,
           data: { data: jsonContent },
         } as OB11MessageJson
       }
diff --git a/src/onebot11/adapter.ts b/src/onebot11/adapter.ts
index d657116..763a516 100644
--- a/src/onebot11/adapter.ts
+++ b/src/onebot11/adapter.ts
@@ -22,7 +22,7 @@ import { initActionMap } from './action'
 import { llonebotError } from '../common/globalVars'
 import { OB11GroupAdminNoticeEvent } from './event/notice/OB11GroupAdminNoticeEvent'
 import { OB11ProfileLikeEvent } from './event/notice/OB11ProfileLikeEvent'
-import { SysMsg } from '@/ntqqapi/proto/compiled'
+import { Msg, SysMsg } from '@/ntqqapi/proto/compiled'
 import { OB11GroupIncreaseEvent } from './event/notice/OB11GroupIncreaseEvent'
 
 declare module 'cordis' {
@@ -351,10 +351,10 @@ class OneBot11Adapter extends Service {
       this.handleFriendRequest(input)
     })
     this.ctx.on('nt/system-message-created', async input => {
-      const sysMsg = SysMsg.SystemMessage.decode(input)
-      const { msgType, subType, subSubType } = sysMsg.msgSpec[0] ?? {}
-      if (msgType === 528 && subType === 39 && subSubType === 39) {
-        const tip = SysMsg.ProfileLikeTip.decode(sysMsg.bodyWrapper!.body!)
+      const sysMsg = Msg.Message.decode(input)
+      const { msgType, subType } = sysMsg.contentHead ?? {}
+      if (msgType === 528 && subType === 39) {
+        const tip = SysMsg.ProfileLikeTip.decode(sysMsg.body!.msgContent!)
         if (tip.msgType !== 0 || tip.subType !== 203) return
         const detail = tip.content?.msg?.detail
         if (!detail) return
@@ -362,7 +362,7 @@ class OneBot11Adapter extends Service {
         const event = new OB11ProfileLikeEvent(detail.uin!, detail.nickname!, +times)
         this.dispatch(event)
       } else if (msgType === 33) {
-        const tip = SysMsg.GroupMemberChange.decode(sysMsg.bodyWrapper!.body!)
+        const tip = SysMsg.GroupMemberChange.decode(sysMsg.body!.msgContent!)
         if (tip.type !== 130) return
         this.ctx.logger.info('群成员增加', tip)
         const memberUin = await this.ctx.ntUserApi.getUinByUid(tip.memberUid)
diff --git a/src/onebot11/entities.ts b/src/onebot11/entities.ts
index 24c9a2a..9e7a970 100644
--- a/src/onebot11/entities.ts
+++ b/src/onebot11/entities.ts
@@ -1,4 +1,3 @@
-import { XMLParser } from 'fast-xml-parser'
 import {
   OB11Group,
   OB11GroupMember,
@@ -122,7 +121,7 @@ export namespace OB11Entities {
           name = content.replace('@', '')
         }
         messageSegment = {
-          type: OB11MessageDataType.at,
+          type: OB11MessageDataType.At,
           data: {
             qq,
             name
@@ -135,7 +134,7 @@ export namespace OB11Entities {
           continue
         }
         messageSegment = {
-          type: OB11MessageDataType.text,
+          type: OB11MessageDataType.Text,
           data: {
             text
           }
@@ -171,7 +170,7 @@ export namespace OB11Entities {
             throw new Error('回复消息验证失败')
           }
           messageSegment = {
-            type: OB11MessageDataType.reply,
+            type: OB11MessageDataType.Reply,
             data: {
               id: ctx.store.createMsgShortId(peer, replyMsg ? replyMsg.msgId : records.msgId).toString()
             }
@@ -185,7 +184,7 @@ export namespace OB11Entities {
         const { picElement } = element
         const fileSize = picElement.fileSize ?? '0'
         messageSegment = {
-          type: OB11MessageDataType.image,
+          type: OB11MessageDataType.Image,
           data: {
             file: picElement.fileName,
             subType: picElement.picSubType,
@@ -213,7 +212,7 @@ export namespace OB11Entities {
         }, msg.msgId, element.elementId)
         const fileSize = videoElement.fileSize ?? '0'
         messageSegment = {
-          type: OB11MessageDataType.video,
+          type: OB11MessageDataType.Video,
           data: {
             file: videoElement.fileName,
             url: videoUrl || pathToFileURL(videoElement.filePath).href,
@@ -237,7 +236,7 @@ export namespace OB11Entities {
         const { fileElement } = element
         const fileSize = fileElement.fileSize ?? '0'
         messageSegment = {
-          type: OB11MessageDataType.file,
+          type: OB11MessageDataType.File,
           data: {
             file: fileElement.fileName,
             url: pathToFileURL(fileElement.filePath).href,
@@ -262,7 +261,7 @@ export namespace OB11Entities {
         const { pttElement } = element
         const fileSize = pttElement.fileSize ?? '0'
         messageSegment = {
-          type: OB11MessageDataType.voice,
+          type: OB11MessageDataType.Record,
           data: {
             file: pttElement.fileName,
             url: pathToFileURL(pttElement.filePath).href,
@@ -285,7 +284,7 @@ export namespace OB11Entities {
       else if (element.arkElement) {
         const { arkElement } = element
         messageSegment = {
-          type: OB11MessageDataType.json,
+          type: OB11MessageDataType.Json,
           data: {
             data: arkElement.bytesData
           }
@@ -296,14 +295,14 @@ export namespace OB11Entities {
         const { faceIndex, pokeType } = faceElement
         if (faceIndex === FaceIndex.Dice) {
           messageSegment = {
-            type: OB11MessageDataType.dice,
+            type: OB11MessageDataType.Dice,
             data: {
               result: faceElement.resultId!
             }
           }
         } else if (faceIndex === FaceIndex.RPS) {
           messageSegment = {
-            type: OB11MessageDataType.RPS,
+            type: OB11MessageDataType.Rps,
             data: {
               result: faceElement.resultId!
             }
@@ -315,7 +314,7 @@ export namespace OB11Entities {
             }*/
         } else {
           messageSegment = {
-            type: OB11MessageDataType.face,
+            type: OB11MessageDataType.Face,
             data: {
               id: faceIndex.toString()
             }
@@ -331,7 +330,7 @@ export namespace OB11Entities {
         // const url = `https://p.qpic.cn/CDN_STATIC/0/data/imgcache/htdocs/club/item/parcel/item/${dir}/${md5}/300x300.gif?max_age=31536000`
         const url = `https://gxh.vip.qq.com/club/item/parcel/item/${dir}/${emojiId}/raw300.gif`
         messageSegment = {
-          type: OB11MessageDataType.mface,
+          type: OB11MessageDataType.Mface,
           data: {
             summary: marketFaceElement.faceName!,
             url,
@@ -344,15 +343,15 @@ export namespace OB11Entities {
       else if (element.markdownElement) {
         const { markdownElement } = element
         messageSegment = {
-          type: OB11MessageDataType.markdown,
+          type: OB11MessageDataType.Markdown,
           data: {
-            data: markdownElement.content
+            content: markdownElement.content
           }
         }
       }
       else if (element.multiForwardMsgElement) {
         messageSegment = {
-          type: OB11MessageDataType.forward,
+          type: OB11MessageDataType.Forward,
           data: {
             id: msg.msgId
           }
@@ -491,31 +490,27 @@ export namespace OB11Entities {
         const xmlElement = grayTipElement.xmlElement
 
         if (xmlElement?.templId === '10382') {
-          const emojiLikeData = new XMLParser({
-            ignoreAttributes: false,
-            attributeNamePrefix: '',
-          }).parse(xmlElement.content)
-          ctx.logger.info('收到表情回应我的消息', emojiLikeData)
+          ctx.logger.info('收到表情回应我的消息', xmlElement.templParam)
           try {
-            const senderUin: string = emojiLikeData.gtip.qq.jp
-            const msgSeq: string = emojiLikeData.gtip.url.msgseq
-            const emojiId: string = emojiLikeData.gtip.face.id
+            const senderUin = xmlElement.templParam.get('jp_uin')
+            const msgSeq = xmlElement.templParam.get('msg_seq')
+            const emojiId = xmlElement.templParam.get('face_id')
             const peer = {
               chatType: ChatType.Group,
               guildId: '',
               peerUid: msg.peerUid,
             }
-            const replyMsgList = (await ctx.ntMsgApi.queryFirstMsgBySeq(peer, msgSeq)).msgList
+            const replyMsgList = (await ctx.ntMsgApi.queryFirstMsgBySeq(peer, msgSeq!)).msgList
             if (!replyMsgList?.length) {
               return
             }
             const shortId = ctx.store.createMsgShortId(peer, replyMsgList[0].msgId)
             return new OB11GroupMsgEmojiLikeEvent(
               parseInt(msg.peerUid),
-              parseInt(senderUin),
+              parseInt(senderUin!),
               shortId,
               [{
-                emoji_id: emojiId,
+                emoji_id: emojiId!,
                 count: 1,
               }]
             )
diff --git a/src/onebot11/helper/createMessage.ts b/src/onebot11/helper/createMessage.ts
index 39ae1a2..acbe92a 100644
--- a/src/onebot11/helper/createMessage.ts
+++ b/src/onebot11/helper/createMessage.ts
@@ -33,14 +33,14 @@ export async function createSendElements(
       continue
     }
     switch (sendMsg.type) {
-      case OB11MessageDataType.text: {
+      case OB11MessageDataType.Text: {
         const text = sendMsg.data?.text
         if (text) {
           sendElements.push(SendElement.text(sendMsg.data!.text))
         }
       }
         break
-      case OB11MessageDataType.at: {
+      case OB11MessageDataType.At: {
         if (!peer) {
           continue
         }
@@ -76,7 +76,7 @@ export async function createSendElements(
         }
       }
         break
-      case OB11MessageDataType.reply: {
+      case OB11MessageDataType.Reply: {
         if (sendMsg.data?.id) {
           const info = await ctx.store.getMsgInfoByShortId(+sendMsg.data.id)
           if (!info) {
@@ -90,14 +90,14 @@ export async function createSendElements(
         }
       }
         break
-      case OB11MessageDataType.face: {
+      case OB11MessageDataType.Face: {
         const faceId = sendMsg.data?.id
         if (faceId) {
           sendElements.push(SendElement.face(parseInt(faceId)))
         }
       }
         break
-      case OB11MessageDataType.mface: {
+      case OB11MessageDataType.Mface: {
         sendElements.push(
           SendElement.mface(
             +sendMsg.data.emoji_package_id,
@@ -108,10 +108,10 @@ export async function createSendElements(
         )
       }
         break
-      case OB11MessageDataType.image: {
+      case OB11MessageDataType.Image: {
         const res = await SendElement.pic(
           ctx,
-          (await handleOb11FileLikeMessage(ctx, sendMsg, { deleteAfterSentFiles })).path,
+          (await handleOb11RichMedia(ctx, sendMsg, deleteAfterSentFiles)).path,
           sendMsg.data.summary || '',
           sendMsg.data.subType || 0,
           sendMsg.data.type === 'flash'
@@ -120,13 +120,13 @@ export async function createSendElements(
         sendElements.push(res)
       }
         break
-      case OB11MessageDataType.file: {
-        const { path, fileName } = await handleOb11FileLikeMessage(ctx, sendMsg, { deleteAfterSentFiles })
+      case OB11MessageDataType.File: {
+        const { path, fileName } = await handleOb11RichMedia(ctx, sendMsg, deleteAfterSentFiles)
         sendElements.push(await SendElement.file(ctx, path, fileName))
       }
         break
-      case OB11MessageDataType.video: {
-        const { path, fileName } = await handleOb11FileLikeMessage(ctx, sendMsg, { deleteAfterSentFiles })
+      case OB11MessageDataType.Video: {
+        const { path, fileName } = await handleOb11RichMedia(ctx, sendMsg, deleteAfterSentFiles)
         let thumb = sendMsg.data.thumb
         if (thumb) {
           const uri2LocalRes = await uri2local(ctx, thumb)
@@ -137,32 +137,32 @@ export async function createSendElements(
         sendElements.push(res)
       }
         break
-      case OB11MessageDataType.voice: {
-        const { path } = await handleOb11FileLikeMessage(ctx, sendMsg, { deleteAfterSentFiles })
+      case OB11MessageDataType.Record: {
+        const { path } = await handleOb11RichMedia(ctx, sendMsg, deleteAfterSentFiles)
         sendElements.push(await SendElement.ptt(ctx, path))
       }
         break
-      case OB11MessageDataType.json: {
+      case OB11MessageDataType.Json: {
         sendElements.push(SendElement.ark(sendMsg.data.data))
       }
         break
-      case OB11MessageDataType.dice: {
+      case OB11MessageDataType.Dice: {
         const resultId = sendMsg.data?.result
         sendElements.push(SendElement.dice(resultId))
       }
         break
-      case OB11MessageDataType.RPS: {
+      case OB11MessageDataType.Rps: {
         const resultId = sendMsg.data?.result
         sendElements.push(SendElement.rps(resultId))
       }
         break
-      case OB11MessageDataType.contact: {
+      case OB11MessageDataType.Contact: {
         const { type, id } = sendMsg.data
         const data = type === 'qq' ? ctx.ntFriendApi.getBuddyRecommendContact(id) : ctx.ntGroupApi.getGroupRecommendContact(id)
         sendElements.push(SendElement.ark(await data))
       }
         break
-      case OB11MessageDataType.shake: {
+      case OB11MessageDataType.Shake: {
         sendElements.push(SendElement.shake())
       }
         break
@@ -175,51 +175,22 @@ export async function createSendElements(
   }
 }
 
-// forked from https://github.com/NapNeko/NapCatQQ/blob/6f6b258f22d7563f15d84e7172c4d4cbb547f47e/src/onebot11/action/msg/SendMsg/create-send-elements.ts#L26
-async function handleOb11FileLikeMessage(
-  ctx: Context,
-  { data: inputdata }: OB11MessageFileBase,
-  { deleteAfterSentFiles }: { deleteAfterSentFiles: string[] },
-) {
-  //有的奇怪的框架将url作为参数 而不是file 此时优先url 同时注意可能传入的是非file://开头的目录 By Mlikiowa
-  const {
-    path,
-    isLocal,
-    fileName,
-    errMsg,
-    success,
-  } = (await uri2local(ctx, inputdata.url || inputdata.file))
-
-  if (!success) {
-    ctx.logger.error(errMsg)
-    throw Error(errMsg)
-  }
-
-  if (!isLocal) { // 只删除http和base64转过来的文件
-    deleteAfterSentFiles.push(path)
-  }
-
-  return { path, fileName: inputdata.name || fileName }
-}
-
-export function convertMessage2List(message: OB11MessageMixType, autoEscape = false) {
+export function message2List(message: OB11MessageMixType, autoEscape = false) {
   if (typeof message === 'string') {
     if (autoEscape === true) {
-      message = [
+      return [
         {
-          type: OB11MessageDataType.text,
+          type: OB11MessageDataType.Text,
           data: {
             text: message,
           },
         },
-      ]
+      ] as OB11MessageData[]
+    } else {
+      return decodeCQCode(message)
     }
-    else {
-      message = decodeCQCode(message.toString())
-    }
-  }
-  else if (!Array.isArray(message)) {
-    message = [message]
+  } else if (!Array.isArray(message)) {
+    return [message]
   }
   return message
 }
@@ -301,3 +272,18 @@ export async function createPeer(ctx: Context, payload: CreatePeerPayload, mode
   }
   throw new Error('请指定 group_id 或 user_id')
 }
+
+export async function handleOb11RichMedia(ctx: Context, segment: OB11MessageFileBase, deleteAfterSentFiles: string[]) {
+  const res = await uri2local(ctx, segment.data.url || segment.data.file)
+
+  if (!res.success) {
+    ctx.logger.error(res.errMsg)
+    throw Error(res.errMsg)
+  }
+
+  if (!res.isLocal) {
+    deleteAfterSentFiles.push(res.path)
+  }
+
+  return { path: res.path, fileName: segment.data.name || res.fileName }
+}
diff --git a/src/onebot11/helper/createMultiMessage.ts b/src/onebot11/helper/createMultiMessage.ts
new file mode 100644
index 0000000..a12cfaf
--- /dev/null
+++ b/src/onebot11/helper/createMultiMessage.ts
@@ -0,0 +1,239 @@
+import { Context } from 'cordis'
+import { OB11MessageData, OB11MessageDataType } from '../types'
+import { Msg, RichMedia } from '@/ntqqapi/proto/compiled'
+import { handleOb11RichMedia } from './createMessage'
+import { selfInfo } from '@/common/globalVars'
+import { Peer, RichMediaUploadCompleteNotify } from '@/ntqqapi/types'
+import { deflateSync } from 'node:zlib'
+import faceConfig from '@/ntqqapi/helper/face_config.json'
+
+export class MessageEncoder {
+  static support = ['text', 'face', 'image', 'markdown', 'forward']
+  results: Msg.Message[]
+  children: Msg.Elem[]
+  deleteAfterSentFiles: string[]
+  isGroup: boolean
+  seq: number
+  tsum: number
+  preview: string
+  news: { text: string }[]
+  name?: string
+  uin?: number
+
+  constructor(private ctx: Context, private peer: Peer) {
+    this.results = []
+    this.children = []
+    this.deleteAfterSentFiles = []
+    this.isGroup = peer.chatType === 2
+    this.seq = Math.trunc(Math.random() * 65430)
+    this.tsum = 0
+    this.preview = ''
+    this.news = []
+  }
+
+  async flush() {
+    if (this.children.length === 0) return
+
+    const nick = this.name || selfInfo.nick || 'QQ用户'
+
+    if (this.news.length < 4) {
+      this.news.push({
+        text: `${nick}: ${this.preview}`
+      })
+    }
+
+    this.results.push({
+      routingHead: {
+        fromUin: this.uin ?? +selfInfo.uin ?? 1094950020,
+        c2c: this.isGroup ? undefined : {
+          friendName: nick
+        },
+        group: this.isGroup ? {
+          groupCode: 284840486,
+          groupCard: nick
+        } : undefined
+      },
+      contentHead: {
+        msgType: this.isGroup ? 82 : 9,
+        random: Math.floor(Math.random() * 4294967290),
+        msgSeq: this.seq,
+        msgTime: Math.trunc(Date.now() / 1000),
+        pkgNum: 1,
+        pkgIndex: 0,
+        divSeq: 0,
+        field15: {
+          field1: 0,
+          field2: 0,
+          field3: 0,
+          field4: '',
+          field5: ''
+        }
+      },
+      body: {
+        richText: {
+          elems: this.children
+        }
+      }
+    })
+
+    this.seq++
+    this.tsum++
+    this.children = []
+    this.preview = ''
+  }
+
+  async packImage(data: RichMediaUploadCompleteNotify, busiType: number) {
+    const imageSize = await this.ctx.ntFileApi.getImageSize(data.filePath)
+    return {
+      commonElem: {
+        serviceType: 48,
+        pbElem: RichMedia.MsgInfo.encode({
+          msgInfoBody: [{
+            index: {
+              info: {
+                fileSize: +data.commonFileInfo.fileSize,
+                md5HexStr: data.commonFileInfo.md5,
+                sha1HexStr: data.commonFileInfo.sha,
+                fileName: data.commonFileInfo.fileName,
+                fileType: {
+                  type: 1,
+                  picFormat: imageSize.type === 'gif' ? 2000 : 1000
+                },
+                width: imageSize.width,
+                height: imageSize.height,
+                time: 0,
+                original: 1
+              },
+              fileUuid: data.fileId,
+              storeID: 1,
+              expire: 2678400
+            },
+            pic: {
+              urlPath: `/download?appid=${this.isGroup ? 1407 : 1406}&fileid=${data.fileId}`,
+              ext: {
+                originalParam: '&spec=0',
+                bigParam: '&spec=720',
+                thumbParam: '&spec=198'
+              },
+              domain: 'multimedia.nt.qq.com.cn'
+            },
+            fileExist: true
+          }],
+          extBizInfo: {
+            pic: {
+              bizType: 0,
+              summary: ''
+            },
+            busiType
+          }
+        }).finish(),
+        businessType: this.isGroup ? 20 : 10
+      }
+    }
+  }
+
+  packForwardMessage(resid: string) {
+    const uuid = crypto.randomUUID()
+    const content = JSON.stringify({
+      app: 'com.tencent.multimsg',
+      config: {
+        autosize: 1,
+        forward: 1,
+        round: 1,
+        type: 'normal',
+        width: 300
+      },
+      desc: '[聊天记录]',
+      extra: JSON.stringify({
+        filename: uuid,
+        tsum: 0,
+      }),
+      meta: {
+        detail: {
+          news: [{
+            text: '查看转发消息'
+          }],
+          resid,
+          source: '聊天记录',
+          summary: '查看转发消息',
+          uniseq: uuid,
+        }
+      },
+      prompt: '[聊天记录]',
+      ver: '0.0.0.5',
+      view: 'contact'
+    })
+    return {
+      lightApp: {
+        data: Buffer.concat([Buffer.from([1]), deflateSync(Buffer.from(content, 'utf-8'))])
+      }
+    }
+  }
+
+  async visit(segment: OB11MessageData) {
+    const { type, data } = segment
+    if (type === OB11MessageDataType.Node) {
+      await this.render(data.content as OB11MessageData[])
+      const id = data.id ?? data.user_id
+      this.uin = id ? +id : undefined
+      this.name = data.name ?? data.nickname
+      await this.flush()
+    } else if (type === OB11MessageDataType.Text) {
+      this.children.push({
+        text: {
+          str: data.text
+        }
+      })
+      this.preview += data.text
+    } else if (type === OB11MessageDataType.Face) {
+      this.children.push({
+        face: {
+          index: +data.id
+        }
+      })
+      const face = faceConfig.sysface.find(e => e.QSid === String(data.id))
+      if (face) {
+        this.preview += face.QDes
+      }
+    } else if (type === OB11MessageDataType.Image) {
+      const { path } = await handleOb11RichMedia(this.ctx, segment, this.deleteAfterSentFiles)
+      const data = await this.ctx.ntFileApi.uploadRMFileWithoutMsg(path, this.isGroup ? 4 : 3, this.peer.peerUid)
+      const busiType = Number(segment.data.subType) || 0
+      this.children.push(await this.packImage(data, busiType))
+      this.preview += busiType === 1 ? '[动画表情]' : '[图片]'
+    } else if (type === OB11MessageDataType.Markdown) {
+      this.children.push({
+        commonElem: {
+          serviceType: 45,
+          pbElem: Msg.MarkdownElem.encode(data).finish(),
+          businessType: 1
+        }
+      })
+    } else if (type === OB11MessageDataType.Forward) {
+      this.children.push(this.packForwardMessage(data.id))
+      this.preview += '[聊天记录]'
+    }
+  }
+
+  async render(segments: OB11MessageData[]) {
+    for (const segment of segments) {
+      await this.visit(segment)
+    }
+  }
+
+  async generate(content: any[]) {
+    await this.render(content)
+    return {
+      multiMsgItems: [{
+        fileName: 'MultiMsg',
+        buffer: {
+          msg: this.results
+        }
+      }],
+      tsum: this.tsum,
+      source: this.isGroup ? '群聊的聊天记录' : '聊天记录',
+      summary: `查看${this.tsum}条转发消息`,
+      news: this.news
+    }
+  }
+}
diff --git a/src/onebot11/helper/quickOperation.ts b/src/onebot11/helper/quickOperation.ts
index 913ab19..ad0a538 100644
--- a/src/onebot11/helper/quickOperation.ts
+++ b/src/onebot11/helper/quickOperation.ts
@@ -2,7 +2,7 @@ import { OB11Message, OB11MessageData, OB11MessageDataType } from '../types'
 import { OB11FriendRequestEvent } from '../event/request/OB11FriendRequest'
 import { OB11GroupRequestEvent } from '../event/request/OB11GroupRequest'
 import { GroupRequestOperateTypes } from '@/ntqqapi/types'
-import { convertMessage2List, createSendElements, sendMsg, createPeer, CreatePeerMode } from '../helper/createMessage'
+import { message2List, createSendElements, sendMsg, createPeer, CreatePeerMode } from '../helper/createMessage'
 import { isNullable } from 'cosmokit'
 import { Context } from 'cordis'
 
@@ -65,7 +65,7 @@ async function handleMsg(ctx: Context, msg: OB11Message, quickAction: QuickOpera
   if (reply) {
     let replyMessage: OB11MessageData[] = []
     replyMessage.push({
-      type: OB11MessageDataType.reply,
+      type: OB11MessageDataType.Reply,
       data: {
         id: msg.message_id.toString(),
       },
@@ -74,14 +74,14 @@ async function handleMsg(ctx: Context, msg: OB11Message, quickAction: QuickOpera
     if (msg.message_type == 'group') {
       if ((quickAction as QuickOperationGroupMessage).at_sender) {
         replyMessage.push({
-          type: OB11MessageDataType.at,
+          type: OB11MessageDataType.At,
           data: {
             qq: msg.user_id.toString(),
           },
         })
       }
     }
-    replyMessage = replyMessage.concat(convertMessage2List(reply, quickAction.auto_escape))
+    replyMessage = replyMessage.concat(message2List(reply, quickAction.auto_escape))
     const { sendElements, deleteAfterSentFiles } = await createSendElements(ctx, replyMessage, peer)
     sendMsg(ctx, peer, sendElements, deleteAfterSentFiles).catch(e => ctx.logger.error(e))
   }
diff --git a/src/onebot11/types.ts b/src/onebot11/types.ts
index 9a2c339..c6c504f 100644
--- a/src/onebot11/types.ts
+++ b/src/onebot11/types.ts
@@ -117,30 +117,30 @@ export interface OB11Return<DataType> {
 }
 
 export enum OB11MessageDataType {
-  text = 'text',
-  image = 'image',
-  music = 'music',
-  video = 'video',
-  voice = 'record',
-  file = 'file',
-  at = 'at',
-  reply = 'reply',
-  json = 'json',
-  face = 'face',
-  mface = 'mface', // 商城表情
-  markdown = 'markdown',
-  node = 'node', // 合并转发消息节点
-  forward = 'forward', // 合并转发消息,用于上报
-  xml = 'xml',
-  poke = 'poke',
-  dice = 'dice',
-  RPS = 'rps',
-  contact = 'contact',
-  shake = 'shake',
+  Text = 'text',
+  Image = 'image',
+  Music = 'music',
+  Video = 'video',
+  Record = 'record',
+  File = 'file',
+  At = 'at',
+  Reply = 'reply',
+  Json = 'json',
+  Face = 'face',
+  Mface = 'mface', // 商城表情
+  Markdown = 'markdown',
+  Node = 'node', // 合并转发消息节点
+  Forward = 'forward', // 合并转发消息,用于上报
+  Xml = 'xml',
+  Poke = 'poke',
+  Dice = 'dice',
+  Rps = 'rps',
+  Contact = 'contact',
+  Shake = 'shake',
 }
 
 export interface OB11MessageMFace {
-  type: OB11MessageDataType.mface
+  type: OB11MessageDataType.Mface
   data: {
     emoji_package_id: number
     emoji_id: string
@@ -151,27 +151,27 @@ export interface OB11MessageMFace {
 }
 
 export interface OB11MessageDice {
-  type: OB11MessageDataType.dice
+  type: OB11MessageDataType.Dice
   data: {
     result: number /* intended */ | string /* in fact */
   }
 }
 export interface OB11MessageRPS {
-  type: OB11MessageDataType.RPS
+  type: OB11MessageDataType.Rps
   data: {
     result: number | string
   }
 }
 
 export interface OB11MessageText {
-  type: OB11MessageDataType.text
+  type: OB11MessageDataType.Text
   data: {
     text: string // 纯文本
   }
 }
 
 export interface OB11MessagePoke {
-  type: OB11MessageDataType.poke
+  type: OB11MessageDataType.Poke
   data: {
     qq?: number
     id?: number
@@ -189,7 +189,7 @@ export interface OB11MessageFileBase {
 }
 
 export interface OB11MessageImage extends OB11MessageFileBase {
-  type: OB11MessageDataType.image
+  type: OB11MessageDataType.Image
   data: OB11MessageFileBase['data'] & {
     summary?: string // 图片摘要
     subType?: PicSubType
@@ -198,14 +198,14 @@ export interface OB11MessageImage extends OB11MessageFileBase {
 }
 
 export interface OB11MessageRecord extends OB11MessageFileBase {
-  type: OB11MessageDataType.voice
+  type: OB11MessageDataType.Record
   data: OB11MessageFileBase['data'] & {
     path?: string //扩展
   }
 }
 
 export interface OB11MessageFile extends OB11MessageFileBase {
-  type: OB11MessageDataType.file
+  type: OB11MessageDataType.File
   data: OB11MessageFileBase['data'] & {
     file_id?: string
     path?: string
@@ -213,14 +213,14 @@ export interface OB11MessageFile extends OB11MessageFileBase {
 }
 
 export interface OB11MessageVideo extends OB11MessageFileBase {
-  type: OB11MessageDataType.video
+  type: OB11MessageDataType.Video
   data: OB11MessageFileBase['data'] & {
     path?: string //扩展
   }
 }
 
 export interface OB11MessageAt {
-  type: OB11MessageDataType.at
+  type: OB11MessageDataType.At
   data: {
     qq: string | 'all'
     name?: string
@@ -228,14 +228,14 @@ export interface OB11MessageAt {
 }
 
 export interface OB11MessageReply {
-  type: OB11MessageDataType.reply
+  type: OB11MessageDataType.Reply
   data: {
     id: string
   }
 }
 
 export interface OB11MessageFace {
-  type: OB11MessageDataType.face
+  type: OB11MessageDataType.Face
   data: {
     id: string
   }
@@ -244,48 +244,50 @@ export interface OB11MessageFace {
 export type OB11MessageMixType = OB11MessageData[] | string | OB11MessageData
 
 export interface OB11MessageNode {
-  type: OB11MessageDataType.node
+  type: OB11MessageDataType.Node
   data: {
-    id?: string
-    user_id?: number
-    nickname: string
-    content: OB11MessageMixType
+    id?: number | string
+    content?: OB11MessageMixType
+    user_id?: number // ob11
+    nickname?: string // ob11
+    name?: string // gocq
+    uin?: number | string // gocq
   }
 }
 
 export interface OB11MessageIdMusic {
-  type: OB11MessageDataType.music
+  type: OB11MessageDataType.Music
   data: IdMusicSignPostData
 }
 
 export interface OB11MessageCustomMusic {
-  type: OB11MessageDataType.music
+  type: OB11MessageDataType.Music
   data: Omit<CustomMusicSignPostData, 'singer'> & { content?: string }
 }
 
 export type OB11MessageMusic = OB11MessageIdMusic | OB11MessageCustomMusic
 
 export interface OB11MessageJson {
-  type: OB11MessageDataType.json
+  type: OB11MessageDataType.Json
   data: { data: string /* , config: { token: string } */ }
 }
 
 export interface OB11MessageMarkdown {
-  type: OB11MessageDataType.markdown
+  type: OB11MessageDataType.Markdown
   data: {
-    data: string
+    content: string
   }
 }
 
 export interface OB11MessageForward {
-  type: OB11MessageDataType.forward
+  type: OB11MessageDataType.Forward
   data: {
     id: string
   }
 }
 
 export interface OB11MessageContact {
-  type: OB11MessageDataType.contact
+  type: OB11MessageDataType.Contact
   data: {
     type: 'qq' | 'group'
     id: string
@@ -293,7 +295,7 @@ export interface OB11MessageContact {
 }
 
 export interface OB11MessageShake {
-  type: OB11MessageDataType.shake
+  type: OB11MessageDataType.Shake
   data: Record<string, never>
 }