<?php

require_once( PATH_LIB . 'cserver/ESPacket.php' );
require_once( PATH_LIB . 'cserver/NetUtil.php' );

class IDataServer{
	
	const PHP_CALL_SERVER_GET_PROPERTY			= 0x1004;   //获取用户基本信息
	const PHP_CALL_SERVER_UPDATE_PROPERTY		= 0x1005;   //设置用户基本信息
    const PHP_CALL_SERVER_MATCH_INFO            = 0x910;    //获取比赛场相关信息
    const PHP_UPDATE_MATCH_INFO_NOTICE_SERVER   = 0x909;    //通知server比赛场信息有修改
    const PHP_UPDATE_MATCH_STATUS_NOTICE_SERVER   = 0x908;    //通知server比赛场状态有修改 开或者关

    private $errCode;
    private $errMsg;

    private $enumArr = array(1, 2, 3); //修改用户属性的枚举类型 1=>money 2=>safe_box 3=>total_money

    public function __construct(){
        $this->errCode = 0;
        $this->errMsg  = '';
    }
	
    /**
     * 获取用户金币，经验，输，赢
     * @param unknown $mid
     * @return boolean|multitype:NULL number
     */
	public function getUserProperty( $mid ){
		if ( ! $mid = oo::functions()->uint( $mid)) {
			return false;
		}
		
		$packet = new ESPacket();
		$packet->WriteBegin( self::PHP_CALL_SERVER_GET_PROPERTY);
		$packet->WriteInt($mid);
		$packet->WriteEnd();
		$request  = $packet->GetPacketBuffer();

        $moneyServerIp = oo::$config['MoneyServer'][0];
        $moneyServerPort = oo::$config['MoneyServer'][1];
		$response = NetUtil::tcpCmd($moneyServerIp, $moneyServerPort, $request, 5, 3 );
		if(empty($response)){
			return false;
		}
		
		$RevPacket = new ESPacket();
        $RevPacket->SetRecvPacketBuffer($response , strlen($response));
        $RevPacket->ParsePacket();
        $retCode = $RevPacket->ReadInt();
        if ( $retCode == 0) {
            $retStr = $RevPacket->ReadString();//逗号分隔字符串
        	$array = array();
            $retArr = explode(',', $retStr);
        	$array['money'] 		= intval($retArr[0]);
        	$array['safebox'] 		= intval($retArr[1]);
        	$array['totalMoney'] 	= intval($retArr[2]);
        	$array['exp']           = intval($retArr[3]);
        	$array['level']		    = intval($retArr[4]);
        	$array['wintimes']		= intval($retArr[5]);
            $array['losetimes']     = intval($retArr[6]);
            $array['diamonds']      = intval($retArr[7]);
            $array['masterPoints']  = intval($retArr[8]);
        } else {
        	return false;
        }
        return $array;
    }
    
    /**
     * 修改用户金币，经验，输，赢
     * @param unknown $mid
     * @param unknown $array uid，money，exp，win, reason 标识
     * @return boolean|mixed
     */
    public function updateUserProperty($array){
    	if ( !$uid = oo::functions()->uint( $array['uid'])) {
    		return false;
    	}
        //过滤出uid和reason,再加一个是否需要通知
        $uid = $array['uid'];
        $reason = empty($array['reason']) ? 20000 : $array['reason'];
        $needNotice = $array['neednotice'];
        unset($array['uid'], $array['reason'], $array['neednotice']);
        
        $oprLen = count($array);//操作类型的长度
        $packet = new ESPacket();
        $packet->WriteBegin(self::PHP_CALL_SERVER_UPDATE_PROPERTY);
        $packet->WriteInt($uid);
        $packet->WriteString('');
        $packet->WriteByte($oprLen);
        foreach ($array as $type => $val) {
            $packet->WriteInt($type);
            if( in_array($type, $this->enumArr) ){
               $packet->WriteInt64($val);
            }else{
                $packet->WriteInt($val);
            }
        }
        $packet->WriteInt($reason);
    	$packet->WriteEnd();
    	$request  = $packet->GetPacketBuffer();
    	
        $moneyServerIp = oo::$config['MoneyServer'][0];
        $moneyServerPort = oo::$config['MoneyServer'][1];
		$response = NetUtil::tcpCmd( $moneyServerIp, $moneyServerPort, $request, 5, 3 );
    	if( empty($response) )
    	{
    		return false;
    	}

        $packet = new ESPacket();
        $packet->SetRecvPacketBuffer($response, strlen($response));
        $packet->ParsePacket();
        $retCode = $packet->ReadInt();
        if( $retCode != 0 ){
            return false;
        }
        $retStr = $packet->ReadString();
        $retArr = explode(',', $retStr);

        $arr = array();
    	$arr['money']        = $retArr[0];
    	$arr['safe_box']     = $retArr[1];
    	$arr['total_money']  = $retArr[2];
    	$arr['exp']          = $retArr[3];
    	$arr['leve']    	 = $retArr[4];
    	$arr['wintimes']     = $retArr[5];
    	$arr['losetimes']    = $retArr[6];
    	$arr['diamonds']     = $retArr[7];
    	$arr['masterpoints'] = $retArr[8];

        //广播通知 --- 更新用户属性,包括金币,经验等
        if( $needNotice ) {
            oo::broadCastServer()->notifyPropertyChange($uid, $arr);
        }

    	return $arr;
    }


