Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat:added route - /batch_transfer #86

Merged
merged 3 commits into from
Jan 12, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading