2023-01-04 00:20:45 +01:00
include CrystalGauntlet
module CrystalGauntlet::Dailies
extend self
# todo: merge the two tables into one maybe
WEEKLY_OFFSET = 100001
2023-01-04 16:44:49 +01:00
def grab_new_level ( weekly : Bool , prev = Time . utc , prev_idx = 0 ) : { Int32 ?, Int32 ?, Int32 ?}
LOG . debug { " grabbing new event level, weekly: #{ weekly } (previous queue index #{ prev_idx } ) " }
2023-01-04 00:20:45 +01:00
begin
2023-01-04 16:44:49 +01:00
level_id , new_idx = DATABASE . query_one ( " select level_id, idx from #{ weekly ? " weekly_queue " : " daily_queue " } where idx > #{ prev_idx } order by idx limit 1 " , as : { Int32 , Int32 } )
2023-01-04 00:20:45 +01:00
rescue
2023-01-04 16:44:49 +01:00
LOG . debug { " can't find new level in queue, attempting reuse " }
begin
level_id , new_idx = DATABASE . query_one ( " select level_id, idx from #{ weekly ? " weekly_queue " : " daily_queue " } order by idx desc limit 1 " , as : { Int32 , Int32 } )
rescue
LOG . debug { " no levels in queue; quitting out " }
return { nil , nil , nil }
end
2023-01-04 00:20:45 +01:00
end
2023-01-04 16:44:49 +01:00
next_id = IDs . get_next_id ( weekly ? " weekly_levels " : " daily_levels " )
# todo: configurable?
timespan = weekly ? 1 . weeks : 1 . days
LOG . debug { " #{ level_id } for #{ timespan } " }
expires_at = prev + timespan
DATABASE . exec ( " insert into #{ weekly ? " weekly_levels " : " daily_levels " } (level_id, idx, expires_at, queue_idx) values (?, ?, ?, ?) " , level_id , next_id , expires_at . to_s ( Format :: TIME_FORMAT ) , new_idx )
return { level_id , timespan . total_seconds . to_i , next_id }
2023-01-04 00:20:45 +01:00
end
def fetch_current_level ( weekly : Bool ) : { Int32 | Nil , Int32 | Nil , Int32 | Nil }
2023-01-04 16:10:26 +01:00
LOG . debug { " getting current event level, weekly: #{ weekly } " }
2023-01-04 00:20:45 +01:00
begin
2023-01-04 16:44:49 +01:00
level_id , expires_at , idx , queue_idx = DATABASE . query_one ( " select level_id, expires_at, idx, queue_idx from #{ weekly ? " weekly_levels " : " daily_levels " } order by idx desc limit 1 " , as : { Int32 , String , Int32 , Int32 } )
2023-01-04 16:10:26 +01:00
LOG . debug { " #{ level_id } ( #{ idx } ), expiring at #{ expires_at } " }
2023-01-04 00:20:45 +01:00
rescue
# make up a brand new daily; using current time because no previous ones have existed
2023-01-04 16:10:26 +01:00
LOG . debug { " no levels have ever existed " }
2023-01-04 00:20:45 +01:00
level_id , expires , idx = grab_new_level ( weekly )
else
# check if it has expired, roll a new one if so
2023-01-04 00:42:04 +01:00
expires = ( Time . parse ( expires_at , Format :: TIME_FORMAT , Time :: Location :: UTC ) - Time . utc ) . total_seconds . to_i
2023-01-04 00:20:45 +01:00
if expires <= 0
2023-01-04 16:10:26 +01:00
LOG . debug { " expired!! " }
2023-01-04 16:44:49 +01:00
level_id , expires , idx = grab_new_level ( weekly , Time . parse ( expires_at , Format :: TIME_FORMAT , Time :: Location :: UTC ) , queue_idx )
2023-01-04 00:20:45 +01:00
end
end
2023-01-04 16:10:26 +01:00
LOG . debug { " returning #{ level_id } #{ idx } , expiring in #{ expires } s " }
2023-01-04 00:20:45 +01:00
return level_id , expires , idx
end
end