2023-01-05 10:08:36 +01:00
require " uri "
include CrystalGauntlet
2023-01-05 13:57:26 +01:00
private PAD_STR = " _____ " # meaningless but necessary
2023-01-05 10:08:36 +01:00
2023-01-05 13:57:26 +01:00
private def get_chk_value ( chk_str : String )
XorCrypt . encrypt_string ( Base64 . decode_string ( chk_str [ 5 .. ] ) , XorCrypt :: CHEST_XOR_KEY )
2023-01-05 10:08:36 +01:00
end
2023-01-05 13:57:26 +01:00
private def get_rand ( type : String , large = false )
2023-01-05 10:08:36 +01:00
base = " chests. #{ large ? " large " : " small " } . #{ type } "
2023-01-07 09:54:13 +01:00
min = config_get ( " #{ base } _min " , 0 _i64 )
max = config_get ( " #{ base } _max " , 0 _i64 )
increment = config_get ( " #{ base } _increment " , 1_i64 )
2023-01-05 10:08:36 +01:00
( ( Random . rand ( min . to_f .. ( max . to_f + 1 ) ) / increment ) . floor ( ) * increment ) . to_i
end
2023-01-05 17:07:44 +01:00
private REWARD_TYPES = StaticArray [ " orbs " , " diamonds " , " shards " , " keys " ]
2023-01-05 10:08:36 +01:00
2023-01-05 13:57:26 +01:00
private def get_chest ( account_id : Int32 , large = false ) : { Int32 ?, Int32 ?}
2023-01-05 10:08:36 +01:00
begin
total , next_at = DATABASE . query_one ( " select total_opened, next_at from #{ large ? " large_chests " : " small_chests " } where account_id = ? " , account_id , as : { Int32 , String } )
rescue
{ 0 , 0 }
else
{ total , Math . max ( ( Time . parse ( next_at , Format :: TIME_FORMAT , Time :: Location :: UTC ) - Time . utc ) . total_seconds . to_i , 0 ) }
end
end
2023-01-05 13:57:26 +01:00
private def claim_chest ( account_id : Int32 , prev_count : Int32 , large = false )
2023-01-05 10:08:36 +01:00
table = large ? " large_chests " : " small_chests "
2023-01-07 09:54:13 +01:00
timer = config_get ( " chests. #{ large ? " large " : " small " } .timer " , 0 _i64 )
2023-01-05 10:08:36 +01:00
next_at = ( Time . utc + timer . seconds ) . to_s ( Format :: TIME_FORMAT )
2023-01-05 10:34:24 +01:00
if DATABASE . scalar ( " select count(*) from #{ table } where account_id = ? " , account_id ) . as ( Int64 ) > 0
2023-01-05 10:28:41 +01:00
DATABASE . exec ( " update #{ table } set total_opened = ?, next_at = ? where account_id = ? " , prev_count + 1 , next_at , account_id )
2023-01-05 10:08:36 +01:00
else
DATABASE . exec ( " insert into #{ table } (account_id, total_opened, next_at) values (?, ?, ?) " , account_id , prev_count + 1 , next_at )
end
return timer
end
CrystalGauntlet . endpoints [ " /getGJRewards.php " ] = - > ( context : HTTP :: Server :: Context ) : String {
params = URI :: Params . parse ( context . request . body . not_nil! . gets_to_end )
LOG . debug { params . inspect }
if ! config_get ( " chests.enabled " ) . as? ( Bool )
2023-01-05 10:22:25 +01:00
LOG . debug { " chests disabled " }
2023-01-05 10:08:36 +01:00
return " -1 "
end
user_id , account_id = Accounts . auth ( params )
if ! ( user_id && account_id )
return " -1 "
end
small_total , small_next = get_chest ( account_id , false )
large_total , large_next = get_chest ( account_id , true )
LOG . debug { " small: #{ small_next } s, large: #{ large_next } s " }
2023-01-07 09:46:18 +01:00
# todo: figure out why opening one chest resets the other visually
2023-01-05 10:08:36 +01:00
case params [ " rewardType " ]
when " 1 "
if small_next > 0
LOG . debug { " you still need to wait #{ small_next } s " }
return " -1 "
end
small_next = claim_chest ( account_id , small_total , false )
when " 2 "
if large_next > 0
LOG . debug { " you still need to wait #{ large_next } s " }
return " -1 "
end
large_next = claim_chest ( account_id , large_total , true )
end
resp = [
PAD_STR ,
user_id ,
String . new ( get_chk_value ( params [ " chk " ] ) ) ,
params [ " udid " ] ,
account_id ,
# small
small_next , REWARD_TYPES . map { | t | get_rand ( t , false ) } . join ( " , " ) , small_total ,
# large
large_next , REWARD_TYPES . map { | t | get_rand ( t , true ) } . join ( " , " ) , large_total ,
params [ " rewardType " ] . to_i? || 0
] . join ( " : " )
2023-01-05 13:57:26 +01:00
resp_str = Base64 . urlsafe_encode ( XorCrypt . encrypt_string ( resp , XorCrypt :: CHEST_XOR_KEY ) )
2023-01-05 10:08:36 +01:00
return PAD_STR + resp_str + " | " + Hashes . gen_solo_4 ( resp_str )
}