コード例 #1
0
ファイル: main.cpp プロジェクト: Bong1236/europa
void render_ortho(SDL_Renderer* renderer)
{
	const int offset = input_offset;
	const float scale = input_scale;

	const int tileSizeX = 128;
	const int tileSizeY = 64;

	//draw draw space
	if (input_draw_space) {
		SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
		int w = worldMap.GetWidth()*tileSizeX*scale + (worldMap.GetWidth() - 1)*offset;
		int h = worldMap.GetHeight()*tileSizeY*scale + (worldMap.GetHeight() - 1)*offset;
		DRect rect(-camX, -camY, w, h);
		SDL_RenderFillRect(renderer, rect.get());
		SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
	}

	//draw map
	for (int y = 0; y < worldMap.GetHeight(); y++) {
		for (int x = 0; x < worldMap.GetWidth(); x++) {
			const int tileId = 0;
			SDL_Rect tileRect; //in tileset coords
			tileRect.x = tileId*tileSizeX;
			tileRect.y = tileId*tileSizeY;
			tileRect.w = tileSizeX;
			tileRect.h = tileSizeY;

			SDL_Rect rect; //in world coords
			rect.x = x*tileSizeX*scale + x*offset - camX;
			rect.y = y*tileSizeY*scale + y*offset - camY;
			rect.w = tileSizeX*scale;
			rect.h = tileSizeY*scale;

			SDL_RenderCopy(renderer, tileset, &tileRect, &rect);
		}
	}

	//draw debug rect
	if (input_show_debug_rect) {
		SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
		for (int y = 0; y < worldMap.GetHeight(); y++) {
			for (int x = 0; x < worldMap.GetWidth(); x++) {
				SDL_Rect rect; //in world coords
				rect.x = x*tileSizeX*scale + x*offset - camX;
				rect.y = y*tileSizeY*scale + y*offset - camY;
				rect.w = tileSizeX*scale;
				rect.h = tileSizeY*scale;

				SDL_RenderDrawRect(renderer, &rect);
			}
		}
		SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
	}
}
コード例 #2
0
void
RandomMovementGenerator<Creature>::Initialize(Creature &creature)
{
    float x,y,z,z2, wander_distance;
    creature.GetRespawnCoord(x, y, z);
    creature.GetRespawnDist(wander_distance);
    uint32 mapid=creature.GetMapId();

    Map* map = MapManager::Instance().GetMap(mapid, &creature);
    // Initialization is done in bulk. Don’t use vamps for that (4. parameter = false). It is too costly when entering a new map grid
    z2 = map->GetHeight(x,y,z, false);
    if( fabs( z2 - z ) < 5 )
        z = z2;

    i_nextMove = 1;
    i_waypoints[0][0] = x;
    i_waypoints[0][1] = y;
    i_waypoints[0][2] = z;

    bool is_water_ok = creature.isCanSwimOrFly();
    bool is_land_ok  = creature.isCanWalkOrFly();

    for(unsigned int idx=1; idx < MAX_RAND_WAYPOINTS+1; ++idx)
    {
        const float angle = 2*M_PI*rand_norm();
        const float range = wander_distance*rand_norm();

        i_waypoints[idx][0] = x+ range * cos(angle);
        i_waypoints[idx][1] = y+ range * sin(angle);

        // prevent invalid coordinates generation
        MaNGOS::NormalizeMapCoord(i_waypoints[idx][0]);
        MaNGOS::NormalizeMapCoord(i_waypoints[idx][1]);

        bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z);
        // if generated wrong path just ignore
        if( is_water && !is_water_ok || !is_water && !is_land_ok )
        {
            i_waypoints[idx][0] = i_waypoints[idx-1][0];
            i_waypoints[idx][1] = i_waypoints[idx-1][1];
            i_waypoints[idx][2] = i_waypoints[idx-1][2];
            continue;
        }

        // Initialization is done in bulk. Don’t use vamps for that (4. parameter = false). It is too costly when entering a new map grid
        z2 = map->GetHeight(i_waypoints[idx][0],i_waypoints[idx][1],z, false);
        if( fabs( z2 - z ) < 5 )
            z = z2;
        i_waypoints[idx][2] =  z;
    }
    i_nextMoveTime.Reset(urand(0, 10000-1));                // TODO: check the lower bound (it is probably too small)
    creature.StopMoving();
}
コード例 #3
0
void
RandomMovementGenerator::Initialize(Creature &creature)
{
    float x,y,z,z2, wander_distance;
    creature.GetRespawnCoord(x, y, z);
    creature.GetRespawnDist(wander_distance);
    uint32 mapid=creature.GetMapId();

    Map* map = MapManager::Instance().GetMap(mapid);
    z2 = map->GetHeight(x,y);
    if( abs( z2 - z ) < 5 )
        z = z2;

    i_nextMove = 1;
    i_waypoints[0][0] = x;
    i_waypoints[0][1] = y;
    i_waypoints[0][2] = z;

    bool is_water_ok = creature.isCanSwimOrFly();
    bool is_land_ok  = creature.isCanWalkOrFly();

    for(unsigned int idx=1; idx < MAX_RAND_WAYPOINTS+1; ++idx)
    {
        const float angle = (2*M_PI*rand())/RAND_MAX;
        const float range = (wander_distance*rand())/RAND_MAX;

        i_waypoints[idx][0] = x+ range * cos(angle);
        i_waypoints[idx][1] = y+ range * sin(angle);

        // prevent invalid coordinates generation
        MaNGOS::NormalizeMapCoord(i_waypoints[idx][0]);
        MaNGOS::NormalizeMapCoord(i_waypoints[idx][1]);

        bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1]);

        // if generated wrong path just ignore
        if( is_water && !is_water_ok || !is_water && !is_land_ok )
        {
            i_waypoints[idx][0] = i_waypoints[idx-1][0];
            i_waypoints[idx][1] = i_waypoints[idx-1][1];
            i_waypoints[idx][2] = i_waypoints[idx-1][2];
            continue;
        }

        z2 = map->GetHeight(i_waypoints[idx][0],i_waypoints[idx][1]);
        if( abs( z2 - z ) < 5 )
            z = z2;
        i_waypoints[idx][2] =  z;
    }
    i_nextMoveTime.Reset((rand() % 10000));
    creature.StopMoving();
}
コード例 #4
0
ファイル: main.cpp プロジェクト: Bong1236/europa
void mouseClick(MOUSE_EVENT event) {
	if (event == MOUSE_LEFT) {
		if (inEditorBar()) {
			std::cout << "editor!\n";
			int editorTileIndex = getTileEditor(mouse_x, mouse_y);
			
			if(editorTileIndex >= 0 && editorTileIndex < NB_TILES_EDITOR) {
				std::cout << "id= " << editorTileIndex << "\n";
				selectedTileEditor = editorTileIndex;
			}
		}
		else {
			//write tile to map
			int mapX; int mapY;
			getSelectedTileXY(mouse_x, mouse_y, mapX, mapY);

			if (mapX >= 0 && mapX < worldMap.GetWidth() && 
				mapY >= 0 && mapY < worldMap.GetHeight()) {
				int tileId = TILES_EDITOR[selectedTileEditor];
				Terrain& terrain = worldMap.Get(mapX, mapY);
				if (EDITOR_SELECTED_LAYER == 0) {
					terrain.terrainId = tileId;
				}
				else if (EDITOR_SELECTED_LAYER == 1) {
					terrain.objectId = tileId;
				}
				std::cout << "set tile " << tileId << " at " << mapX << "," << mapY << "\n";
			}
		}
	}
	else if (event == MOUSE_RIGHT) {
		//erase tile from map
		int mapX; int mapY;
		getSelectedTileXY(mouse_x, mouse_y, mapX, mapY);

		if (mapX >= 0 && mapX <= worldMap.GetWidth() &&
			mapY >= 0 && mapY < worldMap.GetHeight()) {
			int tileId = TILES_EDITOR[0];
			Terrain& terrain = worldMap.Get(mapX, mapY);
			if (EDITOR_SELECTED_LAYER == 0) {
				terrain.terrainId = -1;
			}
			else if (EDITOR_SELECTED_LAYER == 1) {
				terrain.objectId = -1;
			}
			std::cout << "set tile " << tileId << " at " << mapX << "," << mapY << "\n";
		}
	}
}
コード例 #5
0
void
ConfusedMovementGenerator::Initialize(Creature &creature)
{
    const float wander_distance=11;
    float x,y,z,z2;
    x = creature.GetPositionX();
    y = creature.GetPositionY();
    z = creature.GetPositionZ();
    uint32 mapid=creature.GetMapId();

    Map* map = MapManager::Instance().GetMap(mapid);
    z2 = map->GetHeight(x,y);
    if( abs( z2 - z ) < 5 )
        z = z2;

    i_nextMove = 1;

    bool is_water_ok = creature.isCanSwimOrFly();
    bool is_land_ok  = creature.isCanWalkOrFly();

    for(unsigned int idx=0; idx < MAX_CONF_WAYPOINTS+1; ++idx)
    {
        const float wanderX=((wander_distance*rand())/RAND_MAX)-wander_distance/2;
        const float wanderY=((wander_distance*rand())/RAND_MAX)-wander_distance/2;
            
        i_waypoints[idx][0] = x + wanderX;
        i_waypoints[idx][1] = y + wanderY;

        // prevent invalid coordinates generation
        MaNGOS::NormalizeMapCoord(i_waypoints[idx][0]);
        MaNGOS::NormalizeMapCoord(i_waypoints[idx][1]);

        bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1]);

        // if generated wrong path just ignore
        if( is_water && !is_water_ok || !is_water && !is_land_ok )
        {
            i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x;
            i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y;
        }

        z2 = map->GetHeight(i_waypoints[idx][0],i_waypoints[idx][1]);
        if( abs( z2 - z ) < 5 )
            z = z2;
        i_waypoints[idx][2] =  z;
    }
    creature.StopMoving();
}
コード例 #6
0
ファイル: main.cpp プロジェクト: Bong1236/europa
void reset_view()
{
	camX = -(tileSizeX / 2) * (worldMap.GetHeight() - 1);
	camY = 0;
	input_offset = 0;
	input_scale = 1;
}
コード例 #7
0
void RandomPlayerbotMgr::RandomTeleport(Player* bot, vector<WorldLocation> &locs)
{
    if (bot->IsBeingTeleported())
        return;

    if (locs.empty())
    {
        sLog->outMessage("playerbot", LOG_LEVEL_ERROR, "Cannot teleport bot %s - no locations available", bot->GetName().c_str());
        return;
    }

    for (int attemtps = 0; attemtps < 10; ++attemtps)
    {
        int index = urand(0, locs.size() - 1);
        WorldLocation loc = locs[index];
        float x = loc.m_positionX + urand(0, sPlayerbotAIConfig.grindDistance) - sPlayerbotAIConfig.grindDistance / 2;
        float y = loc.m_positionY + urand(0, sPlayerbotAIConfig.grindDistance) - sPlayerbotAIConfig.grindDistance / 2;
        float z = loc.m_positionZ;

        Map* map = sMapMgr->FindMap(loc.GetMapId(), 0);
        if (!map)
            continue;

        if (!map->IsOutdoors(x, y, z) ||
                map->IsInWater(x, y, z))
            continue;

        uint32 areaId = map->GetAreaId(x, y, z);
        if (!areaId)
            continue;

        AreaTableEntry const* area = sAreaStore.LookupEntry(areaId);
        if (!area)
            continue;

        float ground = map->GetHeight(x, y, z + 0.5f);
        if (ground <= INVALID_HEIGHT)
            continue;

        z = 0.05f + ground;
        sLog->outMessage("playerbot", LOG_LEVEL_INFO, "Random teleporting bot %s to %s %f,%f,%f", bot->GetName().c_str(), area->area_name[0], x, y, z);

        bot->GetMotionMaster()->Clear();
        bot->TeleportTo(loc.GetMapId(), x, y, z, 0);
        return;
    }

    sLog->outMessage("playerbot", LOG_LEVEL_ERROR, "Cannot teleport bot %s - no locations available", bot->GetName().c_str());
}
コード例 #8
0
/** layerToImage
  *
  * Converts a layer into an ImageMagick Image
  */
