コード例 #1
0
ファイル: GameSocket.cpp プロジェクト: Rithual/snoxd-koserver
void CGameSocket::RecvUserInfoAllData(char* pBuf)
{
    int index = 0;
    BYTE		byCount = 0;			// 마리수
    short uid=-1, sHp, sMp, len;
    BYTE bNation, bLevel, bZone, bAuthority=1;
    short sDamage, sAC, sPartyIndex=0;
    float fHitAgi, fAvoidAgi;

    TRACE(" ***** 유저의 모든 정보를 받기 시작합니다 ****** \n");

    byCount = GetByte(pBuf, index);
    for(int i=0; i<byCount; i++)
    {
        char strName[MAX_ID_SIZE+1] = "";
        len = 0;

        uid = GetShort( pBuf, index );
        len = GetShort( pBuf, index );
        GetString(strName, pBuf, len, index);
        bZone = GetByte( pBuf, index );
        bNation = GetByte( pBuf, index );
        bLevel = GetByte( pBuf, index );
        sHp = GetShort( pBuf, index );
        sMp = GetShort( pBuf, index );
        sDamage = GetShort( pBuf, index );
        sAC = GetShort( pBuf, index );
        fHitAgi = Getfloat( pBuf, index );
        fAvoidAgi = Getfloat( pBuf, index );
        sPartyIndex = GetShort( pBuf, index );
        bAuthority = GetByte( pBuf, index );

        if( len > MAX_ID_SIZE || len <= 0 ) {
            TRACE("###  RecvUserInfoAllData() Fail ---> uid = %d, name=%s, len=%d  ### \n", uid, strName, len);
            continue;
        }

        //CUser* pUser = m_pMain->GetActiveUserPtr(uid);
        //if(pUser == NULL)	continue;
        CUser* pUser = new CUser;
        pUser->Initialize();

        pUser->m_iUserId = uid;
        strcpy(pUser->m_strUserID, strName);
        pUser->m_curZone = bZone;
        pUser->m_pMap = m_pMain->GetZoneByID(bZone);
        pUser->m_bNation = bNation;
        pUser->m_bLevel = bLevel;
        pUser->m_sHP = sHp;
        pUser->m_sMP = sMp;
        //pUser->m_sSP = sSp;
        pUser->m_sHitDamage = sDamage;
        pUser->m_fHitrate = fHitAgi;
        pUser->m_fAvoidrate = fAvoidAgi;
        pUser->m_sAC = sAC;
        pUser->m_byIsOP = bAuthority;
        pUser->m_bLive = USER_LIVE;

        if(sPartyIndex != -1)	{
            pUser->m_byNowParty = 1;					// 파티중
            pUser->m_sPartyNumber = sPartyIndex;		// 파티 번호 셋팅
        }

        TRACE("****  RecvUserInfoAllData()---> uid = %d, %s, party_number=%d  ******\n", uid, strName, pUser->m_sPartyNumber);

        if(uid >= USER_BAND && uid < MAX_USER)	{
            m_pMain->m_pUser[uid] = pUser;
        }
    }

    TRACE(" ***** 유저의 모든 정보를 다 받았습니다 ****** \n");
}
コード例 #2
0
ファイル: GameSocket.cpp プロジェクト: Rithual/snoxd-koserver
void CGameSocket::RecvAttackReq(char* pBuf)
{
    int index = 0;
    int sid = -1, tid = -1;
    BYTE type, result;
    float rx=0.0f, ry=0.0f, rz=0.0f;
    float fDir = 0.0f;
    short sDamage, sAC;
    float fHitAgi, fAvoidAgi;
//
    short sItemAC;
    BYTE   bTypeLeft;
    BYTE   bTypeRight;
    short  sAmountLeft;
    short  sAmountRight;
//

    type = GetByte(pBuf,index);
    result = GetByte(pBuf,index);
    sid = GetShort(pBuf,index);
    tid = GetShort(pBuf,index);
    sDamage = GetShort( pBuf, index );
    sAC = GetShort( pBuf, index );
    fHitAgi = Getfloat( pBuf, index );
    fAvoidAgi = Getfloat( pBuf, index );
//
    sItemAC = GetShort(pBuf, index);
    bTypeLeft = GetByte(pBuf, index);
    bTypeRight = GetByte(pBuf, index);
    sAmountLeft = GetShort(pBuf, index);
    sAmountRight = GetShort(pBuf, index);
//

    //TRACE("RecvAttackReq : [sid=%d, tid=%d, zone_num=%d] \n", sid, tid, m_sSocketID);

    CUser* pUser = m_pMain->GetUserPtr(sid);
    if(pUser == NULL) return;
    //TRACE("RecvAttackReq 222 :  [id=%d, %s, bLive=%d, zone_num=%d] \n", pUser->m_iUserId, pUser->m_strUserID, pUser->m_bLive, m_sSocketID);

    if(pUser->m_bLive == USER_DEAD || pUser->m_sHP <= 0)
    {
        if(pUser->m_sHP > 0)
        {
            pUser->m_bLive = USER_LIVE;
            TRACE("##### CGameSocket-Attack Fail : User가 Heal된 경우.. [id=%d, %s, bLive=%d, hp=%d] ######\n", pUser->m_iUserId, pUser->m_strUserID, pUser->m_bLive, pUser->m_sHP);
        }
        else
        {
            TRACE("##### CGameSocket-Attack Fail : UserDead  [id=%d, %s, bLive=%d, hp=%d] ######\n", pUser->m_iUserId, pUser->m_strUserID, pUser->m_bLive, pUser->m_sHP);
            // 죽은 유저이므로 게임서버에 죽은 처리를 한다...
            Send_UserError(sid, tid);
            return;
        }
    }
    pUser->m_sHitDamage = sDamage;
    pUser->m_fHitrate = fHitAgi;
    pUser->m_fAvoidrate = fAvoidAgi;
    pUser->m_sAC = sAC;
//
    pUser->m_sItemAC = sItemAC;
    pUser->m_bMagicTypeLeftHand = bTypeLeft;
    pUser->m_bMagicTypeRightHand = bTypeRight;
    pUser->m_sMagicAmountLeftHand = sAmountLeft;
    pUser->m_sMagicAmountRightHand = sAmountRight;
//

    pUser->Attack(sid, tid);
}
コード例 #3
0
ファイル: GameSocket.cpp プロジェクト: Rithual/snoxd-koserver
void CGameSocket::RecvUserUpdate(char* pBuf)
{
    int index = 0;
    short uid=-1, sHP=0, sMP=0, sSP=0;
    BYTE byLevel;

    short sDamage, sAC;
    float fHitAgi, fAvoidAgi;
//
    short  sItemAC;
    BYTE   bTypeLeft;
    BYTE   bTypeRight;
    short  sAmountLeft;
    short  sAmountRight;
//

    uid = GetShort( pBuf, index );
    byLevel = GetByte(pBuf, index);
    sHP = GetShort( pBuf, index );
    sMP = GetShort( pBuf, index );
    sDamage = GetShort( pBuf, index );
    sAC = GetShort( pBuf, index );
    fHitAgi = Getfloat( pBuf, index );
    fAvoidAgi = Getfloat( pBuf, index );
//
    sItemAC = GetShort( pBuf, index ) ;
    bTypeLeft = GetByte(pBuf, index);
    bTypeRight = GetByte(pBuf, index);
    sAmountLeft = GetShort(pBuf, index);
    sAmountRight = GetShort(pBuf, index);
//

    // User List에서 User정보,, 삭제...
    CUser* pUser = m_pMain->GetUserPtr(uid);
    if(pUser == NULL)	return;

    if(pUser->m_bLevel < byLevel)		// level up
    {
        pUser->m_sHP = sHP;
        pUser->m_sMP = sMP;
        //pUser->m_sSP = sSP;
        _USERLOG* pUserLog = NULL;
        pUserLog = new _USERLOG;
        pUserLog->t = CTime::GetCurrentTime();
        pUserLog->byFlag = USER_LEVEL_UP;
        pUserLog->byLevel = byLevel;
        strcpy( pUserLog->strUserID, pUser->m_strUserID );
        pUser->m_UserLogList.push_back( pUserLog );
    }
    pUser->m_bLevel = byLevel;
    pUser->m_sHitDamage = sDamage;
    pUser->m_fHitrate = fHitAgi;
    pUser->m_fAvoidrate = fAvoidAgi;
    pUser->m_sAC = sAC;

//
    pUser->m_sItemAC = sItemAC ;
    pUser->m_bMagicTypeLeftHand = bTypeLeft;
    pUser->m_bMagicTypeRightHand = bTypeRight;
    pUser->m_sMagicAmountLeftHand = sAmountLeft;
    pUser->m_sMagicAmountRightHand = sAmountRight;
//
    //char buff[256];
    //sprintf_s(buff, sizeof(buff), "**** RecvUserUpdate -- uid = (%s,%d), HP = %d, level=%d->%d", pUser->m_strUserID, pUser->m_iUserId, pUser->m_sHP, byLevel, pUser->m_bLevel);
    //TimeTrace(buff);
    //TRACE("**** RecvUserUpdate -- uid = (%s,%d), HP = %d\n", pUser->m_strUserID, pUser->m_iUserId, pUser->m_sHP);
}
コード例 #4
0
ファイル: GameSocket.cpp プロジェクト: Rithual/snoxd-koserver
void CGameSocket::RecvUserInfo(char* pBuf)
{
//	TRACE("RecvUserInfo()\n");
    int index = 0;
    short uid=-1, sHp, sMp, sLength = 0;
    BYTE bNation, bLevel, bZone, bAuthority=1;
    short sDamage, sAC;
    float fHitAgi, fAvoidAgi;
    char strName[MAX_ID_SIZE+1];

    short  sItemAC, sAmountLeft, sAmountRight;
    BYTE   bTypeLeft, bTypeRight;

    uid = GetShort( pBuf, index );
    sLength = GetShort( pBuf, index );
    if( sLength > MAX_ID_SIZE || sLength <= 0 ) {
        char countstr[256];
        CTime cur = CTime::GetCurrentTime();
        sprintf_s( countstr, "RecvUserInfo() Fail : %02d/%02d %02d:%02d - uid=%d, name=%s\r\n", cur.GetMonth(), cur.GetDay(), cur.GetHour(), cur.GetMinute(), uid, strName);
        LogFileWrite( countstr );
        TRACE("###  RecvUserInfo() Fail ---> uid = %d, name=%s  ### \n", uid, strName);
        return;
    }
    GetString(strName, pBuf, sLength, index);
    bZone = GetByte( pBuf, index );
    bNation = GetByte( pBuf, index );
    bLevel = GetByte( pBuf, index );
    sHp = GetShort( pBuf, index );
    sMp = GetShort( pBuf, index );
    sDamage = GetShort( pBuf, index );
    sAC = GetShort( pBuf, index );
    fHitAgi = Getfloat( pBuf, index );
    fAvoidAgi = Getfloat( pBuf, index );
//
    sItemAC = GetShort(pBuf, index);
    bTypeLeft = GetByte(pBuf, index);
    bTypeRight = GetByte(pBuf, index);
    sAmountLeft = GetShort(pBuf, index);
    sAmountRight = GetShort(pBuf, index);
    bAuthority = GetByte(pBuf, index);
//

    //CUser* pUser = m_pMain->GetActiveUserPtr(uid);
    //if( pUser == NULL )		return;
    CUser* pUser = new CUser;
    pUser->Initialize();

    pUser->m_iUserId = uid;
    strcpy(pUser->m_strUserID, strName);
    pUser->m_curZone = bZone;
    pUser->m_pMap = m_pMain->GetZoneByID(bZone);
    pUser->m_bNation = bNation;
    pUser->m_bLevel = bLevel;
    pUser->m_sHP = sHp;
    pUser->m_sMP = sMp;
    //pUser->m_sSP = sSp;
    pUser->m_sHitDamage = sDamage;
    pUser->m_fHitrate = fHitAgi;
    pUser->m_fAvoidrate = fAvoidAgi;
    pUser->m_sAC = sAC;
    pUser->m_bLive = USER_LIVE;
//
    pUser->m_sItemAC = sItemAC;
    pUser->m_bMagicTypeLeftHand = bTypeLeft;
    pUser->m_bMagicTypeRightHand = bTypeRight;
    pUser->m_sMagicAmountLeftHand = sAmountLeft;
    pUser->m_sMagicAmountRightHand = sAmountRight;
    pUser->m_byIsOP = bAuthority;
//

    TRACE("****  RecvUserInfo()---> uid = %d, name=%s, leng=%d  ******\n", uid, strName, sLength);

    if(uid >= USER_BAND && uid < MAX_USER)	{
        m_pMain->m_pUser[uid] = pUser;
    }

    _USERLOG* pUserLog = NULL;
    pUserLog = new _USERLOG;
    pUserLog->t = CTime::GetCurrentTime();
    pUserLog->byFlag = USER_LOGIN;
    pUserLog->byLevel = pUser->m_bLevel;
    strcpy( pUserLog->strUserID, pUser->m_strUserID );
    pUser->m_UserLogList.push_back( pUserLog );
}
コード例 #5
0
ファイル: GameSocket.cpp プロジェクト: Rithual/snoxd-koserver
void CGameSocket::RecvUserInOut(char* pBuf)
{
    int index = 0;
    BYTE bType=-1;
    short uid=-1, len=0;
    char strName[MAX_ID_SIZE+1] = "";
    float fX=-1, fZ=-1;

    bType = GetByte( pBuf, index );
    uid = GetShort( pBuf, index );
    len = GetShort( pBuf, index );
    GetString(strName, pBuf, len, index);
    fX = Getfloat(pBuf, index);
    fZ = Getfloat(pBuf, index);

    if(fX < 0 || fZ < 0)
    {
        TRACE("Error:: RecvUserInOut(),, uid = %d, fX=%.2f, fZ=%.2f\n", uid, fX, fZ);
        return;
    }
//	TRACE("RecvUserInOut(),, uid = %d\n", uid);

    int region_x = 0, region_z=0;
    int x1 = (int)fX / TILE_SIZE;
    int z1 = (int)fZ / TILE_SIZE;
    region_x = (int)fX / VIEW_DIST;
    region_z = (int)fZ / VIEW_DIST;

    // 수정할것,,, : 지금 존 번호를 0으로 했는데.. 유저의 존 정보의 번호를 읽어야,, 함,,
    MAP* pMap = NULL;
    //m_pMain->g_arZone[pUser->m_curZone];

    CUser* pUser = m_pMain->GetUserPtr(uid);

//	TRACE("^^& RecvUserInOut( type=%d )-> User(%s, %d),, zone=%d, index=%d, region_x=%d, y=%d\n", bType, pUser->m_strUserID, pUser->m_iUserId, pUser->m_curZone, pUser->m_sZoneIndex, region_x, region_z);

    if(pUser != NULL)
    {
        //	TRACE("##### Fail : ^^& RecvUserInOut() [name = %s]. state=%d, hp=%d\n", pUser->m_strUserID, pUser->m_bLive, pUser->m_sHP);
        BOOL bFlag = FALSE;

        if(pUser->m_bLive == USER_DEAD || pUser->m_sHP <= 0)
        {
            if(pUser->m_sHP > 0)
            {
                pUser->m_bLive = TRUE;
                TRACE("##### CGameSocket-RecvUserInOut Fail : UserHeal  [id=%s, bLive=%d, hp=%d], fX=%.2f, fZ=%.2f ######\n", pUser->m_strUserID, pUser->m_bLive, pUser->m_sHP, fX, fZ);
            }
            else
            {
                TRACE("##### CGameSocket-RecvUserInOut Fail : UserDead  [id=%s, bLive=%d, hp=%d], fX=%.2f, fZ=%.2f ######\n", pUser->m_strUserID, pUser->m_bLive, pUser->m_sHP, fX, fZ);
                // 죽은 유저이므로 게임서버에 죽은 처리를 한다...
                //Send_UserError(uid);
                //return;
            }
        }

        pMap = pUser->GetMap();

        if(pMap == NULL)
        {
            TRACE("#### Fail : pMap == NULL ####\n");
            return;
        }

        if(x1 < 0 || z1 < 0 || x1 > pMap->m_sizeMap.cx || z1 > pMap->m_sizeMap.cy)
        {
            TRACE("#### RecvUserInOut Fail : [name=%s], x1=%d, z1=%d #####\n", pUser->m_strUserID, region_x, region_z);
            return;
        }
        // map 이동이 불가능이면 User등록 실패..
        //if(pMap->m_pMap[x1][z1].m_sEvent == 0) return;
        if(region_x > pMap->GetXRegionMax() || region_z > pMap->GetZRegionMax())
        {
            TRACE("#### GameSocket-RecvUserInOut() Fail : [name=%s], nRX=%d, nRZ=%d #####\n", pUser->m_strUserID, region_x, region_z);
            return;
        }

        //strcpy(pUser->m_strUserID, strName);
        pUser->m_curx = pUser->m_fWill_x = fX;
        pUser->m_curz = pUser->m_fWill_z = fZ;

        //bFlag = pUser->IsOpIDCheck(strName);
        //if(bFlag)	pUser->m_byIsOP = 1;

        if(bType == 2)	{		// region out
            // 기존의 region정보에서 User의 정보 삭제..
            pMap->RegionUserRemove(region_x, region_z, uid);
            //TRACE("^^& RecvUserInOut()-> User(%s, %d)를 Region에서 삭제..,, zone=%d, index=%d, region_x=%d, y=%d\n", pUser->m_strUserID, pUser->m_iUserId, pUser->m_curZone, pUser->m_sZoneIndex, region_x, region_z);
        }
        else	{				// region in
            if(pUser->m_sRegionX != region_x || pUser->m_sRegionZ != region_z)	{
                pUser->m_sRegionX = region_x;
                pUser->m_sRegionZ = region_z;
                pMap->RegionUserAdd(region_x, region_z, uid);
                //TRACE("^^& RecvUserInOut()-> User(%s, %d)를 Region에 등록,, zone=%d, index=%d, region_x=%d, y=%d\n", pUser->m_strUserID, pUser->m_iUserId, pUser->m_curZone, pUser->m_sZoneIndex, region_x, region_z);
            }
        }
    }
}
コード例 #6
0
ファイル: AISocket.cpp プロジェクト: tuku/snoxd-koserver
void CAISocket::RecvNpcInfo(char* pBuf)
{
	int index = 0;

	BYTE		Mode;			// 01(INFO_MODIFY)	: NPC 정보 변경
								// 02(INFO_DELETE)	: NPC 정보 삭제
	short		nid;			// NPC index
	short		sid;			// NPC index
	short		sPid;			// NPC Picture Number
	short		sSize = 100;	// NPC Size
	int			iWeapon_1;		// 오른손 무기
	int			iWeapon_2;		// 왼손  무기
	BYTE        bZone;			// Current zone number
	char		szName[MAX_NPC_SIZE+1];		// NPC Name
	BYTE		byGroup;		// 소속 집단
	BYTE		byLevel;			// level
	float		fPosX;			// X Position
	float		fPosZ;			// Z Position
	float		fPosY;			// Y Position
	BYTE		byDirection;	// 방향
	BYTE		tState;			// NPC 상태
								// 00	: NPC Dead
								// 01	: NPC Live
	BYTE		tNpcKind;		// 00	: Monster
								// 01	: NPC
	int		iSellingGroup;
  	int		nMaxHP;			// 최대 HP
	int		nHP;			// 현재 HP
	BYTE		byGateOpen;
	short		sHitRate;		// 공격 성공률
	BYTE		byObjectType;	// 보통 : 0, 특수 : 1

	Mode = GetByte(pBuf, index);
	nid = GetShort(pBuf, index);
	sid = GetShort(pBuf, index);
	sPid = GetShort(pBuf, index);
	sSize = GetShort(pBuf, index);
	iWeapon_1 = GetDWORD(pBuf, index);
	iWeapon_2 = GetDWORD(pBuf, index);
	bZone = GetByte(pBuf, index);
	int nLength = GetVarString(szName, pBuf, sizeof(BYTE), index);
	if(nLength < 0 || nLength > MAX_NPC_SIZE) return;		// 잘못된 monster 아이디 
	byGroup = GetByte(pBuf, index);
	byLevel  = GetByte(pBuf, index);
	fPosX = Getfloat(pBuf, index);
	fPosZ = Getfloat(pBuf, index);
	fPosY = Getfloat(pBuf, index);
	byDirection = GetByte(pBuf, index);
	tState = GetByte(pBuf, index);
	tNpcKind = GetByte(pBuf, index);
	iSellingGroup = GetDWORD(pBuf, index);
	nMaxHP = GetDWORD(pBuf, index);
	nHP = GetDWORD(pBuf, index);
	byGateOpen = GetByte(pBuf, index);
	sHitRate = GetShort(pBuf, index);
	byObjectType = GetByte(pBuf, index);

	CNpc* pNpc = NULL;

	pNpc = m_pMain->m_arNpcArray.GetData(nid);
	if(!pNpc)	return;

	pNpc->m_NpcState = NPC_DEAD;

	if( pNpc->m_NpcState == NPC_LIVE )	{	// 살아 있는데 또 정보를 받는 경우
		char strLog[256]; 
		CTime t = CTime::GetCurrentTime();
		sprintf_s(strLog, sizeof(strLog), "## time(%d:%d-%d) npc regen check(%d) : nid=%d, name=%s, x=%d, z=%d, rx=%d, rz=%d ## \r\n", t.GetHour(), t.GetMinute(), t.GetSecond(), pNpc->m_NpcState, nid, szName, (int)pNpc->m_fCurX, (int)pNpc->m_fCurZ, pNpc->m_sRegion_X, pNpc->m_sRegion_Z);
		EnterCriticalSection( &g_LogFile_critical );
		m_pMain->m_RegionLogFile.Write( strLog, strlen(strLog) );
		LeaveCriticalSection( &g_LogFile_critical );
		TRACE(strLog);
		// to-do: replace with m_pMain->WriteRegionLog(...);
	}

	pNpc->m_NpcState = NPC_LIVE;
	
	pNpc->m_sNid = nid;
	pNpc->m_sSid = sid;
	pNpc->m_sPid = sPid;
	pNpc->m_sSize = sSize;
	pNpc->m_iWeapon_1 = iWeapon_1;
	pNpc->m_iWeapon_2 = iWeapon_2;
	strcpy(pNpc->m_strName, szName);
	pNpc->m_byGroup = byGroup;
	pNpc->m_byLevel = byLevel;
	pNpc->m_bCurZone = bZone;
	pNpc->m_pMap = m_pMain->GetZoneByID(bZone);
	pNpc->m_fCurX = fPosX;
	pNpc->m_fCurZ = fPosZ;
	pNpc->m_fCurY = fPosY;
	pNpc->m_byDirection = byDirection;
	pNpc->m_NpcState = tState;
	pNpc->m_tNpcType = tNpcKind;
	pNpc->m_iSellingGroup = iSellingGroup;
	pNpc->m_iMaxHP = nMaxHP;
	pNpc->m_iHP = nHP;
	pNpc->m_byGateOpen = byGateOpen;
	pNpc->m_sHitRate = sHitRate;
	pNpc->m_byObjectType = byObjectType;

	if (pNpc->GetMap() == NULL)
		return;

	int nRegX = (int)fPosX / VIEW_DISTANCE;
	int nRegZ = (int)fPosZ / VIEW_DISTANCE;

	pNpc->m_sRegion_X = nRegX;
	pNpc->m_sRegion_Z = nRegZ;

	_OBJECT_EVENT* pEvent = NULL;
	if( pNpc->m_byObjectType == SPECIAL_OBJECT )	{
		pEvent = pNpc->GetMap()->GetObjectEvent( pNpc->m_sSid );
		if( pEvent )	pEvent->byLife = 1;
	}

	if(Mode == 0)	{
		TRACE("RecvNpcInfo - dead monster nid=%d, name=%s\n", pNpc->m_sNid, pNpc->m_strName);
		return;
	}

	pNpc->NpcInOut(NPC_IN, fPosX, fPosZ, fPosY);
}
コード例 #7
0
ファイル: AISocket.cpp プロジェクト: tuku/snoxd-koserver
void CAISocket::RecvNpcGiveItem(char* pBuf)
{
	int index = 0, send_index = 0;
	char send_buff[1024];
	short sUid, sNid, sZone, regionx, regionz;
	float fX, fZ, fY;
	BYTE byCount;
	int nItemNumber[NPC_HAVE_ITEM_LIST];
	short sCount[NPC_HAVE_ITEM_LIST];
	_ZONE_ITEM* pItem = NULL;
	C3DMap* pMap = NULL;
	CUser* pUser = NULL;

	sUid = GetShort(pBuf,index);	// Item을 가져갈 사람의 아이디... (이것을 참조해서 작업하셈~)
	sNid = GetShort(pBuf,index);
	sZone = GetShort(pBuf, index);
	regionx = GetShort( pBuf, index );
	regionz = GetShort( pBuf, index );
	fX = Getfloat(pBuf,index);
	fZ = Getfloat(pBuf,index);
	fY = Getfloat(pBuf,index);
	byCount = GetByte(pBuf,index);
	for(int i=0; i<byCount; i++)
	{
		nItemNumber[i] = GetDWORD(pBuf, index);
		sCount[i] = GetShort(pBuf,index);
	}

	if( sUid < 0 || sUid >= MAX_USER ) return;
	pMap = m_pMain->GetZoneByID(sZone);
	if (pMap == NULL)
		return;

	pItem = new _ZONE_ITEM;
	for(int i=0; i<6; i++) {
		pItem->itemid[i] = 0;
		pItem->count[i] = 0;
	}
	pItem->bundle_index = pMap->m_wBundle;
	pItem->time = TimeGet();
	pItem->x = fX;
	pItem->z = fZ;
	pItem->y = fY;
	for(int i=0; i<byCount; i++) {
		if( m_pMain->m_ItemtableArray.GetData(nItemNumber[i]) ) {
			pItem->itemid[i] = nItemNumber[i];
			pItem->count[i] = sCount[i];
		}
	}

	if (!pMap->RegionItemAdd(regionx, regionz, pItem ))
	{
		delete pItem;
		return;
	}

	pUser = m_pMain->GetUserPtr(sUid);
	if (pUser == NULL) 
		return;
	
	send_index = 0;

	SetByte( send_buff, WIZ_ITEM_DROP, send_index );
	SetShort( send_buff, sNid, send_index );
	SetDWORD( send_buff, pItem->bundle_index, send_index );
	if( pUser->m_sPartyIndex == -1 )
		pUser->Send( send_buff, send_index );
	else
		m_pMain->Send_PartyMember( pUser->m_sPartyIndex, send_buff, send_index );
}
コード例 #8
0
ファイル: AISocket.cpp プロジェクト: tuku/snoxd-koserver
void CAISocket::RecvNpcAttack(char* pBuf)
{
	int index = 0, send_index = 0, sid = -1, tid = -1, nHP = 0, temp_damage = 0;
	BYTE type, result, byAttackType = 0;
	float fDir=0.0f;
	short damage = 0;
	CNpc* pNpc = NULL, *pMon = NULL;
	CUser* pUser = NULL;
	char pOutBuf[1024];
	_OBJECT_EVENT* pEvent = NULL;

	type = GetByte(pBuf,index);
	result = GetByte(pBuf,index);
	sid = GetShort(pBuf,index);
	tid = GetShort(pBuf,index);
	damage = GetShort(pBuf,index);
	nHP = GetDWORD(pBuf,index);
	byAttackType = GetByte(pBuf, index);

	//TRACE("CAISocket-RecvNpcAttack : sid=%s, tid=%d, zone_num=%d\n", sid, tid, m_iZoneNum);

	if(type == 0x01)			// user attack -> npc
	{
		pNpc = m_pMain->m_arNpcArray.GetData(tid);
		if(!pNpc)	return;
		pNpc->m_iHP -= damage;
		if( pNpc->m_iHP < 0 )
			pNpc->m_iHP = 0;

		if(result == 0x04)	{								// 마법으로 죽는경우
			SetByte( pOutBuf, WIZ_DEAD, send_index );
			SetShort( pOutBuf, tid, send_index );
			m_pMain->Send_Region(pOutBuf, send_index, pNpc->GetMap(), pNpc->m_sRegion_X, pNpc->m_sRegion_Z, NULL, false);
		}
		else {

			SetByte(pOutBuf, WIZ_ATTACK, send_index);
			SetByte( pOutBuf, byAttackType, send_index );		// 직접:1, 마법:2, 지속마법:3
			//if(result == 0x04)								// 마법으로 죽는경우
			//	SetByte( pOutBuf, 0x02, send_index );
			//else											// 단순공격으로 죽는경우
				SetByte( pOutBuf, result, send_index );
			SetShort( pOutBuf, sid, send_index );
			SetShort( pOutBuf, tid, send_index );
		
			m_pMain->Send_Region(pOutBuf, send_index, pNpc->GetMap(), pNpc->m_sRegion_X, pNpc->m_sRegion_Z, NULL, false);

		}

		pUser = m_pMain->GetUserPtr(sid);
		if (pUser != NULL) 
		{
			pUser->SendTargetHP( 0, tid, -damage ); 
			if( byAttackType != MAGIC_ATTACK && byAttackType != DURATION_ATTACK) {
				pUser->ItemWoreOut(ATTACK, damage);

			// LEFT HAND!!! by Yookozuna
			temp_damage = damage * pUser->m_bMagicTypeLeftHand / 100 ;

			switch (pUser->m_bMagicTypeLeftHand) {	// LEFT HAND!!!
				case ITEM_TYPE_HP_DRAIN :	// HP Drain		
					pUser->HpChange(temp_damage, 0);	
					break;
				case ITEM_TYPE_MP_DRAIN :	// MP Drain		
					pUser->MSpChange(temp_damage);
					break;
				}				
			
			temp_damage = 0;	// reset data;

			// RIGHT HAND!!! by Yookozuna
			temp_damage = damage * pUser->m_bMagicTypeRightHand / 100 ;

			switch (pUser->m_bMagicTypeRightHand) {	// LEFT HAND!!!
				case ITEM_TYPE_HP_DRAIN :	// HP Drain		
					pUser->HpChange(temp_damage, 0);			
					break;
				case ITEM_TYPE_MP_DRAIN :	// MP Drain		
					pUser->MSpChange(temp_damage);
					break;
				}	
//		
			}
		}

		if(result == 0x02 || result == 0x04)		// npc dead
		{
			pNpc->GetMap()->RegionNpcRemove(pNpc->m_sRegion_X, pNpc->m_sRegion_Z, tid);
			
//			TRACE("--- Npc Dead : Npc를 Region에서 삭제처리.. ,, region_x=%d, y=%d\n", pNpc->m_sRegion_X, pNpc->m_sRegion_Z);
			pNpc->m_sRegion_X = 0;		pNpc->m_sRegion_Z = 0;
			pNpc->m_NpcState = NPC_DEAD;
			if( pNpc->m_byObjectType == SPECIAL_OBJECT )	{
				pEvent = pNpc->GetMap()->GetObjectEvent( pNpc->m_sSid );
				if( pEvent )	pEvent->byLife = 0;
			}
			if (pNpc->m_tNpcType == 2 && pUser != NULL) // EXP 
				pUser->GiveItem(900001000, 1);	
		}
	}
	else if(type == 0x02)		// npc attack -> user
	{
		pNpc = m_pMain->m_arNpcArray.GetData(sid);
		if(!pNpc)	return;

		//TRACE("CAISocket-RecvNpcAttack 222 : sid=%s, tid=%d, zone_num=%d\n", sid, tid, m_iZoneNum);
		if( tid >= USER_BAND && tid < NPC_BAND)
		{
			pUser = m_pMain->GetUserPtr(tid);
			if(pUser == NULL)	
				return;

			// sungyong 2002. 02.04
/*			if( sHP <= 0 && pUser->m_pUserData->m_sHp > 0 ) {
				TRACE("Npc Attack : id=%s, result=%d, AI_HP=%d, GM_HP=%d\n", pUser->m_pUserData->m_id, result, sHP, pUser->m_pUserData->m_sHp);
				if(result == 0x02)
					pUser->HpChange(-1000, 1);
			}
			else	
				pUser->HpChange(-damage, 1);
			*/  
			// ~sungyong 2002. 02.04
			if( pUser->m_MagicProcess.m_bMagicState == CASTING ) 
				pUser->m_MagicProcess.IsAvailable( 0, -1, -1, MAGIC_EFFECTING ,0,0,0 );
			pUser->HpChange(-damage, 1, true);
			pUser->ItemWoreOut(DEFENCE, damage);

			SetByte(pOutBuf, WIZ_ATTACK, send_index);
			SetByte( pOutBuf, byAttackType, send_index );
			if(result == 0x03)
				SetByte( pOutBuf, 0x00, send_index );
			else
				SetByte( pOutBuf, result, send_index );
			SetShort( pOutBuf, sid, send_index );
			SetShort( pOutBuf, tid, send_index );
			
			m_pMain->Send_Region(pOutBuf, send_index, pNpc->GetMap(), pNpc->m_sRegion_X, pNpc->m_sRegion_Z, NULL, false);

//			TRACE("RecvNpcAttack : id=%s, result=%d, AI_HP=%d, GM_HP=%d\n", pUser->m_pUserData->m_id, result, sHP, pUser->m_pUserData->m_sHp);
			//TRACE("RecvNpcAttack ==> sid = %d, tid = %d, result = %d\n", sid, tid, result);

			if(result == 0x02) {		// user dead
				if (pUser->m_bResHpType == USER_DEAD)
					return;
				// 유저에게는 바로 데드 패킷을 날림... (한 번 더 보냄, 유령을 없애기 위해서)
				send_index = 0;
				SetByte(pOutBuf, WIZ_DEAD, send_index);
				SetShort(pOutBuf, pUser->GetSocketID(), send_index);
				m_pMain->Send_Region(pOutBuf, send_index, pUser->GetMap(), pUser->m_RegionX, pUser->m_RegionZ);

				pUser->m_bResHpType = USER_DEAD;
				DEBUG_LOG("*** User Dead, id=%s, result=%d, AI_HP=%d, GM_HP=%d, x=%d, z=%d", pUser->m_pUserData->m_id, result, nHP, pUser->m_pUserData->m_sHp, (int)pUser->m_pUserData->m_curx, (int)pUser->m_pUserData->m_curz);

				send_index = 0;
				if( pUser->m_pUserData->m_bFame == COMMAND_CAPTAIN )	{	// 지휘권한이 있는 유저가 죽는다면,, 지휘 권한 박탈
					pUser->m_pUserData->m_bFame = CHIEF;
					SetByte( pOutBuf, WIZ_AUTHORITY_CHANGE, send_index );
					SetByte( pOutBuf, COMMAND_AUTHORITY, send_index );
					SetShort( pOutBuf, pUser->GetSocketID(), send_index );
					SetByte( pOutBuf, pUser->m_pUserData->m_bFame, send_index );
					m_pMain->Send_Region( pOutBuf, send_index, pUser->GetMap(), pUser->m_RegionX, pUser->m_RegionZ );
					// sungyong tw
					pUser->Send( pOutBuf, send_index );
					// ~sungyong tw
					TRACE("---> AISocket->RecvNpcAttack() Dead Captain Deprive - %s\n", pUser->m_pUserData->m_id);
					if( pUser->m_pUserData->m_bNation == KARUS )			m_pMain->Announcement( KARUS_CAPTAIN_DEPRIVE_NOTIFY, KARUS );
					else if( pUser->m_pUserData->m_bNation == ELMORAD )	m_pMain->Announcement( ELMORAD_CAPTAIN_DEPRIVE_NOTIFY, ELMORAD );

				}

				if(pNpc->m_tNpcType == NPC_PATROL_GUARD)	{	// 경비병에게 죽는 경우라면..
					pUser->ExpChange( -pUser->m_iMaxExp/100 );
					//TRACE("RecvNpcAttack : 경험치를 1%깍기 id = %s\n", pUser->m_pUserData->m_id);
				}
				else {
//
					if( pUser->m_pUserData->m_bZone != pUser->m_pUserData->m_bNation && pUser->m_pUserData->m_bZone < 3) {
						pUser->ExpChange(-pUser->m_iMaxExp / 100);
						//TRACE("정말로 1%만 깍였다니까요 ㅠ.ㅠ");
					}
//				
					else {
						pUser->ExpChange( -pUser->m_iMaxExp/20 );
					}
					//TRACE("RecvNpcAttack : 경험치를 5%깍기 id = %s\n", pUser->m_pUserData->m_id);
				}
			}
		}
		else if(tid >= NPC_BAND)		// npc attack -> monster
		{
			pMon = m_pMain->m_arNpcArray.GetData(tid);
			if(!pMon)	return;
			pMon->m_iHP -= damage;
			if( pMon->m_iHP < 0 )
				pMon->m_iHP = 0;

			send_index = 0;
			SetByte(pOutBuf, WIZ_ATTACK, send_index);
			SetByte( pOutBuf, byAttackType, send_index );
			SetByte( pOutBuf, result, send_index );
			SetShort( pOutBuf, sid, send_index );
			SetShort( pOutBuf, tid, send_index );
			if(result == 0x02)	{		// npc dead
				pNpc->GetMap()->RegionNpcRemove(pMon->m_sRegion_X, pMon->m_sRegion_Z, tid);
//				TRACE("--- Npc Dead : Npc를 Region에서 삭제처리.. ,, region_x=%d, y=%d\n", pMon->m_sRegion_X, pMon->m_sRegion_Z);
				pMon->m_sRegion_X = 0;		pMon->m_sRegion_Z = 0;
				pMon->m_NpcState = NPC_DEAD;
				if( pNpc->m_byObjectType == SPECIAL_OBJECT )	{
					pEvent = pNpc->GetMap()->GetObjectEvent( pMon->m_sSid );
					if( pEvent )	pEvent->byLife = 0;
				}
			}

			m_pMain->Send_Region(pOutBuf, send_index, pNpc->GetMap(), pNpc->m_sRegion_X, pNpc->m_sRegion_Z, NULL, false);
		}
	}
}
コード例 #9
0
ファイル: AISocket.cpp プロジェクト: tuku/snoxd-koserver
void CAISocket::RecvMagicAttackResult(char* pBuf)
{
	int index = 0, send_index = 1, sid = -1, tid = -1, magicid=0;
	BYTE byCommand; 
	short data0, data1, data2, data3, data4, data5;

	CNpc* pNpc = NULL;
	CUser* pUser = NULL;
	char send_buff[1024];

	//byType = GetByte(pBuf,index);				// who ( 1:mon->user 2:mon->mon )
	//byAttackType = GetByte(pBuf,index);			// attack type ( 1:long attack, 2:magic attack
	byCommand = GetByte(pBuf,index);			// magic type ( 1:casting, 2:flying, 3:effecting, 4:fail )
	magicid = GetDWORD(pBuf,index);
	sid = GetShort(pBuf,index);
	tid = GetShort(pBuf,index);
	data0 = GetShort(pBuf,index);
	data1 = GetShort(pBuf,index);
	data2 = GetShort(pBuf,index);
	data3 = GetShort(pBuf,index);
	data4 = GetShort(pBuf,index);
	data5 = GetShort(pBuf,index);

	SetByte( send_buff, byCommand, send_index );
	SetDWORD( send_buff, magicid, send_index );
	SetShort( send_buff, sid, send_index );
	SetShort( send_buff, tid, send_index );
	SetShort( send_buff, data0, send_index );
	SetShort( send_buff, data1, send_index );
	SetShort( send_buff, data2, send_index );
	SetShort( send_buff, data3, send_index );
	SetShort( send_buff, data4, send_index );
	SetShort( send_buff, data5, send_index );

	if(byCommand == 0x01)	{		// casting
		pNpc = m_pMain->m_arNpcArray.GetData(sid);
		if(!pNpc)	return;
		index = 0;
		SetByte( send_buff, WIZ_MAGIC_PROCESS, index );
		m_pMain->Send_Region(send_buff, send_index, pNpc->GetMap(), pNpc->m_sRegion_X, pNpc->m_sRegion_Z, NULL, false);
	}
	else if(byCommand == 0x03)	{	// effecting
		//pNpc = m_pMain->m_arNpcArray.GetData(tid);
		//if(!pNpc)	return;
		if( sid >= USER_BAND && sid < NPC_BAND)	{
			pUser = m_pMain->GetUserPtr(sid);
			if (pUser == NULL || pUser->isDead())
				return;

			index = 0;
			SetByte( send_buff, WIZ_MAGIC_PROCESS, index );
			m_pMain->Send_Region(send_buff, send_index, pUser->GetMap(), pUser->m_RegionX, pUser->m_RegionZ, NULL, false);
		}
		else if(sid >= NPC_BAND)	{
			if(tid >= NPC_BAND)	{
				pNpc = m_pMain->m_arNpcArray.GetData(tid);
				if(!pNpc)	return;
				index = 0;
				SetByte( send_buff, WIZ_MAGIC_PROCESS, index );
				m_pMain->Send_Region(send_buff, send_index, pNpc->GetMap(), pNpc->m_sRegion_X, pNpc->m_sRegion_Z, NULL, false);
				return;
			}
			send_index = 0;
			SetByte( send_buff, byCommand, send_index );
			SetDWORD( send_buff, magicid, send_index );
			SetShort( send_buff, sid, send_index );
			SetShort( send_buff, tid, send_index );
			SetShort( send_buff, data0, send_index );
			SetShort( send_buff, data1, send_index );
			SetShort( send_buff, data2, send_index );
			SetShort( send_buff, data3, send_index );
			SetShort( send_buff, data4, send_index );
			SetShort( send_buff, data5, send_index );
			m_MagicProcess.MagicPacket(send_buff, send_index);
		}
	}
	
}
コード例 #10
0
/***
 * We've been told from another server that a user's status in the clan has changed.
 ***/
