Exemple #1
0
static a_sym *findNewShiftSym( a_state *state, traceback **h )
{
    a_shift_action  *saction;
    a_sym           *shift_sym;
    a_name          name;

    if( state->trans[0].sym != NULL && state->trans[1].sym == NULL ) {
        shift_sym = state->trans[0].sym;
        if( notInTraceback( h, shift_sym ) ) {
            return( shift_sym );
        }
    }
    if( state->name.item[0] == NULL || !IsState( *state->name.item[0] ) ) {
        for( name.item = state->name.item; *name.item; ++name.item ) {
            shift_sym = terminalInKernel( *name.item );
            if( shift_sym != NULL ) {
                if( notInTraceback( h, shift_sym ) ) {
                    return( shift_sym );
                }
            }
        }
    }
    saction = state->trans;
    for( ;; ) {
        shift_sym = saction->sym;
        if( shift_sym == NULL ) break;
        if( notInTraceback( h, shift_sym ) ) {
            return( shift_sym );
        }
        ++saction;
    }
    return( NULL );
}
Exemple #2
0
void CPlayer::SendMsgToClient(Json::Value& jsMsg, uint16_t nMsgType ,bool bBrocat )
{
    if ( IsState(ePlayerState_Offline) == false  )
    {
        CGameServerApp::SharedGameServerApp()->sendMsg(GetSessionID(),jsMsg,nMsgType,ID_MSG_PORT_CLIENT,bBrocat) ;
        return ;
    }
    LOGFMTD("player uid = %d not online so , can not send msg" ,GetUserUID() ) ;
}
Exemple #3
0
void CPlayer::SendMsgToClient(const char* pBuffer, unsigned short nLen,bool bBrocat )
{
	if ( IsState(ePlayerState_Online)  )
	{
		CGameServerApp::SharedGameServerApp()->SendMsg(GetSessionID(),pBuffer,nLen,bBrocat) ;
		return ;
	}
	CLogMgr::SharedLogMgr()->PrintLog("player uid = %d not online so , can not send msg" ,GetUserUID() ) ;
}
Exemple #4
0
// Goto State
bool CFSM::GotoState(CState & NewState)
{
	if (IsState(NewState) && m_pNewState == &NewState)
		return true;

	// Set New State
	m_pNewState = &NewState;
	return true;
}
Exemple #5
0
void CPlayer::SendMsgToClient(const char* pBuffer, unsigned short nLen,bool bBrocat )
{
    stMsg* pmsg = (stMsg*)pBuffer ;
    if ( IsState(ePlayerState_Offline) == false )
    {
        CGameServerApp::SharedGameServerApp()->sendMsg(GetSessionID(),pBuffer,nLen,bBrocat) ;
        return ;
    }
    LOGFMTD("player uid = %d not online so , can not send msg" ,GetUserUID() ) ;
}
DWORD CActionMover::OnDamageMsgC( DWORD dwMsg, CMover* pAttacker, DWORD dwAtkFlags, int nParam )
{
	CMover*	pMover = GetMover();
	BOOL bValid = IsValidObj( pMover ) && IsValidObj( pAttacker );

	if( !bValid || IsState( OBJSTA_DIE_ALL ) )
		return 0;

	if( IsSit() )										// 앉아있다가 맞으면 앉기해제 한다.
		ResetState( OBJSTA_MOVE_ALL );
	
	SendActMsg( OBJMSG_STAND );

	// 날때린놈에 대한 정보를 기록함.
	if( pMover->IsNPC() && pAttacker->IsPlayer() )		// 맞은놈은 NPC , 어태커가 플레이어 일때만 적용됨
	{
		pMover->m_idAttacker = pAttacker->GetId();		// 날 때린넘이 어떤놈인가를 기록함.
		pMover->m_idTargeter = pAttacker->GetId();	
	}
	pAttacker->m_idLastHitMover = pMover->GetId();		// 어태커가 마지막으로 때렸던넘이 나란걸 기록함.

	if( (dwAtkFlags & AF_GENERIC) )	
	{
		ItemProp* pAttackerProp = pAttacker->GetActiveHandItemProp();
		
		D3DXVECTOR3 vLocal;
		if( pAttackerProp && pAttackerProp->dwItemKind3 == IK3_YOYO )
		{
			vLocal    = pMover->GetPos();
			vLocal.y += 1.0f;
		}
		else
		{
			AngleToVectorXZ( &vLocal, pAttacker->GetAngle(), 1.0f );
			vLocal += pMover->GetPos();		//gmpbigsun : 피격자 일반 effect 09_12_17
			vLocal.y += 1.0f;			// 2006/6/20 xuzhu
		}

		if( pAttackerProp && pAttackerProp->dwSfxObj3 != NULL_ID )
			CreateSfx( g_Neuz.m_pd3dDevice, pAttackerProp->dwSfxObj3, vLocal );

		
		if( pAttackerProp && pAttackerProp->dwSfxObj5 != NULL_ID ) //gmpbigsun: 공격자 일반 effect 09_12_17
		{
			vLocal = pAttacker->GetPos( );		
			CreateSfx( g_Neuz.m_pd3dDevice, pAttackerProp->dwSfxObj5, vLocal );
		}
		
	}
	else if ( (dwAtkFlags & AF_MONSTER_SP_CLIENT) )
	{
		// hitter
		ItemProp* pAttackerProp = prj.GetItemProp( nParam >> 16 );
		assert( pAttackerProp );
		DWORD dwSfxObj = pAttackerProp->dwSfxObj3;		// gmpbigsun:특수공격에 이펙트가 있다면 3번사용.
		if( dwSfxObj != NULL_ID )
			CreateSfx( D3DDEVICE, dwSfxObj, pMover->GetPos() );

		// attacker
		dwSfxObj = pAttackerProp->dwSfxObj5;
		if( NULL_ID != dwSfxObj )
			CreateSfx( D3DDEVICE, dwSfxObj, pAttacker->GetPos() );
	}
Exemple #7
0
/**
 @brief	this에게 발동효과 적용
 xApply
*/
int XSkillReceiver::ApplyInvokeEffect( XSkillDat *pSkillDat,
																			 XSkillUser *pCaster,
																			 XSkillReceiver* pInvoker,
																			 XBuffObj *pBuffObj,
																			 const EFFECT *pEffect,
																			 int level )
{
	bool bApplied = false;
	// 발동조건스킬이 지정되어있을땐 그 스킬(버프)을 인보커가 가지고 있는지 검사해야 한다.
	if( pEffect->strInvokeIfHaveBuff.empty() == false )
		if( !pInvoker->FindBuffSkill( pEffect->strInvokeIfHaveBuff.c_str() ) )
			return 0;
	/*
	// 효과가 적용될때마다 이벤트를 발생시킨다.
	// DoT형태의 경우 DoT시점마다 호출되면 만약 발동효과가 2개인경우는 DoT때마다 두번씩 호출된다.
	*/
	if( !OnEventApplyInvokeEffect( pCaster, pBuffObj, pSkillDat, pEffect, level ) )	// virtual
		return 0;		// 사용자가 0을 리턴하면 효과 적용시키지 않는다.
	// 상태발동되어야 할게 있으면 버추얼로 호출시킨다.
	if( pEffect->invokeState ) {
		if( OnApplyState( pCaster, 
											pInvoker, 
											pEffect, 
											pEffect->invokeState, 
											IsState(pEffect->invokeState) ) == FALSE ) {	// virtual
			// 상태이상을 저항하면 효과를 적용하지 않는다.
			return 0;	
		}
		SetStateMsg( pEffect->invokeState, true );
		if( pBuffObj && pBuffObj->IsFirstProcess() ) {
			OnFirstApplyState( pCaster, 
												pInvoker, 
												pEffect, 
												pEffect->invokeState, 
												IsState(pEffect->invokeState),
												level );	// virtual
			bApplied = true;
		}
	} // invokeState
	// 발동스킬이 있는가?
	if( !pEffect->strInvokeSkill.empty()) {
		const ID idCallerBuff = (pBuffObj)? pBuffObj->GetidSkill() : 0;
		// this에게 스킬을 발동스킨다.
		bApplied = DoInvokeSkill( this, XE::VEC2(), pSkillDat, pEffect, level, pCaster, idCallerBuff );
// 		_tstring strInvokeSkillMut = pEffect->strInvokeSkill;
// 		// strInvokeSkill이 바뀔수 있음.
// 		bool bInvoke = pInvoker->OnInvokeSkill( pSkillDat, pEffect, this, level, &strInvokeSkillMut );
// 		if( bInvoke ) {
// #ifdef _XSINGLE
// //			XLOGXN( "스킬발동: %s", pEffect->strInvokeSkill.c_str() );
// #endif // _XSINGLE
// 			// 발동스킬을 실행시킨다. 기준타겟은 this로 된다.
// 			// 발동스킬이 m_listUseSkill에 들어가는 문제가 있어 안들어가도록 수정함.
// 			auto infoUseSkill 
// 				= pCaster->UseSkillByIds( strInvokeSkillMut, // 이게 맞는듯. pEffect->strInvokeSkill,
// 																	level,
// 																	this, nullptr );
// 			XASSERT( infoUseSkill.errCode == xOK /*|| infoUseSkill.errCode == xERR_ALREADY_APPLY_SKILL*/ );
// 			const ID idCallerBuff = (pBuffObj)? pBuffObj->GetidSkill() : 0;
// 			if( infoUseSkill.errCode == xOK ) {
// 				// 발동스킬은 지속형일수도 있고 즉시발동형일수도 있다.
// 				pCaster->OnShootSkill( infoUseSkill, idCallerBuff );
// 				bApplied = true;
// 			}
// 		}
	}
	// 효과발동자(시전대상)에게 이 스킬로 부터 발동될 스킬이 있으면 발생시킨다.
	pInvoker->OnEventInvokeFromSkill( pSkillDat, pEffect, pCaster, this );
	// 비보정파라메터와 보정파라메터를 나눠서 버추얼로 처리한다
	if( pEffect->invokeParameter < 0 ) {
		return ApplyEffectNotAdjParam( pSkillDat, pCaster, pEffect, level );
	} else 
	if( pEffect->invokeParameter > 0 ) {
		return ApplyEffectAdjParam( pSkillDat, pCaster, pEffect, level, pBuffObj );
	}
	return bApplied;
}
Exemple #8
0
void CPlayerBaseData::onBeInviteBy(uint32_t nInviteUID )
{
	if ( m_stBaseData.nInviteUID )
	{
		LOGFMTD("can not do twice be invited ") ;
		return ;
	}
	m_stBaseData.nInviteUID = nInviteUID ;
	m_bPlayerInfoDataDirty = true ;

	// give self prize ;
	AddMoney(COIN_BE_INVITED) ;

	// show dlg ;
	stMsgDlgNotice msg;
	msg.nNoticeType = eNotice_BeInvite ;
	Json::Value jNotice ;
	jNotice["targetUID"] = nInviteUID ;
	jNotice["addCoin"] = COIN_BE_INVITED ;
	Json::StyledWriter writer ;
	std::string strNotice = writer.write(jNotice) ;
	msg.nJsonLen = strNotice.size();
	CAutoBuffer msgBuffer(sizeof(msg) + msg.nJsonLen );
	msgBuffer.addContent(&msg,sizeof(msg)) ;
	msgBuffer.addContent(strNotice.c_str(),msg.nJsonLen) ;
	SendMsg((stMsg*)msgBuffer.getBufferPtr(),msgBuffer.getContentSize()) ;
	LOGFMTD("uid = %d be invite give prize coin = %d",GetPlayer()->GetUserUID(),COIN_BE_INVITED) ;

	// give prize to inviter ;
	auto player = CGameServerApp::SharedGameServerApp()->GetPlayerMgr()->GetPlayerByUserUID(nInviteUID) ;
	if ( player && player->IsState(CPlayer::ePlayerState_Online))
	{
		player->GetBaseData()->addInvitePrize(COIN_INVITE_PRIZE);

		//stMsgDlgNotice msg;
		//msg.nNoticeType = eNotice_InvitePrize ;
		//Json::StyledWriter writer ;
		//std::string strNotice = writer.write(jNotice) ;
		//msg.nJsonLen = strNotice.size();
		//CAutoBuffer msgBuffer(sizeof(msg) + msg.nJsonLen );
		//msgBuffer.addContent(&msg,sizeof(msg)) ;
		//msgBuffer.addContent(strNotice.c_str(),msg.nJsonLen) ;
		//player->GetBaseData()->SendMsg((stMsg*)msgBuffer.getBufferPtr(),msgBuffer.getContentSize()) ;
		LOGFMTD("invite id = %d online just give prize ",nInviteUID) ;
	}
	else
	{
		Json::Value jconArg;
		jconArg["comment"] = "invitePrize" ;
		jconArg["addCoin"] = COIN_INVITE_PRIZE ;
		CPlayerMailComponent::PostOfflineEvent(CPlayerMailComponent::Event_AddCoin,jconArg,nInviteUID) ;
		LOGFMTD("invite id = %d not online just post a mail",nInviteUID) ;
	}

	// send a mail to inviter 
	jNotice["targetUID"] = GetPlayer()->GetUserUID() ;
	jNotice["addCoin"] = COIN_INVITE_PRIZE ;
	Json::StyledWriter writerInfo ;
	strNotice = writerInfo.write(jNotice) ;
	CPlayerMailComponent::PostMailToPlayer(eMail_InvitePrize,strNotice.c_str(),strNotice.size(),nInviteUID);

	// send push notification ;
	CSendPushNotification::getInstance()->reset();
	CSendPushNotification::getInstance()->addTarget(nInviteUID) ;
	CSendPushNotification::getInstance()->setContent(CServerStringTable::getInstance()->getStringByID(5),1) ;
	CSendPushNotification::getInstance()->postApns(CGameServerApp::SharedGameServerApp()->getAsynReqQueue(),false,"invite") ;
}
Exemple #9
0
static int FindPrevIndent(EBuffer *B, int &RowP, int &ColP, char &CharP, int Flags)
{
    STARTFUNC("FindPrevIndent{h_c.cpp}");
    LOG << "Flags: " << hex << Flags << dec << ENDLINE;
    int StateLen;
    hsState *StateMap = 0;
    char *P;
    int L;
    int Count[4] = {
        0, // { }
        0, // ( )
        0, // [ ]
        0, // if/else (one if for each else)
    };

    assert(RowP >= 0 && RowP < B->RCount);
    L = B->RLine(RowP)->Count;
    if (ColP >= L)
        ColP = L - 1;
    assert(ColP >= -1 && ColP <= L);

    char BolChar = ' ';
    int BolCol = -1;
    int BolRow = -1;

    while (RowP >= 0) {

        P = B->RLine(RowP)->Chars;
        L = B->RLine(RowP)->Count;
        StateMap = NULL;
        if (B->GetMap(RowP, &StateLen, &StateMap) == 0)
        {
            LOG << "Can't get state maps" << ENDLINE;
            ENDFUNCRC(0);
        }
	if (L > 0)
	    while (ColP >= 0) {
            LOG << "ColP: " << ColP << " State: " << (int)StateMap[ColP] << ENDLINE;
            if (StateMap[ColP] == hsC_Normal) {
                LOG << "CharP: " << BinChar(P[ColP]) << " BolChar: " << BinChar(BolChar) <<
                    " BolRow: " << BolRow <<
                    " BolCol: " << BolCol <<
                    ENDLINE;
                switch (CharP = P[ColP]) {
                case '{':
                    if (BolChar == ':' || BolChar == ',') {
                        CharP = BolChar;
                        ColP = BolCol;
                        RowP = BolRow;
                        free(StateMap);
                        ENDFUNCRC(1);
                    }
		    if (TEST_ZERO) {
                        free(StateMap);
                        ENDFUNCRC(1);
                    }
                    Count[0]--;
                    break;
                case '}':
                    if (BolChar == ':' || BolChar == ',') {
                        CharP = BolChar;
                        ColP = BolCol;
                        RowP = BolRow;
                        free(StateMap);
                        ENDFUNCRC(1);
                    }
                    if (BolChar == ';') {
                        CharP = BolChar;
                        ColP = BolCol;
                        RowP = BolRow;
                        free(StateMap);
                        ENDFUNCRC(1);
                    }
                    if (ColP == 0) { /* speed optimization */
                        free(StateMap);
                        ENDFUNCRC(1);
                    }
		    if (TEST_ZERO && (Flags & FIND_ENDBLOCK)) {
                        free(StateMap);
                        ENDFUNCRC(1);
                    }
                    Count[0]++;
                    break;
                case '(':
		    if (TEST_ZERO) {
                        free(StateMap);
                        ENDFUNCRC(1);
                    }
                    Count[1]--;
                    break;
                case ')':
                    Count[1]++;
                    break;
                case '[':
                    if (TEST_ZERO) {
                        free(StateMap);
                        ENDFUNCRC(1);
                    }
                    Count[2]--;
                    break;
                case ']':
                    Count[2]++;
                    break;
                case ':':
                    if (ColP >= 1 && P[ColP - 1] == ':') { // skip ::
                        ColP -= 2;
                        continue;
                    }
                case ',':
                case ';':
                    if (TEST_ZERO && BolChar == ' ') {
			if ((CharP == ';' && (Flags & FIND_SEMICOLON))
			    || (CharP == ',' && (Flags & FIND_COMMA))
			    || (CharP == ':' && (Flags & FIND_COLON))) {
                            BolChar = CharP;
                            BolCol = ColP;
			    BolRow = RowP;
			    // this should be here
                            // if not say why ???
			    //free(StateMap);
			    //return 1;
                        }
                    }
                    if (BolChar == ',' && CharP == ':') {
                        BolChar = ' ';
                        BolCol = -1;
                        BolRow = -1;
                        break;
                    }
		    if ((BolChar == ':' || BolChar == ',')
			&& (CharP == ';'/* || CharP == ','*/)) {
                        CharP = ':';
                        ColP = BolCol;
                        RowP = BolRow;
                        free(StateMap);
                        ENDFUNCRC(1);
                    }
                    break;
                case '?':
                    //if ((Flags & FIND_QUESTION)) {
                    if (BolChar == ':' || BolChar == ',') {
                        BolChar = ' ';
                        BolCol = -1;
                        BolRow = -1;
                    }
                    //}
                    break;
                }
            } else if (StateMap[ColP] == hsC_Keyword && (BolChar == ' ' || BolChar == ':')) {
                if (L - ColP >= 2 &&
                    IsState(StateMap + ColP, hsC_Keyword, 2) &&
                    memcmp(P + ColP, "if", 2) == 0)
                {
                    //puts("\nif");
                    if (Count[3] > 0)
                        Count[3]--;
                    if (Flags & FIND_IF) {
                        if (TEST_ZERO) {
                            CharP = 'i';
                            free(StateMap);
                            ENDFUNCRC(1);
                        }
                    }
                }
                if (L - ColP >= 4 &&
                    IsState(StateMap + ColP, hsC_Keyword, 4) &&
                    memcmp(P + ColP, "else", 4) == 0)
                {
                    //puts("\nelse\x7");
                    if (Flags & FIND_ELSE) {
			if (TEST_ZERO) {
                            CharP = 'e';
                            free(StateMap);
                            ENDFUNCRC(1);
                        }
                    }
                    Count[3]++;
                }
		if (TEST_ZERO) {

                    if ((Flags & FIND_FOR) &&
                        L - ColP >= 3 &&
                        IsState(StateMap + ColP, hsC_Keyword, 3) &&
                        memcmp(P + ColP, "for", 3) == 0)
                    {
                        CharP = 'f';
                        free(StateMap);
                        ENDFUNCRC(1);
                    }
                    if ((Flags & FIND_WHILE) &&
                        L - ColP >= 5 &&
                        IsState(StateMap + ColP, hsC_Keyword, 5) &&
                        memcmp(P + ColP, "while", 5) == 0)
                    {
                        CharP = 'w';
                        free(StateMap);
                        ENDFUNCRC(1);
                    }
                    if ((Flags & FIND_SWITCH) &&
                        L - ColP >= 6 &&
                        IsState(StateMap + ColP, hsC_Keyword, 6) &&
                        memcmp(P + ColP, "switch", 6) == 0)
                    {
                        CharP = 's';
                        free(StateMap);
                        ENDFUNCRC(1);
                    }
                    if (((Flags & FIND_CASE) || (BolChar == ':')) &&
                        (L - ColP >= 4 &&
                         IsState(StateMap + ColP, hsC_Keyword, 4) &&
                         memcmp(P + ColP, "case", 4) == 0) ||
                        ((L - ColP >= 7) &&
                         IsState(StateMap + ColP, hsC_Keyword, 7) &&
                         memcmp(P + ColP, "default", 7) == 0))
                    {
                        CharP = 'c';
                        if (BolChar == ':') {
                            CharP = BolChar;
                            ColP = BolCol;
                            RowP = BolRow;
                        }
                        free(StateMap);
                        ENDFUNCRC(1);
                    }
                    if (((Flags & FIND_CLASS) || (BolChar == ':')) &&
                        (L - ColP >= 5 &&
                         IsState(StateMap + ColP, hsC_Keyword, 5) &&
                         memcmp(P + ColP, "class", 5) == 0))
                    {
                        CharP = 'l';
                        if (BolChar == ':') {
                            CharP = BolChar;
                            ColP = BolCol;
                            RowP = BolRow;
                        }
                        free(StateMap);
                        ENDFUNCRC(1);
                    }
                    if (((Flags & FIND_CLASS) || (BolChar == ':')) &&
                        ((L - ColP >= 6 &&
                          IsState(StateMap + ColP, hsC_Keyword, 6) &&
                          memcmp(P + ColP, "public", 6) == 0) ||
                         ((L - ColP >= 7) &&
                          IsState(StateMap + ColP, hsC_Keyword, 7) &&
                          memcmp(P + ColP, "private", 7) == 0) ||
                         ((L - ColP >= 9) &&
                          IsState(StateMap + ColP, hsC_Keyword, 9) &&
                          memcmp(P + ColP, "protected", 9) == 0)))
                    {
                        CharP = 'p';
                        if (BolChar == ':') {
                            CharP = BolChar;
                            ColP = BolCol;
                            RowP = BolRow;
                        }
                        free(StateMap);
                        ENDFUNCRC(1);
                    }
                }
            }
            ColP--;
        }
        free(StateMap);
        if (BolChar != ' ' && BolChar != ':' && BolChar != ',') {
            CharP = BolChar;
            ColP = BolCol;
            ENDFUNCRC(1);
        }
        RowP--;
        if (RowP >= 0) {
            L = B->RLine(RowP)->Count;
            ColP = L - 1;
        }
    }
#undef TEST_ZERO
    ENDFUNCRC(0);
}
Exemple #10
0
static int SearchBackMatch(int Count, EBuffer *B, int Row, hsState State, const char *Open, const char *Close, int *OPos, int *OLine, int matchparens = 0, int bolOnly = 0) {
    char *P;
    int L;
    int Pos;
    int LOpen = strlen(Open);
    int LClose = strlen(Close);
    int StateLen;
    hsState *StateMap;
    int CountX[3] = { 0, 0, 0 };
    int didMatch = 0;

    *OLine = Row;
    *OPos = 0;
    while (Row >= 0) {
        P = B->RLine(Row)->Chars;
        L = B->RLine(Row)->Count;
        StateMap = NULL;
        if (B->GetMap(Row, &StateLen, &StateMap) == 0) return -1;
        Pos = L - 1;
        if (L > 0) while (Pos >= 0) {
            if (P[Pos] != ' ' && P[Pos] != 9) {
                if (StateMap[Pos] == hsC_Normal) {
                    switch (P[Pos]) {
                    case '{': CountX[0]--; break;
                    case '}': CountX[0]++; break;
                    case '(': CountX[1]--; break;
                    case ')': CountX[1]++; break;
                    case '[': CountX[2]--; break;
                    case ']': CountX[2]++; break;
                    }
                }
                if (!matchparens ||
                    (CountX[0] == 0 && CountX[1] == 0 && CountX[2] == 0))
                {
                    if (LOpen + Pos <= L) {
                        if (IsState(StateMap + Pos, State, LOpen)) {
                            if (memcmp(P + Pos, Open, LOpen) == 0) Count++;
                            if (Count == 0) {
                                if (bolOnly)
                                    didMatch = 1;
                                else {
                                    *OPos = B->ScreenPos(B->RLine(Row), Pos);
				    *OLine = Row;
				    free(StateMap);
				    return B->LineIndented(Row);
				}
			    }
			}
			if (LClose + Pos <= L) {
			    if (IsState(StateMap + Pos, State, LClose)) {
				if (memcmp(P + Pos, Close, LClose) == 0) Count--;
			    }
			}
		    }
		}
	    }
	    Pos--;
        }
        if (bolOnly && didMatch && CountX[1] == 0 && CountX[2] == 0) {
            *OPos = 0;
            *OLine = Row;
            free(StateMap);
            return B->LineIndented(Row);
        }
        if (StateMap) free(StateMap);
        Row--;
    }
    return -1;
}