int HandlerUtils::LayerToImage(const Map& map, const Layer& layer, std::vector<Magick::Image>& tiles,
                               Magick::Image& image)
{
    for (unsigned int i = 0; i < map.GetHeight(); i++)
    {
        for (unsigned int j = 0; j < map.GetWidth(); j++)
        {
            int index = i * map.GetWidth() + j;
            int tile = layer[index];
            if (tile == -1)
                continue;
            image.composite(tiles[tile], j * map.GetTileWidth(), i * map.GetTileHeight(), Magick::AtopCompositeOp);
        }
    }

    return 0;
}
コード例 #9
0
/** layerToImage
  *
  * Converts a layer into an ImageMagick Image
  */
int HandlerUtils::LayerToImage(const Map& map, const Layer& layer, Magick::Image& image)
{
    std::vector<Magick::Image> tiles;

    if (HandlerUtils::GetTiles(map, tiles))
        return -1;

    Magick::Color color = Magick::ColorRGB(0, 0, 0);
    color.alpha(0);
    int width = map.GetWidth() * map.GetTileWidth();
    int height = map.GetHeight() * map.GetTileHeight();
    image.matte(true);
    image.resize(Magick::Geometry(width, height));
    image.backgroundColor(color);
    image.erase();

    return HandlerUtils::LayerToImage(map, layer, tiles, image);
}
コード例 #10
0
ファイル: main.cpp プロジェクト: nisan270390/BehaviorsProj
int main()
{
	// Read the configuration file
	ConfigManager::ReadParameters();

	// Read and inflate map
	const char* mapurl = ConfigManager::GetMapUrl().erase(ConfigManager::GetMapUrl().size() - 1).c_str();
	Map* currMap = LoadMap(mapurl);

	int robotSize = MAX(ConfigManager::GetRobotHeight(),ConfigManager::GetRobotWidth());
	double mapResulotion = ConfigManager::GetMapResolution();
	int InflateAddition = ceil((robotSize / 2) / mapResulotion);
	Map* inflateMap = currMap->Inflate(InflateAddition);

	Map* Maparticle = currMap->Inflate(5);

	// Calculate the ratio between the grid resolution and map resolution
	int res = ConfigManager::GetGridResolution() / ConfigManager::GetMapResolution();
	Grid* grid = new Grid(inflateMap->GetMatrix(),inflateMap->GetWidth(),inflateMap->GetHeight(), res);

	// A*
	PathPlanner* p = new PathPlanner();
	Point* start = ConfigManager::GetStartLocationMapResolution();
	Point* end = ConfigManager::GetGoalMapResolution();
	int startGridPointX,startGridPointY, endGridPointX, endGridPointY;
	startGridPointX = start->GetRow() / res;
	startGridPointY = start->GetCol() / res;
	endGridPointX = end->GetRow() / res;
	endGridPointY = end->GetCol() / res;

	std::string route = p->pathFind(startGridPointX ,startGridPointY,endGridPointX,endGridPointY,grid);


	// WayPoint calculation
	Point* startWithRes = new Point(start->GetRow() / 4, start->GetCol() / 4);
	vector<Point *> waypointsArr = WayPoints::CalculateByDirectionalPath(route, startWithRes);


	Robot robot("localhost",6665);
	PlnObstacleAvoid plnOA(&robot);
	Manager manager(&robot, &plnOA, waypointsArr, Maparticle);
	manager.run();
}
コード例 #11
0
/** MapToImage
  *
  * Converts a map into an ImageMagick Image
  */
