private int InternalSendGroupMessage(out long mtime, long groupId, byte mtype, string message, string attrs = "", int timeout = 0)
        {
            mtime = 0;

            TCPClient client = GetCoreClient();

            if (client == null)
            {
                return(fpnn.ErrorCode.FPNN_EC_CORE_INVALID_CONNECTION);
            }

            Quest quest = new Quest("sendgroupmsg");

            quest.Param("gid", groupId);
            quest.Param("mid", MidGenerator.Gen());
            quest.Param("mtype", mtype);
            quest.Param("msg", message);
            quest.Param("attrs", attrs);

            Answer answer = client.SendQuest(quest, timeout);

            if (answer.IsException())
            {
                return(answer.ErrorCode());
            }

            mtime = answer.Want <long>("mtime");
            return(fpnn.ErrorCode.FPNN_EC_OK);
        }
        //======================[ string message version ]================================//
        private bool InternalSendMessage(long uid, byte mtype, string message, string attrs, ActTimeDelegate callback, int timeout = 0)
        {
            TCPClient client = GetCoreClient();

            if (client == null)
            {
                return(false);
            }

            Quest quest = new Quest("sendmsg");

            quest.Param("to", uid);
            quest.Param("mid", MidGenerator.Gen());
            quest.Param("mtype", mtype);
            quest.Param("msg", message);
            quest.Param("attrs", attrs);

            return(client.SendQuest(quest, (Answer answer, int errorCode) => {
                long mtime = 0;
                if (errorCode == fpnn.ErrorCode.FPNN_EC_OK)
                {
                    mtime = answer.Want <long>("mtime");
                }

                callback(mtime, errorCode);
            }, timeout));
        }
        private Quest BuildSendFileQuest(SendFileInfo info)
        {
            Quest quest = null;

            switch (info.actionType)
            {
            case FileTokenType.P2P:
                quest = new Quest("sendfile");
                quest.Param("to", info.xid);
                break;

            case FileTokenType.Group:
                quest = new Quest("sendgroupfile");
                quest.Param("gid", info.xid);
                break;

            case FileTokenType.Room:
                quest = new Quest("sendroomfile");
                quest.Param("rid", info.xid);
                break;
            }

            quest.Param("pid", pid);
            quest.Param("from", uid);
            quest.Param("token", info.token);
            quest.Param("mtype", info.mtype);
            quest.Param("mid", MidGenerator.Gen());

            quest.Param("file", info.fileContent);
            quest.Param("attrs", BuildFileAttrs(info));

            return(quest);
        }
        private bool InternalSendGroupMessage(long groupId, byte mtype, string message, string attrs, MessageIdDelegate callback, int timeout = 0)
        {
            TCPClient client = GetCoreClient();

            if (client == null)
            {
                if (RTMConfig.triggerCallbackIfAsyncMethodReturnFalse)
                {
                    ClientEngine.RunTask(() =>
                    {
                        callback(0, fpnn.ErrorCode.FPNN_EC_CORE_INVALID_CONNECTION);
                    });
                }

                return(false);
            }

            long mid = MidGenerator.Gen();

            Quest quest = new Quest("sendgroupmsg");

            quest.Param("gid", groupId);
            quest.Param("mid", mid);
            quest.Param("mtype", mtype);
            quest.Param("msg", message);
            quest.Param("attrs", attrs);

            bool asyncStarted = client.SendQuest(quest, (Answer answer, int errorCode) => {
                //long mtime = 0;
                //if (errorCode == fpnn.ErrorCode.FPNN_EC_OK)
                //    mtime = answer.Want<long>("mtime");

                callback(mid, errorCode);
            }, timeout);

            if (!asyncStarted && RTMConfig.triggerCallbackIfAsyncMethodReturnFalse)
            {
                ClientEngine.RunTask(() =>
                {
                    callback(0, fpnn.ErrorCode.FPNN_EC_CORE_INVALID_CONNECTION);
                });
            }

            return(asyncStarted);
        }