@@ -27,6 +27,7 @@ pub fn routes(cfg: &mut web::ServiceConfig) {
27
27
)
28
28
. service ( web:: resource ( "/top" ) . route ( web:: get ( ) . to ( get_top_defenses) ) )
29
29
. service ( web:: resource ( "/transfer" ) . route ( web:: post ( ) . to ( post_transfer_artifacts) ) )
30
+ . service ( web:: resource ( "/batch_transfer" ) . route ( web:: post ( ) . to ( post_batch_transfer_artifacts) ) )
30
31
. service ( web:: resource ( "/save" ) . route ( web:: put ( ) . to ( confirm_base_details) ) )
31
32
. service ( web:: resource ( "/game/{id}" ) . route ( web:: get ( ) . to ( get_game_base_details) ) )
32
33
. service ( web:: resource ( "/history" ) . route ( web:: get ( ) . to ( defense_history) ) )
@@ -56,6 +57,11 @@ pub struct TransferArtifactResponse {
56
57
pub artifacts_in_bank : i32 ,
57
58
}
58
59
60
+ #[ derive( Deserialize ) ]
61
+ pub struct BatchTransferArtifacts {
62
+ pub transfers : Vec < TransferArtifactEntry > ,
63
+ }
64
+
59
65
async fn post_transfer_artifacts (
60
66
transfer : Json < TransferArtifactEntry > ,
61
67
pg_pool : Data < PgPool > ,
@@ -193,6 +199,149 @@ async fn post_transfer_artifacts(
193
199
} ) )
194
200
}
195
201
202
+ async fn post_batch_transfer_artifacts (
203
+ batch_transfer : Json < BatchTransferArtifacts > ,
204
+ pg_pool : Data < PgPool > ,
205
+ redis_pool : Data < RedisPool > ,
206
+ user : AuthUser ,
207
+ ) -> Result < impl Responder > {
208
+ let user_id = user. 0 ;
209
+ let mut redis_conn = redis_pool
210
+ . get ( )
211
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
212
+
213
+ if let Ok ( Some ( _) ) = get_game_id_from_redis ( user_id, & mut redis_conn, false ) {
214
+ return Err ( ErrorBadRequest (
215
+ "You are under attack. Cannot transfer artifacts" ,
216
+ ) ) ;
217
+ }
218
+
219
+ let transfers = batch_transfer. into_inner ( ) . transfers ;
220
+ let mut responses = Vec :: new ( ) ;
221
+
222
+ for transfer in transfers {
223
+ let mut conn = pg_pool
224
+ . get ( )
225
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
226
+ let bank_block_type_id =
227
+ web:: block ( move || util:: get_block_id_of_bank ( & mut conn, & user_id) )
228
+ . await ?
229
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
230
+
231
+ let mut conn = pg_pool
232
+ . get ( )
233
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
234
+ let current_layout_id = web:: block ( move || {
235
+ util:: check_valid_map_id ( & mut conn, & user_id, & transfer. map_space_id )
236
+ } )
237
+ . await ?
238
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
239
+
240
+ let mut conn = pg_pool
241
+ . get ( )
242
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
243
+ let is_valid_map_space_building = web:: block ( move || {
244
+ util:: check_valid_map_space_building ( & mut conn, & transfer. map_space_id )
245
+ } )
246
+ . await ?
247
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
248
+
249
+ if !is_valid_map_space_building {
250
+ return Err ( ErrorBadRequest (
251
+ "Map Space ID does not correspond to a valid building" ,
252
+ ) ) ;
253
+ }
254
+
255
+ let mut conn = pg_pool
256
+ . get ( )
257
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
258
+ let bank_map_space_id = web:: block ( move || {
259
+ util:: get_bank_map_space_id ( & mut conn, & current_layout_id, & bank_block_type_id)
260
+ } )
261
+ . await ?
262
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
263
+
264
+ if bank_map_space_id == transfer. map_space_id {
265
+ return Err ( ErrorBadRequest ( "Cannot transfer to the same building" ) ) ;
266
+ }
267
+
268
+ let mut conn = pg_pool
269
+ . get ( )
270
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
271
+ let bank_artifact_count = web:: block ( move || {
272
+ util:: get_building_artifact_count ( & mut conn, & current_layout_id, & bank_map_space_id)
273
+ } )
274
+ . await ?
275
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
276
+
277
+ if transfer. artifacts_differ > bank_artifact_count {
278
+ return Err ( ErrorBadRequest ( "Not enough artifacts in the bank" ) ) ;
279
+ }
280
+
281
+ let mut conn = pg_pool
282
+ . get ( )
283
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
284
+ let mut building_artifact_count = web:: block ( move || {
285
+ util:: get_building_artifact_count ( & mut conn, & current_layout_id, & transfer. map_space_id )
286
+ } )
287
+ . await ?
288
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
289
+
290
+ if building_artifact_count == -1 {
291
+ let mut conn = pg_pool
292
+ . get ( )
293
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
294
+ web:: block ( move || util:: create_artifact_record ( & mut conn, & transfer. map_space_id , & 0 ) )
295
+ . await ?
296
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
297
+ building_artifact_count = 0 ;
298
+ }
299
+
300
+ if transfer. artifacts_differ + building_artifact_count < 0 {
301
+ return Err ( ErrorBadRequest ( "Not enough artifacts in the building" ) ) ;
302
+ }
303
+
304
+ let mut conn = pg_pool
305
+ . get ( )
306
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
307
+ let building_capacity =
308
+ web:: block ( move || util:: get_building_capacity ( & mut conn, & transfer. map_space_id ) )
309
+ . await ?
310
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
311
+
312
+ if building_capacity < transfer. artifacts_differ + building_artifact_count {
313
+ return Err ( ErrorBadRequest ( "Building capacity not sufficient" ) ) ;
314
+ }
315
+
316
+ let new_building_artifact_count = building_artifact_count + transfer. artifacts_differ ;
317
+ let new_bank_artifact_count = bank_artifact_count - transfer. artifacts_differ ;
318
+
319
+ let mut conn = pg_pool
320
+ . get ( )
321
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
322
+ web:: block ( move || {
323
+ util:: transfer_artifacts_building (
324
+ & mut conn,
325
+ & transfer. map_space_id ,
326
+ & bank_map_space_id,
327
+ & new_building_artifact_count,
328
+ & new_bank_artifact_count,
329
+ )
330
+ } )
331
+ . await ?
332
+ . map_err ( |err| error:: handle_error ( err. into ( ) ) ) ?;
333
+
334
+ responses. push ( TransferArtifactResponse {
335
+ building_map_space_id : transfer. map_space_id ,
336
+ artifacts_in_building : new_building_artifact_count,
337
+ bank_map_space_id,
338
+ artifacts_in_bank : new_bank_artifact_count,
339
+ } ) ;
340
+ }
341
+
342
+ Ok ( web:: Json ( responses) )
343
+ }
344
+
196
345
async fn get_user_base_details ( pool : Data < PgPool > , user : AuthUser ) -> Result < impl Responder > {
197
346
let defender_id = user. 0 ;
198
347
let response = web:: block ( move || {
0 commit comments