int HandlerUtils::MapToImage(const Map& map, Magick::Image& image)
{
    std::vector<Magick::Image> tiles;

    if (HandlerUtils::GetTiles(map, tiles))
        return -1;

    Magick::Color color = Magick::ColorRGB(0, 0, 0);
    color.alpha(0);

    const Tileset& tileset = map.GetTileset();
    uint32_t tile_width, tile_height;
    tileset.GetTileDimensions(tile_width, tile_height);

    int width = map.GetWidth() * tile_width;
    int height = map.GetHeight() * tile_height;

    image.matte(true);
    image.resize(Magick::Geometry(width, height));
    image.backgroundColor(color);
    image.erase();

    try
    {
        for (const auto& layer : map.GetLayers())
        {
            if (HandlerUtils::LayerToImage(map, layer, tiles, image))
                return -1;
        }
    }
    catch (Magick::Exception& error_)
    {
        return -1;
    }

    return 0;
}
コード例 #12
0
ファイル: MovementHandler.cpp プロジェクト: Subv/diamondcore
void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
{
    uint32 opcode = recv_data.GetOpcode();
    DEBUG_LOG("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode);
    recv_data.hexlike();

    Unit *mover = _player->GetMover();
    Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL;

    // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
    if (plMover && plMover->IsBeingTeleported())
    {
        recv_data.rpos(recv_data.wpos());                   // prevent warnings spam
        return;
    }

    /* extract packet */
    ObjectGuid guid;
    MovementInfo movementInfo;

    recv_data >> guid.ReadAsPacked();
    recv_data >> movementInfo;
    /*----------------*/

    if (!Diamond::IsValidMapCoord(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o))
    {
        recv_data.rpos(recv_data.wpos());                   // prevent warnings spam
        return;
    }

    /* handle special cases */
    if (movementInfo.HasMovementFlag(MOVEFLAG_ONTRANSPORT))
    {
        // transports size limited
        // (also received at zeppelin/lift leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
        if ( movementInfo.GetTransportPos()->x > 50 || movementInfo.GetTransportPos()->y > 50 || movementInfo.GetTransportPos()->z > 100 )
        {
            recv_data.rpos(recv_data.wpos());                   // prevent warnings spam
            return;
        }

        if ( !Diamond::IsValidMapCoord(movementInfo.GetPos()->x + movementInfo.GetTransportPos()->x, movementInfo.GetPos()->y + movementInfo.GetTransportPos()->y,
            movementInfo.GetPos()->z + movementInfo.GetTransportPos()->z, movementInfo.GetPos()->o + movementInfo.GetTransportPos()->o) )
        {
            recv_data.rpos(recv_data.wpos());                   // prevent warnings spam
            return;
        }

        // if we boarded a transport, add us to it
        if (plMover && !plMover->m_transport)
        {
            float trans_rad = movementInfo.GetTransportPos()->x*movementInfo.GetTransportPos()->x + movementInfo.GetTransportPos()->y*movementInfo.GetTransportPos()->y + movementInfo.GetTransportPos()->z*movementInfo.GetTransportPos()->z;
            if (trans_rad > 3600.0f) // transport radius = 60 yards //cheater with on_transport_flag
            {
                 return;
            }
            // elevators also cause the client to send MOVEFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list
            for (MapManager::TransportSet::const_iterator iter = sMapMgr.m_Transports.begin(); iter != sMapMgr.m_Transports.end(); ++iter)
            {
                if ((*iter)->GetObjectGuid() == movementInfo.GetTransportGuid())
                {
                    plMover->m_transport = (*iter);
                    (*iter)->AddPassenger(plMover);

                    if (plMover->GetVehicleKit())
                        plMover->GetVehicleKit()->RemoveAllPassengers();

                    break;
                }
            }
        }
    }
    else if (plMover && plMover->m_transport)               // if we were on a transport, leave
    {
        plMover->m_transport->RemovePassenger(plMover);
        plMover->m_transport = NULL;
        movementInfo.ClearTransportData();
    }

    // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
    if (opcode == MSG_MOVE_FALL_LAND && plMover && !plMover->IsTaxiFlying())
        plMover->HandleFall(movementInfo);

    if (plMover && (movementInfo.HasMovementFlag(MOVEFLAG_SWIMMING) != plMover->IsInWater()))
    {
        // now client not include swimming flag in case jumping under water
        plMover->SetInWater( !plMover->IsInWater() || plMover->GetBaseMap()->IsUnderWater(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z) );
        if (plMover->GetBaseMap()->IsUnderWater(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z-7.0f))
        {
            plMover->m_anti_BeginFallZ=INVALID_HEIGHT;
        }
    }

    // ---- anti-cheat features -->>>
    uint32 Anti_TeleTimeDiff=plMover ? time(NULL) - plMover->Anti__GetLastTeleTime() : time(NULL);
    static const uint32 Anti_TeleTimeIgnoreDiff=sWorld.GetMvAnticheatIgnoreAfterTeleport();
    if (plMover && (plMover->m_transport == 0) && sWorld.GetMvAnticheatEnable() &&
        GetPlayer()->GetSession()->GetSecurity() <= sWorld.GetMvAnticheatGmLevel() &&
        GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()!=FLIGHT_MOTION_TYPE &&
        Anti_TeleTimeDiff>Anti_TeleTimeIgnoreDiff)
    {
        const uint32 CurTime=getMSTime();
        if (getMSTimeDiff(GetPlayer()->m_anti_lastalarmtime,CurTime) > sWorld.GetMvAnticheatAlarmPeriod())
        {
            GetPlayer()->m_anti_alarmcount = 0;
        }
        /* I really don't care about movement-type yet (todo)
        UnitMoveType move_type;

        if (movementInfo.flags & MOVEMENTFLAG_FLYING) move_type = MOVE_FLY;
        else if (movementInfo.flags & MOVEMENTFLAG_SWIMMING) move_type = MOVE_SWIM;
        else if (movementInfo.flags & MOVEMENTFLAG_WALK_MODE) move_type = MOVE_WALK;
        else move_type = MOVE_RUN;*/

        float delta_x = GetPlayer()->GetPositionX() - movementInfo.GetPos()->x;
        float delta_y = GetPlayer()->GetPositionY() - movementInfo.GetPos()->y;
        float delta_z = GetPlayer()->GetPositionZ() - movementInfo.GetPos()->z;
        float delta = sqrt(delta_x * delta_x + delta_y * delta_y); // Len of movement-vector via Pythagoras (a^2+b^2=Len^2)
        float tg_z = 0.0f; //tangens
        float delta_t = getMSTimeDiff(GetPlayer()->m_anti_lastmovetime,CurTime);

        GetPlayer()->m_anti_lastmovetime = CurTime;
        GetPlayer()->m_anti_MovedLen += delta;

        if (delta_t > 15000.0f)
        {   delta_t = 15000.0f;   }

        // Tangens of walking angel
        if (!(movementInfo.GetMovementFlags() & (MOVEFLAG_FLYING | MOVEFLAG_SWIMMING)))
        {
            tg_z = ((delta !=0.0f) && (delta_z > 0.0f)) ? (atan((delta_z*delta_z) / delta) * 180.0f / M_PI) : 0.0f;
        }

        //antiOFF fall-damage, MOVEMENTFLAG_UNK4 seted by client if player try movement when falling and unset in this case the MOVEMENTFLAG_FALLING flag. 
        if ((!GetPlayer()->CanFly() && GetPlayer()->m_anti_BeginFallZ == INVALID_HEIGHT) &&
            (movementInfo.GetMovementFlags() & (MOVEFLAG_FALLING | MOVEFLAG_FALLINGFAR)) != 0)
        {
            GetPlayer()->m_anti_BeginFallZ=(float)(movementInfo.GetPos()->z);
        }

        if (GetPlayer()->m_anti_NextLenCheck <= CurTime)
        {
            // Check every 500ms is a lot more advisable then 1000ms, because normal movment packet arrives every 500ms
            uint32 OldNextLenCheck=GetPlayer()->m_anti_NextLenCheck;
            float delta_xyt=GetPlayer()->m_anti_MovedLen/(float)(getMSTimeDiff(OldNextLenCheck-500,CurTime));
            GetPlayer()->m_anti_NextLenCheck = CurTime+500;
            GetPlayer()->m_anti_MovedLen = 0.0f;
            static const float MaxDeltaXYT = sWorld.GetMvAnticheatMaxXYT();

            if (delta_xyt > MaxDeltaXYT && delta<=100.0f && GetPlayer()->GetZoneId() != 2257)
            {
                if (sWorld.GetMvAnticheatSpeedCheck())
                    Anti__CheatOccurred(CurTime,"Speed hack",delta_xyt,LookupOpcodeName(opcode),
                    (float)(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()),
                    (float)(getMSTimeDiff(OldNextLenCheck-500,CurTime)));
            }
        }

        if (delta > 100.0f && GetPlayer()->GetZoneId() != 2257)
        {
            if (sWorld.GetMvAnticheatTeleportCheck())
                Anti__ReportCheat("Tele hack",delta,LookupOpcodeName(opcode));
        }

        // Check for waterwalking . Fix new way of checking for waterwalking by Darky88
        if (movementInfo.HasMovementFlag(MOVEFLAG_WATERWALKING) &&
            !(GetPlayer()->HasAuraType(SPELL_AURA_WATER_WALK) || GetPlayer()->HasAuraType(SPELL_AURA_GHOST)))
        {
            if (sWorld.GetMvAnticheatWaterCheck())
                Anti__CheatOccurred(CurTime,"Water walking",0.0f,NULL,0.0f,(uint32)(movementInfo.GetMovementFlags()));
        }

        // Check for walking upwards a mountain while not beeing able to do that, New check by Darky88 
        if ((delta_z < -2.3f) && (tg_z > 2.37f))
        {
            if (sWorld.GetMvAnticheatMountainCheck())
                Anti__CheatOccurred(CurTime,"Mountain hack",tg_z,NULL,delta,delta_z);
        }

        static const float DIFF_OVERGROUND = 10.0f;
        float Anti__GroundZ = GetPlayer()->GetMap()->GetHeight(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),MAX_HEIGHT);
        float Anti__FloorZ  = GetPlayer()->GetMap()->GetHeight(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ());
        float Anti__MapZ = ((Anti__FloorZ <= (INVALID_HEIGHT+5.0f)) ? Anti__GroundZ : Anti__FloorZ) + DIFF_OVERGROUND;
         
        if (!GetPlayer()->CanFly() &&
            !GetPlayer()->GetBaseMap()->IsUnderWater(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z-7.0f) &&
            Anti__MapZ < GetPlayer()->GetPositionZ() && Anti__MapZ > (INVALID_HEIGHT+DIFF_OVERGROUND + 5.0f))
        {
            static const float DIFF_AIRJUMP=25.0f; // 25 is realy high, but to many false positives...

            // Air-Jump-Detection definitively needs a better way to be detected...
            if ((movementInfo.GetMovementFlags() & (MOVEFLAG_CAN_FLY | MOVEFLAG_FLYING | MOVEFLAG_ROOT)) != 0) // Fly Hack
            {
                // Fix Aura 55164
                if (!GetPlayer()->HasAura(55164) || !GetPlayer()->HasAuraType(SPELL_AURA_FEATHER_FALL))
                    if (sWorld.GetMvAnticheatFlyCheck())
                        Anti__CheatOccurred(CurTime,"Fly hack",
                            ((uint8)(GetPlayer()->HasAuraType(SPELL_AURA_FLY))) +
                            ((uint8)(GetPlayer()->HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED))*2),
                            NULL,GetPlayer()->GetPositionZ()-Anti__MapZ);
            }

            // Need a better way to do that - currently a lot of fake alarms
            else if ((Anti__MapZ+DIFF_AIRJUMP < GetPlayer()->GetPositionZ() &&
                    (movementInfo.GetMovementFlags() & (MOVEFLAG_FALLINGFAR | MOVEFLAG_PENDINGSTOP))==0) ||
                    (Anti__MapZ < GetPlayer()->GetPositionZ() && opcode==MSG_MOVE_JUMP) &&
                    !GetPlayer()->HasAuraType(SPELL_AURA_FEATHER_FALL))
            {
                if (sWorld.GetMvAnticheatJumpCheck())
                    Anti__CheatOccurred(CurTime,"Possible Air Jump Hack",0.0f,LookupOpcodeName(opcode),0.0f,movementInfo.GetMovementFlags());
            }
        }

        /*if (Anti__FloorZ < -199900.0f && Anti__GroundZ >= -199900.0f &&
           GetPlayer()->GetPositionZ()+5.0f < Anti__GroundZ)
        {
            Anti__CheatOccurred(CurTime,"Teleport2Plane hack",
                                GetPlayer()->GetPositionZ(),NULL,Anti__GroundZ);
        }*/

        //Teleport To Plane checks
        if (movementInfo.GetPos()->z < 0.0001f && movementInfo.GetPos()->z > -0.0001f && (!movementInfo.HasMovementFlag(MovementFlags(MOVEFLAG_SWIMMING | MOVEFLAG_CAN_FLY | MOVEFLAG_FLYING))))
        {
            if (sWorld.GetMvAnticheatTeleport2PlaneCheck())
            {
                // Prevent using TeleportToPlan.
                Map *map = GetPlayer()->GetMap();
                if (map)
                {
                    float plane_z = map->GetHeight(movementInfo.GetPos()->x, movementInfo.GetPos()->y, MAX_HEIGHT) - movementInfo.GetPos()->z;
                    plane_z = (plane_z < -500.0f) ? 0 : plane_z; //check holes in heigth map
                    if (plane_z > 0.1f || plane_z < -0.1f)
                    {
                        if (sWorld.GetMvAnticheatTeleport2PlaneCheck())
                            Anti__CheatOccurred(CurTime,"Teleport2Plane hack",GetPlayer()->GetPositionZ(),NULL,plane_z);
                    }
                }
            }
        }
    }
    // <<---- anti-cheat features

    /* process position-change */
    movementInfo.UpdateTime(getMSTime());

    WorldPacket data(opcode, recv_data.size());
    data.appendPackGUID(mover->GetGUID());                  // write guid
    movementInfo.Write(data);                               // write data
    mover->SendMessageToSetExcept(&data, _player);

    mover->m_movementInfo = movementInfo;
    mover->SetPosition(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o);

    if (plMover)                                             // nothing is charmed, or player charmed
    {
        plMover->UpdateFallInformationIfNeed(movementInfo, opcode);

        // after move info set
        if ((opcode == MSG_MOVE_SET_WALK_MODE || opcode == MSG_MOVE_SET_RUN_MODE))
            plMover->UpdateWalkMode(plMover, false);

        if (plMover->isMovingOrTurning())
            plMover->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);

        if (movementInfo.GetPos()->z < -500.0f)
        {
            if (plMover->InBattleGround()
                && plMover->GetBattleGround()
                && plMover->GetBattleGround()->HandlePlayerUnderMap(_player))
            {
                // do nothing, the handle already did if returned true
            }
            else
            {
                // NOTE: this is actually called many times while falling
                // even after the player has been teleported away
                // TODO: discard movement packets after the player is rooted
                if (plMover->isAlive())
                {
                    plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, plMover->GetMaxHealth());
                    // pl can be alive if GM/etc
                    if (!plMover->isAlive())
                    {
                        // change the death state to CORPSE to prevent the death timer from
                        // starting in the next player update
                        plMover->KillPlayer();
                        plMover->BuildPlayerRepop();
                    }
                }

                // cancel the death timer here if started
                plMover->RepopAtGraveyard();
            }
        }
    }
}
コード例 #13
0
void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
{
    uint32 opcode = recv_data.GetOpcode();
    sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode);

    Unit *mover = _player->m_mover;
    Player *plMover = mover->GetTypeId()==TYPEID_PLAYER ? (Player*)mover : NULL;

    // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
    if(plMover && plMover->IsBeingTeleported()){
        // movement anticheat
        plMover->m_anti_JustTeleported = 1;
        // end movement anticheat
        return;
    }

    /* extract packet */
    MovementInfo movementInfo;
    ReadMovementInfo(recv_data, &movementInfo);
    /*----------------*/

    if(recv_data.size() != recv_data.rpos())
    {
        sLog.outError("MovementHandler: player %s (guid %d, account %u) sent a packet (opcode %u) that is " SIZEFMTD " bytes larger than it should be. Kicked as cheater.", _player->GetName(), _player->GetGUIDLow(), _player->GetSession()->GetAccountId(), recv_data.GetOpcode(), recv_data.size() - recv_data.rpos());
        KickPlayer();
        return;
    }

    if (!MaNGOS::IsValidMapCoord(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o))
        return;

    /* handle special cases */
    if (movementInfo.HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
    {
        // transports size limited
        // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
        if( movementInfo.t_x > 60 || movementInfo.t_y > 60 || movementInfo.t_x < -60 ||  movementInfo.t_y < -60 )
            return;

        if( !MaNGOS::IsValidMapCoord(movementInfo.x+movementInfo.t_x, movementInfo.y + movementInfo.t_y,
            movementInfo.z + movementInfo.t_z, movementInfo.o + movementInfo.t_o) )
            return;

        if (plMover && plMover->m_anti_TransportGUID == 0 && (movementInfo.t_guid !=0))
        {
            // if we boarded a transport, add us to it
            if (plMover && !plMover->m_transport)
            {
                // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list
                for (MapManager::TransportSet::const_iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter)
                {
                    if ((*iter)->GetGUID() == movementInfo.t_guid)
                    {
                        plMover->m_transport = (*iter);
                        (*iter)->AddPassenger(plMover);
                        break;
                    }
                }
            }
            //movement anticheat;
            //Correct finding GO guid in DB (thanks to GriffonHeart)
            GameObject *obj = HashMapHolder<GameObject>::Find(movementInfo.t_guid);
            if(obj)
                plMover->m_anti_TransportGUID = obj->GetDBTableGUIDLow();
            else
                plMover->m_anti_TransportGUID = GUID_LOPART(movementInfo.t_guid);
            // end movement anticheat
        }
    } else if (plMover && plMover->m_anti_TransportGUID != 0){
        if (plMover && plMover->m_transport)               // if we were on a transport, leave
        {
            plMover->m_transport->RemovePassenger(plMover);
            plMover->m_transport = NULL;
        }
        movementInfo.t_x = 0.0f;
        movementInfo.t_y = 0.0f;
        movementInfo.t_z = 0.0f;
        movementInfo.t_o = 0.0f;
        movementInfo.t_time = 0;
        movementInfo.t_seat = -1;
        plMover->m_anti_TransportGUID = 0;
    }

    // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
    if (opcode == MSG_MOVE_FALL_LAND && plMover && !plMover->isInFlight())
    {
        //movement anticheat
        plMover->m_anti_JustJumped = 0;
        plMover->m_anti_JumpBaseZ = 0;
        //end movement anticheat
        plMover->HandleFall(movementInfo);
    }


    if (plMover && (movementInfo.HasMovementFlag(MOVEMENTFLAG_SWIMMING) != plMover->IsInWater()))
    {
        // now client not include swimming flag in case jumping under water
        plMover->SetInWater( !plMover->IsInWater() || plMover->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) );
    }

    /*----------------------*/
    //---- anti-cheat features -->>>
    bool check_passed = true;
    #ifdef MOVEMENT_ANTICHEAT_DEBUG
    if (plMover){
        sLog.outBasic("MA-%s > client-time:%d fall-time:%d | xyzo: %f,%f,%fo(%f) flags[%X] opcode[%s]| transport (xyzo): %f,%f,%fo(%f)",
                    plMover->GetName(),movementInfo.time,movementInfo.fallTime,movementInfo.x,movementInfo.y,movementInfo.z,movementInfo.o,
                    movementInfo.flags, LookupOpcodeName(opcode),movementInfo.t_x,movementInfo.t_y,movementInfo.t_z,movementInfo.t_o);
        sLog.outBasic("MA-%s Transport > server GUID: %d |  client GUID: (lo)%d - (hi)%d",
                    plMover->GetName(),plMover->m_anti_TransportGUID, GUID_LOPART(movementInfo.t_guid), GUID_HIPART(movementInfo.t_guid));
    } else {
        sLog.outBasic("MA > client-time:%d fall-time:%d | xyzo: %f,%f,%fo(%f) flags[%X] opcode[%s]| transport (xyzo): %f,%f,%fo(%f)",
                    movementInfo.time,movementInfo.fallTime,movementInfo.x,movementInfo.y,movementInfo.z,movementInfo.o,
                    movementInfo.flags, LookupOpcodeName(opcode),movementInfo.t_x,movementInfo.t_y,movementInfo.t_z,movementInfo.t_o);
        sLog.outBasic("MA Transport > server GUID:  |  client GUID: (lo)%d - (hi)%d",
                    GUID_LOPART(movementInfo.t_guid), GUID_HIPART(movementInfo.t_guid));
    }
    #endif

    if (plMover && World::GetEnableMvAnticheat())
    {
        //calc time deltas
        int32 cClientTimeDelta = 1500;
        if (plMover->m_anti_LastClientTime !=0){
            cClientTimeDelta = movementInfo.time - plMover->m_anti_LastClientTime;
            plMover->m_anti_DeltaClientTime += cClientTimeDelta;
            plMover->m_anti_LastClientTime = movementInfo.time;
        } else {
            plMover->m_anti_LastClientTime = movementInfo.time;
        }

        uint32 cServerTime=getMSTime();
        uint32 cServerTimeDelta = 1500;
        if (plMover->m_anti_LastServerTime != 0){
            cServerTimeDelta = cServerTime - plMover->m_anti_LastServerTime;
            plMover->m_anti_DeltaServerTime += cServerTimeDelta;
            plMover->m_anti_LastServerTime = cServerTime;
        } else {
            plMover->m_anti_LastServerTime = cServerTime;
        }

        //resync times on client login (first 15 sec for heavy areas)
        if (plMover->m_anti_DeltaServerTime < 15000 && plMover->m_anti_DeltaClientTime < 15000)
            plMover->m_anti_DeltaClientTime = plMover->m_anti_DeltaServerTime;

        int32 sync_time = plMover->m_anti_DeltaClientTime - plMover->m_anti_DeltaServerTime;

        #ifdef MOVEMENT_ANTICHEAT_DEBUG
        sLog.outBasic("MA-%s Time > cClientTimeDelta: %d, cServerTime: %d || deltaC: %d - deltaS: %d || SyncTime: %d",
                        plMover->GetName(),cClientTimeDelta, cServerTime,
                        plMover->m_anti_DeltaClientTime, plMover->m_anti_DeltaServerTime, sync_time);
        #endif

        //mistiming checks
        int32 gmd = World::GetMistimingDelta();
        if (sync_time > gmd || sync_time < -gmd){
            cClientTimeDelta = cServerTimeDelta;
            plMover->m_anti_MistimingCount++;

            sLog.outError("MA-%s, mistiming exception. #:%d, mistiming: %dms ",
                            plMover->GetName(), plMover->m_anti_MistimingCount, sync_time);

            if (plMover->m_anti_MistimingCount > World::GetMistimingAlarms())
            {
                plMover->GetSession()->KickPlayer();
                return;
            }
            check_passed = false;
        }
        // end mistiming checks


        uint32 curDest = plMover->m_taxi.GetTaxiDestination(); //check taxi flight
        if ((plMover->m_anti_TransportGUID == 0) && !curDest)
        {
            UnitMoveType move_type;

            // calculating section ---------------------
            //current speed
            if (movementInfo.flags & MOVEMENTFLAG_FLYING) move_type = movementInfo.flags & MOVEMENTFLAG_BACKWARD ? MOVE_FLIGHT_BACK : MOVE_FLIGHT;
            else if (movementInfo.flags & MOVEMENTFLAG_SWIMMING) move_type = movementInfo.flags & MOVEMENTFLAG_BACKWARD ? MOVE_SWIM_BACK : MOVE_SWIM;
            else if (movementInfo.flags & MOVEMENTFLAG_WALK_MODE) move_type = MOVE_WALK;
            //hmm... in first time after login player has MOVE_SWIMBACK instead MOVE_WALKBACK
            else move_type = movementInfo.flags & MOVEMENTFLAG_BACKWARD ? MOVE_SWIM_BACK : MOVE_RUN;

            float current_speed = plMover->GetSpeed(move_type);
            // end current speed

            // movement distance
            float allowed_delta= 0;

            float delta_x = plMover->GetPositionX() - movementInfo.x;
            float delta_y = plMover->GetPositionY() - movementInfo.y;
            float delta_z = plMover->GetPositionZ() - movementInfo.z;
            float real_delta = delta_x * delta_x + delta_y * delta_y;
            float tg_z = -99999; //tangens
            // end movement distance

            if (cClientTimeDelta < 0) {cClientTimeDelta = 0;}
            float time_delta = (cClientTimeDelta < 1500) ? (float)cClientTimeDelta/1000 : 1.5f; //normalize time - 1.5 second allowed for heavy loaded server

            if (!(movementInfo.flags & (MOVEMENTFLAG_FLYING | MOVEMENTFLAG_SWIMMING)))
              tg_z = (real_delta !=0) ? (delta_z*delta_z / real_delta) : -99999;

            if (current_speed < plMover->m_anti_Last_HSpeed)
            {
                allowed_delta = plMover->m_anti_Last_HSpeed;
                if (plMover->m_anti_LastSpeedChangeTime == 0 )
                    plMover->m_anti_LastSpeedChangeTime = movementInfo.time + (uint32)floor(((plMover->m_anti_Last_HSpeed / current_speed) * 1500)) + 100; //100ms above for random fluctuating =)))
            } else {
                allowed_delta = current_speed;
            }
            allowed_delta = allowed_delta * time_delta;
            allowed_delta = allowed_delta * allowed_delta + 2;
            if (tg_z > 2.2)
                allowed_delta = allowed_delta + (delta_z*delta_z)/2.37; // mountain fall allowed speed

            if (movementInfo.time>plMover->m_anti_LastSpeedChangeTime)
            {
                plMover->m_anti_Last_HSpeed = current_speed; // store current speed
                plMover->m_anti_Last_VSpeed = -2.3f;
                if (plMover->m_anti_LastSpeedChangeTime != 0) plMover->m_anti_LastSpeedChangeTime = 0;
            }
            // end calculating section ---------------------

            //AntiGravitation (thanks to Meekro)
            float JumpHeight = plMover->m_anti_JumpBaseZ - movementInfo.z;
            if ((plMover->m_anti_JumpBaseZ != 0)
                    && !(movementInfo.flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING | MOVEMENTFLAG_FLYING2))
                    && (JumpHeight < plMover->m_anti_Last_VSpeed))
            {
                #ifdef MOVEMENT_ANTICHEAT_DEBUG
                sLog.outError("MA-%s, GraviJump exception. JumpHeight = %f, Allowed Veritcal Speed = %f",
                                plMover->GetName(), JumpHeight, plMover->m_anti_Last_VSpeed);
                #endif
                check_passed = false;
            }

            //multi jump checks
            if (opcode == MSG_MOVE_JUMP && !plMover->IsInWater())
            {
                if (plMover->m_anti_JustJumped >= 1){
                    check_passed = false; //don't process new jump packet
                } else {
                    plMover->m_anti_JustJumped += 1;
                    plMover->m_anti_JumpBaseZ = movementInfo.z;
                }
            } else if (plMover->IsInWater()) {
                 plMover->m_anti_JustJumped = 0;
            }

            //speed hack checks
            if ((real_delta > allowed_delta)) // && (delta_z < 0))
            {
                #ifdef MOVEMENT_ANTICHEAT_DEBUG
                sLog.outError("MA-%s, speed exception | cDelta=%f aDelta=%f | cSpeed=%f lSpeed=%f deltaTime=%f",
                                plMover->GetName(), real_delta, allowed_delta, current_speed, plMover->m_anti_Last_HSpeed,time_delta);
                #endif
                check_passed = false;
            }
            //teleport hack checks
            if ((real_delta>4900.0f) && !(real_delta < allowed_delta))
            {
                #ifdef MOVEMENT_ANTICHEAT_DEBUG
                sLog.outError("MA-%s, is teleport exception | cDelta=%f aDelta=%f | cSpeed=%f lSpeed=%f deltaToime=%f",
                                plMover->GetName(),real_delta, allowed_delta, current_speed, plMover->m_anti_Last_HSpeed,time_delta);
                #endif
                check_passed = false;
            }

            //mountian hack checks // 1.56f (delta_z < GetPlayer()->m_anti_Last_VSpeed))
            if ((delta_z < plMover->m_anti_Last_VSpeed) && (plMover->m_anti_JustJumped == 0) && (tg_z > 2.37f))
            {
                #ifdef MOVEMENT_ANTICHEAT_DEBUG
                sLog.outError("MA-%s, mountain exception | tg_z=%f", plMover->GetName(),tg_z);
                #endif
                check_passed = false;
            }
            //Fly hack checks
            if (((movementInfo.flags & (MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_FLYING | MOVEMENTFLAG_FLYING2)) != 0)
                  && !plMover->isGameMaster()
                  && !(plMover->HasAuraType(SPELL_AURA_FLY) || plMover->HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED)))
            {
                #ifdef MOVEMENT_ANTICHEAT_DEBUG
                sLog.outError("MA-%s, flight exception. {SPELL_AURA_FLY=[%X]} {SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED=[%X]} {SPELL_AURA_MOD_SPEED_FLIGHT=[%X]} {SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS=[%X]} {SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK=[%X]}",
                   plMover->GetName(),
                   plMover->HasAuraType(SPELL_AURA_FLY), plMover->HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED),
                   plMover->HasAuraType(SPELL_AURA_MOD_SPEED_FLIGHT), plMover->HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS),
                   plMover->HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK));
                #endif
                check_passed = false;
            }
            //Water-Walk checks
            if (((movementInfo.flags & MOVEMENTFLAG_WATERWALKING) != 0)
                  && !plMover->isGameMaster()
                  && !(plMover->HasAuraType(SPELL_AURA_WATER_WALK) | plMover->HasAuraType(SPELL_AURA_GHOST)))
            {
                #ifdef MOVEMENT_ANTICHEAT_DEBUG
                sLog.outError("MA-%s, water-walk exception. [%X]{SPELL_AURA_WATER_WALK=[%X]}",
                                plMover->GetName(), movementInfo.flags, plMover->HasAuraType(SPELL_AURA_WATER_WALK));
                #endif
                check_passed = false;
            }
            //Teleport To Plane checks
            if (movementInfo.z < 0.0001f && movementInfo.z > -0.0001f
                && ((movementInfo.flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_FLYING | MOVEMENTFLAG_FLYING2)) == 0)
                && !plMover->isGameMaster())
            {
                // Prevent using TeleportToPlan.
                Map *map = plMover->GetMap();
                if (map){
                    float plane_z = map->GetHeight(movementInfo.x, movementInfo.y, MAX_HEIGHT) - movementInfo.z;
                    plane_z = (plane_z < -500.0f) ? 0 : plane_z; //check holes in heigth map
                    if(plane_z > 0.1f || plane_z < -0.1f)
                    {
                        plMover->m_anti_TeleToPlane_Count++;
                        check_passed = false;
                        #ifdef MOVEMENT_ANTICHEAT_DEBUG
                        sLog.outDebug("MA-%s, teleport to plan exception. plane_z: %f ",
                                        plMover->GetName(), plane_z);
                        #endif
                        if (plMover->m_anti_TeleToPlane_Count > World::GetTeleportToPlaneAlarms())
                        {
                            sLog.outError("MA-%s, teleport to plan exception. Exception count: %d ",
                                            plMover->GetName(), plMover->m_anti_TeleToPlane_Count);
                            plMover->GetSession()->KickPlayer();
                            return;
                        }
                    }
                }
            } else {
                if (plMover->m_anti_TeleToPlane_Count != 0)
                    plMover->m_anti_TeleToPlane_Count = 0;
            }
        } else if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT) {
            //antiwrap checks
            if (plMover->m_transport)
            {
                float trans_rad = movementInfo.t_x*movementInfo.t_x + movementInfo.t_y*movementInfo.t_y + movementInfo.t_z*movementInfo.t_z;
                if (trans_rad > 3600.0f){
                    check_passed = false;
                    #ifdef MOVEMENT_ANTICHEAT_DEBUG
                    sLog.outError("MA-%s, leave transport.", plMover->GetName());
                    #endif
                }
            } else {
                if (GameObjectData const* go_data = objmgr.GetGOData(plMover->m_anti_TransportGUID))
                {
                    float delta_gox = go_data->posX - movementInfo.x;
                    float delta_goy = go_data->posY - movementInfo.y;
                    float delta_goz = go_data->posZ - movementInfo.z;
                    int mapid = go_data->mapid;
                    #ifdef MOVEMENT_ANTICHEAT_DEBUG
                    sLog.outDebug("MA-%s, transport movement. GO xyzo: %f,%f,%f",
                                    plMover->GetName(), go_data->posX,go_data->posY,go_data->posZ);
                    #endif
                    if (plMover->GetMapId() != mapid){
                        check_passed = false;
                    } else if (mapid !=369) {
                        float delta_go = delta_gox*delta_gox + delta_goy*delta_goy;
                        if (delta_go > 3600.0f) {
                            check_passed = false;
                            #ifdef MOVEMENT_ANTICHEAT_DEBUG
                            sLog.outError("MA-%s, leave transport. GO xyzo: %f,%f,%f",
                                            plMover->GetName(), go_data->posX,go_data->posY,go_data->posZ);
                            #endif
                        }
                    }

                } else {
                    #ifdef MOVEMENT_ANTICHEAT_DEBUG
                    sLog.outDebug("MA-%s, undefined transport.", plMover->GetName());
                    #endif
                    check_passed = false;
                }
            }
            if (!check_passed){
                if (plMover->m_transport)
                    {
                        plMover->m_transport->RemovePassenger(plMover);
                        plMover->m_transport = NULL;
                    }
                    movementInfo.t_x = 0.0f;
                    movementInfo.t_y = 0.0f;
                    movementInfo.t_z = 0.0f;
                    movementInfo.t_o = 0.0f;
                    movementInfo.t_time = 0;
                    plMover->m_anti_TransportGUID = 0;
            }
        }
    }
    /* process position-change */
    if (check_passed)
    {
    recv_data.put<uint32>(6, getMSTime());                  // fix time, offset flags(4) + unk(2)
    WorldPacket data(recv_data.GetOpcode(), (mover->GetPackGUID().size()+recv_data.size()));
    data.append(mover->GetPackGUID());                      // use mover guid
    data.append(recv_data.contents(), recv_data.size());
    GetPlayer()->SendMessageToSet(&data, false);

    if(plMover)                                             // nothing is charmed, or player charmed
    {
        plMover->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
        plMover->m_movementInfo = movementInfo;
        plMover->UpdateFallInformationIfNeed(movementInfo, recv_data.GetOpcode());

        if(plMover->isMovingOrTurning())
            plMover->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);

        if(movementInfo.z < -500.0f)
        {
            if(plMover->InBattleGround()
                && plMover->GetBattleGround()
                && plMover->GetBattleGround()->HandlePlayerUnderMap(_player))
            {
                // do nothing, the handle already did if returned true
            }
            else
            {
                // NOTE: this is actually called many times while falling
                // even after the player has been teleported away
                // TODO: discard movement packets after the player is rooted
                if(plMover->isAlive())
                {
                    plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
                    // pl can be alive if GM/etc
                    if(!plMover->isAlive())
                    {
                        // change the death state to CORPSE to prevent the death timer from
                        // starting in the next player update
                        plMover->KillPlayer();
                        plMover->BuildPlayerRepop();
                    }
                }

                // cancel the death timer here if started
                plMover->RepopAtGraveyard();
            }
        }
        //movement anticheat >>>
        if (plMover->m_anti_AlarmCount > 0){
            sLog.outError("MA-%s produce %d anticheat alarms",plMover->GetName(),plMover->m_anti_AlarmCount);
            plMover->m_anti_AlarmCount = 0;
        }
    // end movement anticheat
    }
    else                                                    // creature charmed
    {
        if(mover->IsInWorld())
            mover->GetMap()->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
    }
    
    } else if (plMover) {
        plMover->m_anti_AlarmCount++;
        WorldPacket data;
        plMover->m_movementInfo.SetMovementFlags(MovementFlags(MOVEMENTFLAG_NONE));
        plMover->BuildTeleportAckMsg(&data, plMover->GetPositionX(), plMover->GetPositionY(), plMover->GetPositionZ(), plMover->GetOrientation());
        plMover->GetSession()->SendPacket(&data);
        plMover->BuildHeartBeatMsg(&data);
        plMover->SendMessageToSet(&data, true);
    }
}
コード例 #14
0
ファイル: main.cpp プロジェクト: Bong1236/europa
void render(SDL_Renderer* renderer)
{
	//draw draw space
// 	if (input_draw_space) {
// 		SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
// 		
// 		SDL_Rect rect;
// 		rect.x = 0;
// 		rect.y = 0;
// 		mapToOrtho(worldMap.GetWidth(), worldMap.GetHeight(), rect.w, rect.h);
// 		zoom(rect);
// 		worldToScreen(rect.x, rect.y);
// 
// 		SDL_RenderFillRect(renderer, &rect);
// 		SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
// 	}

	//draw map
	for (int y = 0; y < worldMap.GetHeight(); y++) {
		for (int x = 0; x < worldMap.GetWidth(); x++) {
			SDL_Rect rect; //in world coords
			rect.w = tileSizeX;
			rect.h = tileSizeY;
			mapToIso(x, y, rect.x, rect.y);
			zoom(rect);

			rect.y -= (tileSizeY*input_scale - tileWidth*input_scale);

			worldToScreen(rect.x, rect.y);

			SDL_Rect tileRect; //in tileset coords
			tileRect.w = tileSizeX;
			tileRect.h = tileSizeY;

			//layer terrain
			const int tileId = worldMap.Get(x,y).terrainId;
			if (tileId != -1) {
				int tileX; int tileY; getTileXY(tileId, &tileX, &tileY, TILESET_WIDTH);
				tileRect.x = tileX * tileSizeX;
				tileRect.y = tileY * tileSizeY;

				SDL_RenderCopy(renderer, tileset, &tileRect, &rect);
			}
			//layer object
			const int tileId2 = worldMap.Get(x, y).objectId;
			if (tileId2 != -1) {
				int tileObjX; int tileObjY; getTileXY(tileId2, &tileObjX, &tileObjY, TILESET_WIDTH);
				tileRect.x = tileObjX * tileSizeX;
				tileRect.y = tileObjY * tileSizeY;

				SDL_RenderCopy(renderer, tileset, &tileRect, &rect);
			}
		}
	}

// 	//draw debug rect
// 	if (input_show_debug_rect) {
// 		SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
// 		for (int y = 0; y < worldMap.GetHeight(); y++) {
// 			for (int x = 0; x < worldMap.GetWidth(); x++) {
// 				SDL_Rect rect;
// 				rect.w = tileSizeX;
// 				rect.h = tileWidth;
// 
// 				mapToOrtho(x,y,rect.x, rect.y);
// 				zoom(rect);
// 				worldToScreen(rect.x, rect.y);
// 
// 				SDL_RenderDrawRect(renderer, &rect);
// 			}
// 		}
// 		SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
// 	}

	//show editor bar
	for (int i = 0; i < NB_TILES_EDITOR; i++) {
		SDL_Rect tileRect; //in tileset coords
		tileRect.w = tileSizeX;
		tileRect.h = tileSizeY;
		const int tileId = TILES_EDITOR[i];
		int tileX; int tileY; getTileXY(tileId, &tileX, &tileY, TILESET_WIDTH);
		tileRect.x = tileX * tileSizeX;
		tileRect.y = tileY * tileSizeY;

		SDL_Rect rect; //in world coords
		rect.w = tileSizeX;
		rect.h = tileSizeY;
		rect.x = i * tileSizeX;
		rect.y = WIN_HEIGHT - tileSizeY;
		
		SDL_RenderCopy(renderer, tileset, &tileRect, &rect);
	}

	if (input_show_debug_rect) {
		SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
		for (int x = 0; x < worldMap.GetWidth() + 1; x++) {
			int x1 = x;
			int y1 = 0;
			int x2 = x;
			int y2 = worldMap.GetHeight();

			int tx1;
			int tx2;
			int ty1;
			int ty2;
			mapToIso(x1, y1, tx1, ty1);
			mapToIso(x2, y2, tx2, ty2);
			
			x1 = tx1;
			x2 = tx2;
			y1 = ty1;
			y2 = ty2;

			x1 += tileSizeX / 2;
			x2 += tileSizeX / 2;

			x1 *= input_scale;
			x2 *= input_scale;
			y1 *= input_scale;
			y2 *= input_scale;

			worldToScreen(x1, y1);
			worldToScreen(x2, y2);

			SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
		}
		for (int y = 0; y < worldMap.GetHeight() + 1; y++) {
			int x1 = 0;
			int y1 = y;
			int x2 = worldMap.GetWidth();
			int y2 = y;

			int tx1;
			int tx2;
			int ty1;
			int ty2;
			mapToIso(x1, y1, tx1, ty1);
			mapToIso(x2, y2, tx2, ty2);
			x1 = tx1;
			x2 = tx2;
			y1 = ty1;
			y2 = ty2;

			x1 += tileSizeX / 2;
			x2 += tileSizeX / 2;

			x1 *= input_scale;
			x2 *= input_scale;
			y1 *= input_scale;
			y2 *= input_scale;

			worldToScreen(x1, y1);
			worldToScreen(x2, y2);

			SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
		}
		SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
	}
}