Skip to content

Commit

Permalink
feat: batch_transfer
Browse files Browse the repository at this point in the history
* Feat:added route - /batch_transfer

* Feat:added route - /batch_transfer

---------

Co-authored-by: SKsai <[email protected]>
  • Loading branch information
SaiSakthidar and SK-47 authored Jan 12, 2025
1 parent bbceec8 commit 2ab2320
Showing 1 changed file with 149 additions and 0 deletions.
149 changes: 149 additions & 0 deletions src/api/defense/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub fn routes(cfg: &mut web::ServiceConfig) {
)
.service(web::resource("/top").route(web::get().to(get_top_defenses)))
.service(web::resource("/transfer").route(web::post().to(post_transfer_artifacts)))
.service(web::resource("/batch_transfer").route(web::post().to(post_batch_transfer_artifacts)))
.service(web::resource("/save").route(web::put().to(confirm_base_details)))
.service(web::resource("/game/{id}").route(web::get().to(get_game_base_details)))
.service(web::resource("/history").route(web::get().to(defense_history)))
Expand Down Expand Up @@ -56,6 +57,11 @@ pub struct TransferArtifactResponse {
pub artifacts_in_bank: i32,
}

#[derive(Deserialize)]
pub struct BatchTransferArtifacts {
pub transfers: Vec<TransferArtifactEntry>,
}

async fn post_transfer_artifacts(
transfer: Json<TransferArtifactEntry>,
pg_pool: Data<PgPool>,
Expand Down Expand Up @@ -193,6 +199,149 @@ async fn post_transfer_artifacts(
}))
}

async fn post_batch_transfer_artifacts(
batch_transfer: Json<BatchTransferArtifacts>,
pg_pool: Data<PgPool>,
redis_pool: Data<RedisPool>,
user: AuthUser,
) -> Result<impl Responder> {
let user_id = user.0;
let mut redis_conn = redis_pool
.get()
.map_err(|err| error::handle_error(err.into()))?;

if let Ok(Some(_)) = get_game_id_from_redis(user_id, &mut redis_conn, false) {
return Err(ErrorBadRequest(
"You are under attack. Cannot transfer artifacts",
));
}

let transfers = batch_transfer.into_inner().transfers;
let mut responses = Vec::new();

for transfer in transfers {
let mut conn = pg_pool
.get()
.map_err(|err| error::handle_error(err.into()))?;
let bank_block_type_id =
web::block(move || util::get_block_id_of_bank(&mut conn, &user_id))
.await?
.map_err(|err| error::handle_error(err.into()))?;

let mut conn = pg_pool
.get()
.map_err(|err| error::handle_error(err.into()))?;
let current_layout_id = web::block(move || {
util::check_valid_map_id(&mut conn, &user_id, &transfer.map_space_id)
})
.await?
.map_err(|err| error::handle_error(err.into()))?;

let mut conn = pg_pool
.get()
.map_err(|err| error::handle_error(err.into()))?;
let is_valid_map_space_building = web::block(move || {
util::check_valid_map_space_building(&mut conn, &transfer.map_space_id)
})
.await?
.map_err(|err| error::handle_error(err.into()))?;

if !is_valid_map_space_building {
return Err(ErrorBadRequest(
"Map Space ID does not correspond to a valid building",
));
}

let mut conn = pg_pool
.get()
.map_err(|err| error::handle_error(err.into()))?;
let bank_map_space_id = web::block(move || {
util::get_bank_map_space_id(&mut conn, &current_layout_id, &bank_block_type_id)
})
.await?
.map_err(|err| error::handle_error(err.into()))?;

if bank_map_space_id == transfer.map_space_id {
return Err(ErrorBadRequest("Cannot transfer to the same building"));
}

let mut conn = pg_pool
.get()
.map_err(|err| error::handle_error(err.into()))?;
let bank_artifact_count = web::block(move || {
util::get_building_artifact_count(&mut conn, &current_layout_id, &bank_map_space_id)
})
.await?
.map_err(|err| error::handle_error(err.into()))?;

if transfer.artifacts_differ > bank_artifact_count {
return Err(ErrorBadRequest("Not enough artifacts in the bank"));
}

let mut conn = pg_pool
.get()
.map_err(|err| error::handle_error(err.into()))?;
let mut building_artifact_count = web::block(move || {
util::get_building_artifact_count(&mut conn, &current_layout_id, &transfer.map_space_id)
})
.await?
.map_err(|err| error::handle_error(err.into()))?;

if building_artifact_count == -1 {
let mut conn = pg_pool
.get()
.map_err(|err| error::handle_error(err.into()))?;
web::block(move || util::create_artifact_record(&mut conn, &transfer.map_space_id, &0))
.await?
.map_err(|err| error::handle_error(err.into()))?;
building_artifact_count = 0;
}

if transfer.artifacts_differ + building_artifact_count < 0 {
return Err(ErrorBadRequest("Not enough artifacts in the building"));
}

let mut conn = pg_pool
.get()
.map_err(|err| error::handle_error(err.into()))?;
let building_capacity =
web::block(move || util::get_building_capacity(&mut conn, &transfer.map_space_id))
.await?
.map_err(|err| error::handle_error(err.into()))?;

if building_capacity < transfer.artifacts_differ + building_artifact_count {
return Err(ErrorBadRequest("Building capacity not sufficient"));
}

let new_building_artifact_count = building_artifact_count + transfer.artifacts_differ;
let new_bank_artifact_count = bank_artifact_count - transfer.artifacts_differ;

let mut conn = pg_pool
.get()
.map_err(|err| error::handle_error(err.into()))?;
web::block(move || {
util::transfer_artifacts_building(
&mut conn,
&transfer.map_space_id,
&bank_map_space_id,
&new_building_artifact_count,
&new_bank_artifact_count,
)
})
.await?
.map_err(|err| error::handle_error(err.into()))?;

responses.push(TransferArtifactResponse {
building_map_space_id: transfer.map_space_id,
artifacts_in_building: new_building_artifact_count,
bank_map_space_id,
artifacts_in_bank: new_bank_artifact_count,
});
}

Ok(web::Json(responses))
}

async fn get_user_base_details(pool: Data<PgPool>, user: AuthUser) -> Result<impl Responder> {
let defender_id = user.0;
let response = web::block(move || {
Expand Down

0 comments on commit 2ab2320

Please sign in to comment.