void CUdpSocket::RecvModifyFame(char* pBuf, BYTE command)
{
	CString clanNotice;
	int index = 0, knightsindex = 0, vicechief = 0;
	char userid[MAX_ID_SIZE+1];

	knightsindex = GetShort(pBuf, index);
	if (!GetKOString(pBuf, userid, index, MAX_ID_SIZE))
		return;

	CUser *pTUser = g_pMain->GetUserPtr(userid, TYPE_CHARACTER);
	CKnights *pKnights = g_pMain->GetClanPtr(knightsindex);
	if (pKnights == NULL)
		return;

	switch (command)
	{
	case KNIGHTS_REMOVE:
	case KNIGHTS_REJECT:
		if (pTUser)
		{
			pTUser->SetClanID(0);
			pTUser->m_pUserData->m_bFame = 0;

			if (command == KNIGHTS_REMOVE)
				clanNotice = g_pMain->GetServerResource(IDS_KNIGHTS_REMOVE);
		}

		g_pMain->m_KnightsManager.RemoveKnightsUser(knightsindex, userid);
		break;

	case KNIGHTS_ADMIT:
		if (pTUser)
			pTUser->m_pUserData->m_bFame = KNIGHT;
		break;

	case KNIGHTS_CHIEF+0x10:
		if (pTUser)
		{
			pTUser->m_pUserData->m_bFame = CHIEF;
			clanNotice = g_pMain->GetServerResource(IDS_KNIGHTS_CHIEF);
		}
		break;

	case KNIGHTS_VICECHIEF+0x10:
		if (pTUser)
		{
			pTUser->m_pUserData->m_bFame = VICECHIEF;
			clanNotice = g_pMain->GetServerResource(IDS_KNIGHTS_VICECHIEF);
		}
		break;

	case KNIGHTS_OFFICER+0x10:
		if (pTUser)
			pTUser->m_pUserData->m_bFame = OFFICER;
		break;

	case KNIGHTS_PUNISH+0x10:
		if (pTUser)
			pTUser->m_pUserData->m_bFame = PUNISH;
		break;
	}

	if (pTUser != NULL)
		pTUser->SendClanUserStatusUpdate(command == KNIGHTS_REMOVE);

	if (clanNotice.GetLength() == 0)
		return;

	Packet result;

	// Construct the clan system chat packet
	pKnights->ConstructChatPacket(result, clanNotice, pTUser != NULL ? pTUser->m_pUserData->m_id : userid); 

	// If we've been removed from a clan, tell the user as well (since they're no longer in the clan)
	if (command == KNIGHTS_REMOVE && pTUser != NULL)
		pTUser->Send(&result);

	// Otherwise, since we're actually in the clan, we don't need to be explicitly told what happened.
	if (pKnights != NULL)
		pKnights->Send(&result);
}
コード例 #11
0
ファイル: AISocket.cpp プロジェクト: tuku/snoxd-koserver
// ai server에 처음 접속시 npc의 모든 정보를 받아온다..
void CAISocket::RecvNpcInfoAll(char* pBuf)
{
	int index = 0;
	BYTE		byCount = 0;			// 마리수
	BYTE        byType;				// 0:처음에 등장하지 않는 몬스터, 1:등장
	short		nid;				// NPC index
	short		sid;				// NPC index
	BYTE		bZone;				// Current zone number
	short		sPid;				// NPC Picture Number
	short		sSize = 100;				// NPC Size
	int			iweapon_1;
	int			iweapon_2;
	char		szName[MAX_NPC_SIZE+1];		// NPC Name
	BYTE		byGroup;		// 소속 집단
	BYTE		byLevel;		// level
	float		fPosX;			// X Position
	float		fPosZ;			// Z Position
	float		fPosY;			// Y Position
	BYTE		byDirection;	// 
	BYTE		tNpcType;		// 00	: Monster
								// 01	: NPC
	int		iSellingGroup;
  	int		nMaxHP;			// 최대 HP
	int		nHP;			// 현재 HP
	BYTE		byGateOpen;		// 성문일경우 열림과 닫힘 정보
	short		sHitRate;
	BYTE		byObjectType;	// 보통 : 0, 특수 : 1

	byCount = GetByte(pBuf, index);

	for(int i=0; i<byCount; i++)
	{
		byType = GetByte(pBuf, index);
		nid = GetShort(pBuf, index);
		sid = GetShort(pBuf, index);
		sPid = GetShort(pBuf, index);
		sSize = GetShort(pBuf, index);
		iweapon_1 = GetDWORD(pBuf, index);
		iweapon_2 = GetDWORD(pBuf, index);
		bZone = GetByte(pBuf, index);
		int nLength = GetVarString(szName, pBuf, sizeof(BYTE), index);
		byGroup = GetByte(pBuf, index);
		byLevel  = GetByte(pBuf, index);
		fPosX = Getfloat(pBuf, index);
		fPosZ = Getfloat(pBuf, index);
		fPosY = Getfloat(pBuf, index);
		byDirection = GetByte(pBuf, index);
		tNpcType = GetByte(pBuf, index);
		iSellingGroup = GetDWORD(pBuf, index);
		nMaxHP = GetDWORD(pBuf, index);
		nHP = GetDWORD(pBuf, index);
		byGateOpen = GetByte(pBuf, index);
		sHitRate = GetShort(pBuf, index);
		byObjectType = GetByte(pBuf, index);

		//TRACE("RecvNpcInfoAll  : nid=%d, szName=%s, count=%d\n", nid, szName, byCount);

		if(nLength < 0 || nLength > MAX_NPC_SIZE)	{
			TRACE("#### RecvNpcInfoAll Fail : szName=%s\n", szName);
			continue;		// 잘못된 monster 아이디 
		}

		//TRACE("Recv --> NpcUserInfo : uid = %d, x=%f, z=%f.. \n", nid, fPosX, fPosZ);

		CNpc* pNpc = NULL;
		pNpc = new CNpc;
		if(pNpc == NULL)	{ 
			TRACE("#### Recv --> NpcUserInfoAll POINT Fail: uid=%d, sid=%d, name=%s, zone=%d, x=%f, z=%f.. \n", nid, sPid, szName, bZone, fPosX, fPosZ);
			continue;
		}
		pNpc->Initialize();

		pNpc->m_sNid = nid;
		pNpc->m_sSid = sid;
		pNpc->m_sPid = sPid;
		pNpc->m_sSize = sSize;
		pNpc->m_iWeapon_1 = iweapon_1;
		pNpc->m_iWeapon_2 = iweapon_2;
		strcpy(pNpc->m_strName, szName);
		pNpc->m_byGroup = byGroup;
		pNpc->m_byLevel = byLevel;
		pNpc->m_bCurZone = bZone;
		pNpc->m_pMap = m_pMain->GetZoneByID(bZone);
		pNpc->m_fCurX = fPosX;
		pNpc->m_fCurZ = fPosZ;
		pNpc->m_fCurY = fPosY;
		pNpc->m_byDirection = byDirection;
		pNpc->m_NpcState = NPC_LIVE;
		pNpc->m_tNpcType = tNpcType;
		pNpc->m_iSellingGroup = iSellingGroup;
		pNpc->m_iMaxHP = nMaxHP;
		pNpc->m_iHP = nHP;
		pNpc->m_byGateOpen = byGateOpen;
		pNpc->m_sHitRate = sHitRate;
		pNpc->m_byObjectType = byObjectType;
		pNpc->m_NpcState = NPC_LIVE;

		int nRegX = (int)fPosX / VIEW_DISTANCE;
		int nRegZ = (int)fPosZ / VIEW_DISTANCE;

		pNpc->m_sRegion_X = nRegX;
		pNpc->m_sRegion_Z = nRegZ;

		if (pNpc->GetMap() == NULL)
		{
			delete pNpc;
			pNpc = NULL;
			continue;
		}

		_OBJECT_EVENT* pEvent = NULL;
		if (pNpc->m_byObjectType == SPECIAL_OBJECT)
		{
			pEvent = pNpc->GetMap()->GetObjectEvent(pNpc->m_sSid);
			if( pEvent )	pEvent->byLife = 1;
		}

	//	TRACE("Recv --> NpcUserInfoAll : uid=%d, sid=%d, name=%s, x=%f, z=%f. gate=%d, objecttype=%d \n", nid, sPid, szName, fPosX, fPosZ, byGateOpen, byObjectType);

		if( !m_pMain->m_arNpcArray.PutData( pNpc->m_sNid, pNpc) ) {
			TRACE("Npc PutData Fail - %d\n", pNpc->m_sNid);
			delete pNpc;
			pNpc = NULL;
			continue;
		}

		if( byType == 0 )	{
			TRACE("Recv --> NpcUserInfoAll : 등록하면 안돼여,, uid=%d, sid=%d, name=%s\n", nid, sPid, szName);
			continue;		// region에 등록하지 말기...
		}

		pNpc->GetMap()->RegionNpcAdd(pNpc->m_sRegion_X, pNpc->m_sRegion_Z, pNpc->m_sNid);
	}
}
コード例 #12
0
void CUdpSocket::RecvBattleEvent(char *pBuf)
{
	int index = 0, send_index = 0, udp_index = 0;
	int nType = 0, nResult = 0, nLen = 0, nKillKarus = 0, nElmoKill = 0;
	char strMaxUserName[MAX_ID_SIZE+1], strKnightsName[MAX_ID_SIZE+1];
	char finalstr[1024];

	std::string buff;

	nType = GetByte( pBuf, index );
	nResult = GetByte(pBuf, index);

	if( nType == BATTLE_EVENT_OPEN )	{
	}
	else if( nType == BATTLE_MAP_EVENT_RESULT )	{
		if( g_pMain->m_byBattleOpen == NO_BATTLE )	{
			TRACE("#### UDP RecvBattleEvent Fail : battleopen = %d, type = %d\n", g_pMain->m_byBattleOpen, nType);
			return;
		}
		if( nResult == KARUS )	{
			//TRACE("--> UDP RecvBattleEvent : 카루스 땅으로 넘어갈 수 있어\n");
			g_pMain->m_byKarusOpenFlag = 1;		// 카루스 땅으로 넘어갈 수 있어
		}
		else if( nResult == ELMORAD )	{
			//TRACE("--> UDP  RecvBattleEvent : 엘모 땅으로 넘어갈 수 있어\n");
			g_pMain->m_byElmoradOpenFlag = 1;	// 엘모 땅으로 넘어갈 수 있어
		}
	}
	else if( nType == BATTLE_EVENT_RESULT )	{
		if( g_pMain->m_byBattleOpen == NO_BATTLE )	{
			TRACE("####  UDP  RecvBattleEvent Fail : battleopen = %d, type=%d\n", g_pMain->m_byBattleOpen, nType);
			return;
		}
		if( nResult == KARUS )	{
			//TRACE("-->  UDP RecvBattleEvent : 카루스가 승리하였습니다.\n");
		}
		else if( nResult == ELMORAD )	{
			//TRACE("-->  UDP RecvBattleEvent : 엘모라드가 승리하였습니다.\n");
		}

		g_pMain->m_bVictory = nResult;
		g_pMain->m_byOldVictory = nResult;
		g_pMain->m_byKarusOpenFlag = 0;		// 카루스 땅으로 넘어갈 수 없도록
		g_pMain->m_byElmoradOpenFlag = 0;	// 엘모 땅으로 넘어갈 수 없도록
		g_pMain->m_byBanishFlag = 1;
	}
	else if( nType == BATTLE_EVENT_MAX_USER )	{
		nLen = GetByte(pBuf, index);
		if (!GetKOString(pBuf, strKnightsName, index, MAX_ID_SIZE)
			|| GetKOString(pBuf, strMaxUserName, index, MAX_ID_SIZE))
			return;

		int nResourceID = 0;
		switch (nResult)
		{
		case 1: // captain
			nResourceID = IDS_KILL_CAPTAIN;
			break;
		case 2: // keeper

		case 7: // warders?
		case 8:
			nResourceID = IDS_KILL_GATEKEEPER;
			break;

		case 3: // Karus sentry
			nResourceID = IDS_KILL_KARUS_GUARD1;
			break;
		case 4: // Karus sentry
			nResourceID = IDS_KILL_KARUS_GUARD2;
			break;
		case 5: // El Morad sentry
			nResourceID = IDS_KILL_ELMO_GUARD1;
			break;
		case 6: // El Morad sentry
			nResourceID = IDS_KILL_ELMO_GUARD2;
			break;
		}

		if (nResourceID == 0)
		{
			TRACE("RecvBattleEvent: could not establish resource for result %d", nResult);
			return;
		}

		_snprintf(finalstr, sizeof(finalstr), g_pMain->GetServerResource(nResourceID), strKnightsName, strMaxUserName);

#if 0
		SetByte( send_buff, WIZ_CHAT, send_index );
		SetByte( send_buff, WAR_SYSTEM_CHAT, send_index );
		SetByte( send_buff, 1, send_index );
		SetShort( send_buff, -1, send_index );
		SetKOString( send_buff, finalstr, send_index );
		g_pMain->Send_All( send_buff, send_index );

		send_index = 0;
		SetByte( send_buff, WIZ_CHAT, send_index );
		SetByte( send_buff, PUBLIC_CHAT, send_index );
		SetByte( send_buff, 1, send_index );
		SetShort( send_buff, -1, send_index );
		SetKOString( send_buff, finalstr, send_index );
		g_pMain->Send_All( send_buff, send_index );
#endif
	}
	else if( nType == BATTLE_EVENT_KILL_USER )	{
		if( nResult == 1 )	{
			nKillKarus = GetShort( pBuf, index );
			nElmoKill = GetShort( pBuf, index );
			g_pMain->m_sKarusDead = g_pMain->m_sKarusDead + nKillKarus;
			g_pMain->m_sElmoradDead = g_pMain->m_sElmoradDead + nElmoKill;

			//TRACE("-->  UDP RecvBattleEvent type = 1 : 적국 유저 죽인수 : karus=%d->%d, elmo=%d->%d\n", nKillKarus, g_pMain->m_sKarusDead, nElmoKill, g_pMain->m_sElmoradDead);
			Packet result(UDP_BATTLE_EVENT_PACKET, uint8(BATTLE_EVENT_KILL_USER));
			result << uint8(2) << g_pMain->m_sKarusDead << g_pMain->m_sElmoradDead;
			g_pMain->Send_UDP_All(&result);
		}
		else if( nResult == 2 )	{
			nKillKarus = GetShort( pBuf, index );
			nElmoKill = GetShort( pBuf, index );

			//TRACE("-->  UDP RecvBattleEvent type = 2 : 적국 유저 죽인수 : karus=%d->%d, elmo=%d->%d\n", g_pMain->m_sKarusDead, nKillKarus, g_pMain->m_sElmoradDead, nElmoKill);

			g_pMain->m_sKarusDead = nKillKarus;
			g_pMain->m_sElmoradDead = nElmoKill;
		}
	}

}
コード例 #13
0
void CUser::MoveProcess(char *pBuf )
{
	ASSERT(GetMap() != NULL);
	if( m_bWarp ) return;
		
	int index = 0, send_index = 0, region = 0;
	WORD will_x, will_z;
	short will_y, speed=0;
	float real_x, real_z, real_y;
	BYTE echo;
	char send_buff[32];

	will_x = GetShort( pBuf, index );
	will_z = GetShort( pBuf, index );
	will_y = GetShort( pBuf, index );

	speed = GetShort( pBuf, index );
	echo = GetByte( pBuf, index );

	real_x = will_x/10.0f; real_z = will_z/10.0f; real_y = will_y/10.0f;

	if (GetMap()->IsValidPosition(real_x, real_z, real_y) == FALSE) 
		return;

	if (isDead() && speed != 0)
		TRACE("### MoveProcess Fail : name=%s(%d), m_bResHpType=%d, hp=%d, speed=%d, x=%d, z=%d ###\n", m_pUserData->m_id, m_Sid, m_bResHpType, m_pUserData->m_sHp, speed, (int)m_pUserData->m_curx, (int)m_pUserData->m_curz);

	if( speed != 0 ) {
		m_pUserData->m_curx = m_fWill_x;	// ????? ??? ?????g?? ??????g?? ????...
		m_pUserData->m_curz = m_fWill_z;
		m_pUserData->m_cury = m_fWill_y;

		m_fWill_x = will_x/10.0f;	// ?????g?? ???....
		m_fWill_z = will_z/10.0f;
		m_fWill_y = will_y/10.0f;
	}
	else {
		m_pUserData->m_curx = m_fWill_x = will_x/10.0f;	// ?????g == ???? ??g...
		m_pUserData->m_curz = m_fWill_z = will_z/10.0f;
		m_pUserData->m_cury = m_fWill_y = will_y/10.0f;
	}

	SetByte( send_buff, WIZ_MOVE, send_index );
	SetShort( send_buff, m_Sid, send_index );
	SetShort( send_buff, will_x, send_index );
	SetShort( send_buff, will_z, send_index );
	SetShort( send_buff, will_y, send_index );
	SetShort( send_buff, speed, send_index );
	SetByte( send_buff, echo, send_index );

	RegisterRegion();
	m_pMain->Send_Region( send_buff, send_index, GetMap(), m_RegionX, m_RegionZ, NULL, false );

	GetMap()->CheckEvent( real_x, real_z, this );

	send_index = 0;
	SetByte( send_buff, AG_USER_MOVE, send_index );
	SetShort( send_buff, m_Sid, send_index );
	Setfloat( send_buff, m_fWill_x, send_index );
	Setfloat( send_buff, m_fWill_z, send_index );
	Setfloat( send_buff, m_fWill_y, send_index );
	SetShort( send_buff, speed, send_index );
	
	m_pMain->Send_AIServer(send_buff, send_index);
}
コード例 #14
0
ファイル: midisource_hmi.cpp プロジェクト: Blzut3/gzdoom
void HMISong::SetupForHMI(int len)
{
	int i, p;

	ReadVarLen = ReadVarLenHMI;
	NumTracks = GetShort(MusHeader + HMI_TRACK_COUNT_OFFSET);

	if (NumTracks <= 0)
	{
		return;
	}

	// The division is the number of pulses per quarter note (PPQN).
	// HMI files have two values here, a full value and a quarter value. Some games, 
	// notably Quarantines, have identical values for some reason, so it's safer to
	// use the quarter value and multiply it by four than to trust the full value.
	Division = GetShort(MusHeader + HMI_DIVISION_OFFSET) << 2;
	Tempo = InitialTempo = 4000000;

	Tracks = new TrackInfo[NumTracks + 1];
	int track_dir = GetInt(MusHeader + HMI_TRACK_DIR_PTR_OFFSET);

	// Gather information about each track
	for (i = 0, p = 0; i < NumTracks; ++i)
	{
		int start = GetInt(MusHeader + track_dir + i*4);
		int tracklen, datastart;

		if (start > len - HMITRACK_DESIGNATION_OFFSET - 4)
		{ // Track is incomplete.
			continue;
		}

		// BTW, HMI does not actually check the track header.
		if (memcmp(MusHeader + start, TRACK_MAGIC, 13) != 0)
		{
			continue;
		}

		// The track ends where the next one begins. If this is the
		// last track, then it ends at the end of the file.
		if (i == NumTracks - 1)
		{
			tracklen = len - start;
		}
		else
		{
			tracklen = GetInt(MusHeader + track_dir + i*4 + 4) - start;
		}
		// Clamp incomplete tracks to the end of the file.
		tracklen = MIN(tracklen, len - start);
		if (tracklen <= 0)
		{
			continue;
		}

		// Offset to actual MIDI events.
		datastart = GetInt(MusHeader + start + HMITRACK_DATA_PTR_OFFSET);
		tracklen -= datastart;
		if (tracklen <= 0)
		{
			continue;
		}

		// Store track information
		Tracks[p].TrackBegin = MusHeader + start + datastart;
		Tracks[p].TrackP = 0;
		Tracks[p].MaxTrackP = tracklen;

		// Retrieve track designations. We can't check them yet, since we have not yet
		// connected to the MIDI device.
		for (int ii = 0; ii < NUM_HMI_DESIGNATIONS; ++ii)
		{
			Tracks[p].Designation[ii] = GetShort(MusHeader + start + HMITRACK_DESIGNATION_OFFSET + ii*2);
		}

		p++;
	}

	// In case there were fewer actual chunks in the file than the
	// header specified, update NumTracks with the current value of p.
	NumTracks = p;
}
コード例 #15
0
ファイル: GameMessage.cpp プロジェクト: rockfireredmoon/iceee
//
//AbilityActiveMessage
//
int AbilityActiveMessage::handleMessage(SimulatorThread *sim, CharacterServerData *pld,
		SimulatorQuery *query, CreatureInstance *creatureInstance) {

	creatureInstance->RemoveNoncombatantStatus("abilityActivate");

	// Flags appears to be intended for party casting, but isn't used outside the /do command.
	// We don't use it in the server, but we still need to read it from the message.
	short aID = GetShort(&sim->readPtr[sim->ReadPos], sim->ReadPos);            //Ability ID

	// Unused?
	GetByte(&sim->readPtr[sim->ReadPos], sim->ReadPos);
	//unsigned char flags = GetByte(&sim->readPtr[sim->ReadPos], sim->ReadPos);   //flags

	unsigned char ground = GetByte(&sim->readPtr[sim->ReadPos], sim->ReadPos);  //ground
	float x, y, z;

	//LogMessageL(MSG_SHOW, "abilityActivate: %d, flags: %d", aID, flags);

	if (ground != 0) {
		x = GetFloat(&sim->RecBuf[sim->ReadPos], sim->ReadPos);
		y = GetFloat(&sim->RecBuf[sim->ReadPos], sim->ReadPos);
		z = GetFloat(&sim->RecBuf[sim->ReadPos], sim->ReadPos);
		creatureInstance->ab[0].SetPosition(x, y, z);
		//LogMessageL(MSG_DIAGV, "ground: %d, x: %g, y: %g, z: %g", ground, x, y, z);
	}

	if (creatureInstance->serverFlags & ServerFlags::IsTransformed) {
		const Ability2::AbilityEntry2 *abData =
				g_AbilityManager.GetAbilityPtrByID(aID);
		if (abData != NULL) {
			/* TODO: old junk, update or remove this
			 if(abData->isMagic == true)
			 {
			 sim->SendInfoMessage("You may not use elemental abilities while transformed.", INFOMSG_INFO);
			 return;
			 }
			 if(abData->isRanged == true)
			 {
			 sim->SendInfoMessage("You may not use ranged abilities while transformed.", INFOMSG_INFO);
			 return;
			 }
			 */
		}
	}

	if (aID == g_JumpConstant) {
		if (sim->IsGMInvisible() == false)
			sim->AddMessage(pld->CreatureID, 0, BCM_ActorJump);
	} else {
		bool allow = false;
		if (sim->CheckPermissionSimple(Perm_Account, Permission_Debug | Permission_Admin | Permission_Developer) == true)
			allow = true;
		else if (pld->charPtr->abilityList.GetAbilityIndex(aID) >= 0)
			allow = true;
		else {
			if (g_AbilityManager.IsGlobalIntrinsicAbility(aID) == true)
				allow = true;
		}

		if (allow == true) {
			creatureInstance->RequestAbilityActivation(aID);
			if (sim->TargetRarityAboveNormal() == false) {
				if (pld->NotifyCast(creatureInstance->CurrentX,
						creatureInstance->CurrentZ, aID) == true) {
					CreatureInstance *target = creatureInstance->CurrentTarget.targ;
					const char *targetName = "no target";
					int targetID = 0;
					if (target != NULL) {
						targetID = target->CreatureID;
						targetName = target->css.display_name;
					}
					g_Logs.cheat->info(
							"[BOT] Attacks in area by %s @ %d:%d,%d(%d) (%d:%s) [%s:%d]",
							creatureInstance->css.display_name, pld->CurrentZoneID,
							creatureInstance->CurrentX, creatureInstance->CurrentZ,
							creatureInstance->Rotation, aID,
							g_AbilityManager.GetAbilityNameByID(aID),
							targetName, targetID);
				}
			}
		}
	}

	return 0;
}
コード例 #16
0
ファイル: GameMessage.cpp プロジェクト: rockfireredmoon/iceee
//
//UpdateVelocityMessage
//
int UpdateVelocityMessage::handleMessage(SimulatorThread *sim, CharacterServerData *pld,
		SimulatorQuery *query, CreatureInstance *creatureInstance) {

	if (g_ServerTime < pld->MovementBlockTime) {
		creatureInstance->Speed = 0;
		return 0;
	}
	//When entering a new zone from a portal, a velocity update always seems to be sent.
	//This is designed to block that message from interrupting the noncombat status.
	if (pld->IgnoreNextMovement == true)
		pld->IgnoreNextMovement = false;
	else
		creatureInstance->RemoveNoncombatantStatus("updateVelocity");

	int x = GetShort(&sim->readPtr[sim->ReadPos], sim->ReadPos);
	int z = GetShort(&sim->readPtr[sim->ReadPos], sim->ReadPos);
	int y = GetShort(&sim->readPtr[sim->ReadPos], sim->ReadPos);
	creatureInstance->Heading = GetByte(&sim->readPtr[sim->ReadPos], sim->ReadPos);
	creatureInstance->Rotation = GetByte(&sim->readPtr[sim->ReadPos], sim->ReadPos);
	int speed = GetByte(&sim->readPtr[sim->ReadPos], sim->ReadPos);

//	LogMessageL(MSG_SHOW, "Heading:%d, Rot:%d, Spd:%d, X: %d, Y: %d, Z: %d", creatureInstance->Heading, creatureInstance->Rotation, speed, x, y, z);

	if (g_Config.FallDamage && !creatureInstance->actInst->mZoneDefPtr->mGrove) {
		int deltaY = creatureInstance->CurrentY - y;
		if (deltaY >= 30)
			pld->bFalling = true;
		if (pld->bFalling == true) {
			pld->DeltaY += deltaY;
			g_Logs.simulator->debug("[%v] Delta: %v, %v", sim->InternalID, deltaY,
					pld->DeltaY);
		}
		if (deltaY < 30) {
			if (pld->bFalling == true) {
				creatureInstance->CheckFallDamage(pld->DeltaY);
				g_Logs.simulator->debug("[%v] Damage: %v", sim->InternalID,
						pld->DeltaY);
				pld->bFalling = false;
			}
			pld->DeltaY = 0;
		}
	}

	if (g_Config.HasAdministrativeBehaviorFlag(ADMIN_BEHAVIOR_VERIFYSPEED)
			== true) {
		if (sim->CheckPermissionSimple(Perm_Account, Permission_Debug | Permission_Admin | Permission_Developer) == false) {
			int xlen = abs(x - (creatureInstance->CurrentX & 0xFFFF));
			int zlen = abs(z - (creatureInstance->CurrentZ & 0xFFFF));
			if (xlen < SimulatorThread::OverflowThreshold && zlen < SimulatorThread::OverflowThreshold) {
				int pspeed = 120 + creatureInstance->css.mod_movement;
				int distPerSecond = (int) (((float) pspeed / 100.0F) * 40.0F);
				//The number of units to move for this update.
				if (speed > pspeed || xlen > distPerSecond
						|| zlen > distPerSecond) {
					g_Logs.cheat->warn(
							"[SPEED] Spd: %d / %d, xlen: %d, zlen: %d (%d)",
							speed, pspeed, xlen, zlen, distPerSecond);
					return PrepExt_GeneralMoveUpdate(sim->SendBuf, creatureInstance);
				}
			}
		}
	}

	creatureInstance->Speed = speed;

	int oldX = creatureInstance->CurrentX;
	int oldZ = creatureInstance->CurrentZ;
	int newX = oldX;
	int newZ = oldZ;

	//Since these updates are unsigned short, the maximum value they can relay
	//is 65535.  Some maps are much larger (Europe), thus some kind of overflow
	//handling must be supplied to prevent characters from having their
	//position reach 0. Check for an overflow by comparing the new location
	//with the last location.  If the distance is too great, a rollover
	//must've happened (although coordinate warping might be a possibility
	//too?) If the resulting short value is small, it means it overflowed
	//into a higher value.  If not, it underflowed into a smaller value.
	if (abs(x - (oldX & 0xFFFF)) >= SimulatorThread::OverflowThreshold) {
		if (x < SimulatorThread::OverflowThreshold)
			newX += SimulatorThread::OverflowAdditive;
		else
			newX -= SimulatorThread::OverflowAdditive;
	}
	if (abs(z - (oldZ & 0xFFFF)) >= SimulatorThread::OverflowThreshold) {
		if (z < SimulatorThread::OverflowThreshold)
			newZ += SimulatorThread::OverflowAdditive;
		else
			newZ -= SimulatorThread::OverflowAdditive;
	}

	//Zero out the lower short, then OR it back with the short coords we received from the client.
	newX = (newX ^ (newX & 0xFFFF)) | x;
	newZ = (newZ ^ (newZ & 0xFFFF)) | z;
	creatureInstance->CurrentX = newX;
	creatureInstance->CurrentY = y;
	creatureInstance->CurrentZ = newZ;

	//LogMessageL(MSG_SHOW, "Loc: X:%d, Y:%d, Z:%d", x, y, z);
	//LogMessageL(MSG_SHOW, "Vel: Hd:%d, Rot:%d, Spd:%d", creatureInstance->Heading, creatureInstance->Rotation, creatureInstance->Speed);

	if (creatureInstance->Speed != 0) {
		//Check movement timers.
		int xlen = newX - oldX;
		int zlen = newZ - oldZ;
		float offset = sqrt((float) ((xlen * xlen) + (zlen * zlen)));
		creatureInstance->CheckMovement(offset);
		pld->TotalDistanceMoved += (int) offset;

		//Movement data verification against cheats.  Only run it for normal players.
		//If administrative /setstat command was used to increase speed above 255 (speed is 1 byte)
		//the expected velocity won't match.

		//The client uses a recurring event pulse to send the avatar's velocity updates to the server.
		//The pulse activates at 0.25 second intervals, regardless of whether movement occurred.
		//If the client's update flag is true (at least some movement happened), the update is sent
		//with the player's current position and rotation, then the update flag is cleared.  The
		//closed beta does not use any forced updates, although the client function allows that as
		//an optional parameter (forced updating would send the velocity update immediately,
		//independently from the update pulse, and would not trigger the update flag.

		//The pulse is not always accurate, and can vary with framerate.  Also, when first logging in
		//the pulse seems to be ignored, instead sending sporadic updates whenever required.  For example,
		//autorunning into a hill too steep to climb produces an indefinite flood of updates.  At some
		//currently unknown point, the pulse seems to take over and subsequent floods will stop.

		//There are tons of weird cases where verification fails on legit movement, so it may be necessary
		//to just disable it entirely.

		if(g_Config.VerifyMovement == true && !sim->CheckPermissionSimple(Perm_Account, Permission_Admin | Permission_Developer))
				{
			int expectedSpeed = 100 + creatureInstance->css.base_movement
					+ creatureInstance->css.mod_movement;

			//The heading and rotation fields use only a single byte (0 to 255) to represent 360 degree
			//rotation.  So 90 degrees (360/4) -> (255/4) = 64.
			//Usually if we're moving backward in a single direction (pressing Backward only)
			//then the difference is almost always ~128.  However, if we're moving Left or Right while
			//moving backward, sometimes heading and rotation is the same so we can't judge by that.
			//Instead we have to look at the incoming speed.  Since moving backward is half speed,
			//division may be off slightly so we allow a small tolerance.
			int halfExpected = abs(speed - (expectedSpeed / 2));
			if ((speed != expectedSpeed) && (halfExpected > 3)) {
				g_Logs.cheat->info(
						"[SPEED] Unexpected speed by %s @ Zn:%d,X%d,Y%d, Spd:%d, Expected:%d",
						creatureInstance->css.display_name, pld->CurrentZoneID, newX,
						newZ, speed, expectedSpeed);
			} else {
				//Moving backwards, change to half speed for distance calculations.
				if ((speed != expectedSpeed) && (halfExpected <= 3))
					expectedSpeed /= 2;
			}
			//Movement updates are typically every 250 milliseconds, but even on localhost can vary a bit.
			//Using the client, update intervals of ~218ms were semi common.
			unsigned long timeSinceLastMovement = g_ServerTime
					- pld->MovementTime;
			/* Removed: natural latency triggers this so often that it spams too many logs messages.
			 if(timeSinceLastMovement < 200)
			 {
			 Debug::cheatLogger.Log("[SPEED] Rapid request by %s @ Zn:%d,X%d,Y%d, Spd:%d, Time:%lu", creatureInstance->css.display_name, pld->CurrentZoneID, newX, newZ, speed, timeSinceLastMovement);
			 LogMessageL(MSG_SHOW, "[SPEED] Rapid request by %s @ Zn:%d,X%d,Y%d, Spd:%d, Time:%lu", creatureInstance->css.display_name, pld->CurrentZoneID, newX, newZ, speed, timeSinceLastMovement);
			 }
			 */

			//We want to limit this to a quarter second so that we can calculate our expected
			//distance correctly, accepting lower update intervals but not large intervals which
			//would otherwise translate to potentially huge gaps with spoofed movement.
			//if(timeSinceLastMovement > 250)
			timeSinceLastMovement = 250;

			//Calculate how far the creature should have moved.  Default speed is 100, so
			//convert that into an expected distance while factoring the incoming time interval
			//and a 50% tolerance.
			float expectedOffset = ((expectedSpeed / 100.0F)
					* DEFAULT_CREATURE_SPEED)
					* (timeSinceLastMovement / 1000.0F) * 1.5F;

			// Disabled: was testing incoming movement for verification but it doesn't really help.
			/*
			 Sleep(1);
			 g_Log.AddMessageFormat("Offset:%g, Expected:%g", offset, expectedOffset);
			 */

			if (offset > expectedOffset) {
				g_Logs.cheat->info(
						"[SPEED] Moved too far by %s @ Zn:%d,X%d,Z%d, Spd:%d, Offset X:%d,Z:%d  Moved:%g/Expected:%g",
						creatureInstance->css.display_name, pld->CurrentZoneID, newX,
						newZ, speed, xlen, zlen, offset, expectedOffset);
			}
		}

		//Check our current position against any quest objective locations.
		//The movement counter will help us check every other step instead as a small optimization.
		if ((pld->PendingMovement & 1) && (pld->charPtr != NULL)) {
			int r = pld->charPtr->questJournal.CheckTravelLocations(
					creatureInstance->CreatureID, sim->Aux1, creatureInstance->CurrentX,
					creatureInstance->CurrentY, creatureInstance->CurrentZ,
					pld->CurrentZoneID);
			if (r > 0)
				sim->AttemptSend(sim->Aux1, r);
		}

		if (pld->PendingMovement >= 10) {
			pld->PendingMovement = 0;
		}

	}

	if (creatureInstance->actInst != NULL) {
		creatureInstance->actInst->PlayerMovement(creatureInstance);
	}

	//Check for zone boundaries, if a player is trying to go somewhere they should not be able to access.
	if (g_ZoneBarrierManager.CheckCollision(pld->CurrentZoneID,
			creatureInstance->CurrentX, creatureInstance->CurrentZ) == true)
		sim->AddMessage((long) creatureInstance, 0, BCM_UpdateFullPosition);

	int wpos = 0;

	//If GM invisible, send the update to ourself.  Otherwise broadcast it.
	if (sim->IsGMInvisible() == true) {
		wpos = PrepExt_GeneralMoveUpdate(sim->SendBuf, creatureInstance);
	} else {
		sim->AddMessage((long) creatureInstance, 0, BCM_UpdateVelocity);
		sim->AddMessage((long) creatureInstance, 0, BCM_UpdatePosInc);
	}

	pld->PendingMovement++;
	pld->MovementTime = g_ServerTime;

	sim->CheckSpawnTileUpdate(false);
	sim->CheckMapUpdate(false);

	return wpos;
}