    /**
    *   通过比赛场level获取比赛场信息
    */
    public function getMatchInfoByLevel($matchLevel = 0)
    {
        $data = array();
        if ( empty($matchLevel) ) {
            return $data;
        }

        $level = intval($matchLevel);

        $packet = new ESPacket();
        $packet->WriteBegin(self::PHP_CALL_SERVER_MATCH_INFO);
        $packet->WriteInt($level);
        $packet->WriteEnd();
        $request  = $packet->GetPacketBuffer();

        $moneyServerIp = oo::$config['MatchServer_'.$level][0];
        $moneyServerPort = oo::$config['MatchServer_'.$level][1];
        $response = NetUtil::tcpCmd( $moneyServerIp, $moneyServerPort, $request, 5, 3 );
        if( empty($response) )
        {
            return $data;
        }

        $RevPacket = new ESPacket();
        $RevPacket->SetRecvPacketBuffer($response, strlen($response));
        $RevPacket->ParsePacket();
        $sMatchLevel = $RevPacket->ReadInt();
        if ( $sMatchLevel != $level ) {
            return $data;
        }
        
        $sCurrentJoinCnt    = $RevPacket->ReadInt(); //当前报名人数
        $sCurrentJoinOnline = $RevPacket->ReadInt(); //当前报名在线人数
        $sCurrentPlayCnt    = $RevPacket->ReadInt(); //当前在玩人数
        $sCurrentMatchCnt   = $RevPacket->ReadInt(); //当前状态，0表示没有开赛，1以上数字表示同时整在进行几场
        $sM_MaintainSwitch  = $RevPacket->ReadInt(); //当前系统维护标志，0表示禁止报名，1表示允许报名

        $data['matchlevel']         = $sMatchLevel;
        $data['currentJoinCnt']     = $sCurrentJoinCnt;
        $data['currentJoinOnline']  = $sCurrentJoinOnline;
        $data['currentPlayCnt']     = $sCurrentPlayCnt;
        $data['currentMatchCnt']    = $sCurrentMatchCnt;
        $data['m_MaintainSwitch']   = $sM_MaintainSwitch;

        return $data;
    }

    /**
     * 比赛场有修改后通知server端
     * @param int $matchLevel
     * @return array|string
     */
    public function noticeServerMatchInfoUpdate($matchLevel = 0)
    {
        $matchLevel = intval($matchLevel);
        if(empty($matchLevel)) {
            return false;
        }

        $matchServerIP = oo::$config['MatchServer_'.$matchLevel][0];
        $matchServerPort = oo::$config['MatchServer_'.$matchLevel][1];
        if(empty($matchServerIP) || empty($matchServerPort)) {
            return false;
        }
        $packet = new ESPacket();
        $packet->WriteBegin(self::PHP_UPDATE_MATCH_INFO_NOTICE_SERVER);
        $packet->WriteEnd();
        $request = $packet->GetPacketBuffer();
        oo::logs()->debug3("IP:{$matchServerIP} port:{$matchServerPort} request:{$request}", 'Match.php');
        NetUtil::tcpCmd($matchServerIP, $matchServerPort, $request, 5, 3);//server端没有给返回

        return true;
    }


    /**
     * 比赛场状态有修改后通知server端
     * @param int $matchLevel
     * @param int $status 0 关闭 1 打开
     * @return array|string
     */
    public function noticeServerMatchStatusUpdate($matchLevel = 0, $status = 1)
    {
        $matchLevel = intval($matchLevel);
        if(empty($matchLevel)) {
            return false;
        }
        if(!in_array($status, [0, 1])) {
            return false;
        }

        $matchServerIP = oo::$config['MatchServer_'.$matchLevel][0];
        $matchServerPort = oo::$config['MatchServer_'.$matchLevel][1];
        if(empty($matchServerIP) || empty($matchServerPort)) {
            return false;
        }
        $packet = new ESPacket();
        $packet->WriteBegin(self::PHP_UPDATE_MATCH_STATUS_NOTICE_SERVER);
        $packet->WriteInt($status);
        $packet->WriteEnd();
        $request = $packet->GetPacketBuffer();
        oo::logs()->debug3("IP:{$matchServerIP} port:{$matchServerPort} request:{$request}", 'Match.php');
        $response = NetUtil::tcpCmd($matchServerIP, $matchServerPort, $request, 5, 3);//server端返回1 则成功
        if( empty($response) )
        {
            return false;
        }

        $RevPacket = new ESPacket();
        $RevPacket->SetRecvPacketBuffer($response, strlen($response));
        $RevPacket->ParsePacket();
        $retCode = $RevPacket->ReadInt();
        oo::logs()->debug3("IP:{$matchServerIP} port:{$matchServerPort} request:{$request}##end responseCode:{$retCode}'##end", 'Match.php');

        if ( $retCode == 1 ) {
            return true;
        }

        return false;
    }
}
