private void DoHandler(sourceAPIDelegate sourceAPI, bool isBlock)
    {
        //return if I am in offline play mode
        //if (NetworkManager.Instance.isOfflinePlay)
        //	return;

        //already a handler exist? skip this request
        if (_sourceAPI != null)
        {
            Debug.LogError("[Connection Manager] Already have an API running " + _sourceAPI.ToString());
            return;
        }

        Reset();

        _sourceAPI = sourceAPI;
        _isBlock   = isBlock;


        //start to run the handler
        Debug.Log("[Connection Manager] Running API: " + _sourceAPI.ToString());
        _sourceAPI();

        //set timeout handler
        StartCoroutine(JudgeSourceAPITimeOut());

        //set msg box level 1 handler
        StartCoroutine(BlockMsgBoxLevel1());
    }
    public void RegisterHandler(sourceAPIDelegate sourceAPI, bool isBlock)
    {
        APITemplate api = new APITemplate();

        api.sourceAPI = sourceAPI;
        api.isBlock   = isBlock;
        _sourceAPIQueue.Enqueue(api);
    }
    //this should from the callback of source API, info me that success or not
    public void SendACK(sourceAPIDelegate sourceAPI, bool success, string errorCode = "", string errorType = "", string description = "")
    {
        Debug.Log(string.Format("[Connection Manager] ACK received for API {0}, Success = {1}", sourceAPI.ToString(), success.ToString()));

        //check the source API is null?
        if (_sourceAPI == null)
        {
            Debug.LogWarning("[Connection Manager] ACK received but no API exists.");
            return;
        }

        //check the ACK api is not my current source API?
        if (!_sourceAPI.Equals(sourceAPI))
        {
            Debug.LogWarning("[Connection Manager] ACK received but is not current API: " + sourceAPI.ToString());
            return;
        }

        //stop JudgeSourceAPITimeOut coroutine
        StopCoroutine("JudgeSourceAPITimeOut");

        //stop BlockMsgBoxLevel1 coroutine
        StopCoroutine("BlockMsgBoxLevel1");

        //close msg box lv 1
        if (_msgBoxLv1 != null)
        {
            UIMessageBoxManager.Instance.CloseMessageBox(_msgBoxLv1);
            _msgBoxLv1 = null;
        }

        //get a success, reset all.
        if (success)
        {
            Reset();
        }
        else
        {
            ProcessSourceAPITimeOutOrFail();
        }
    }
    void Reset()
    {
        Debug.Log("[Connection manager] Reset!");

        //		_msgBoxFlag = MsgBoxFlag.None;
        _sourceAPI = null;
        _isBlock   = false;

        //close msg box lv 1
        if (_msgBoxLv1 != null)
        {
            UIMessageBoxManager.Instance.CloseMessageBox(_msgBoxLv1);
            _msgBoxLv1 = null;
        }

        //close msg box lv 2
        if (_msgBoxLv2 != null)
        {
            UIMessageBoxManager.Instance.CloseMessageBox(_msgBoxLv2);
            _msgBoxLv2 = null;
        }
    }