dumb daily levels implementation
This commit is contained in:
parent
17a4332e24
commit
9b55f5c423
|
@ -0,0 +1,28 @@
|
|||
-- +migrate up
|
||||
CREATE TABLE daily_queue (
|
||||
level_id INTEGER NOT NULL references levels(id),
|
||||
idx SERIAL NOT NULL PRIMARY KEY
|
||||
);
|
||||
|
||||
CREATE TABLE daily_levels (
|
||||
level_id INTEGER NOT NULL references levels(id),
|
||||
idx SERIAL NOT NULL PRIMARY KEY,
|
||||
expires_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE weekly_queue (
|
||||
level_id INTEGER NOT NULL references levels(id),
|
||||
idx SERIAL NOT NULL PRIMARY KEY
|
||||
);
|
||||
|
||||
CREATE TABLE weekly_levels (
|
||||
level_id INTEGER NOT NULL references levels(id),
|
||||
idx SERIAL NOT NULL PRIMARY KEY,
|
||||
expires_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
-- +migrate down
|
||||
DROP TABLE daily_queue;
|
||||
DROP TABLE daily_levels;
|
||||
DROP TABLE weekly_queue;
|
||||
DROP TABLE weekly_levels;
|
|
@ -18,6 +18,7 @@ require "./lib/clean"
|
|||
require "./lib/songs"
|
||||
require "./lib/ids"
|
||||
require "./lib/level"
|
||||
require "./lib/dailies"
|
||||
|
||||
if File.exists?(".env")
|
||||
Dotenv.load
|
||||
|
|
|
@ -9,7 +9,30 @@ CrystalGauntlet.endpoints["/downloadGJLevel22.php"] = ->(context : HTTP::Server:
|
|||
|
||||
response = [] of String
|
||||
|
||||
DATABASE.query("select levels.id, levels.name, levels.extra_data, levels.level_info, levels.password, levels.user_id, levels.description, levels.original, levels.game_version, levels.requested_stars, levels.version, levels.song_id, levels.length, levels.objects, levels.coins, levels.has_ldm, levels.two_player, levels.downloads, levels.likes, levels.difficulty, levels.community_difficulty, levels.demon_difficulty, levels.stars, levels.featured, levels.epic, levels.rated_coins, users.username, users.udid, users.account_id, users.registered, editor_time, editor_time_copies from levels join users on levels.user_id = users.id where levels.id = ?", params["levelID"].to_i32) do |rs|
|
||||
level_id = params["levelID"].to_i32
|
||||
daily_num = nil # for hash checks
|
||||
|
||||
case level_id
|
||||
when -1
|
||||
# daily
|
||||
level_id, _, idx = Dailies.fetch_current_level(false)
|
||||
if !level_id || !idx
|
||||
return "-1"
|
||||
end
|
||||
daily_num = idx
|
||||
when -2
|
||||
# weekly
|
||||
level_id, _, idx = Dailies.fetch_current_level(true)
|
||||
if !level_id || !idx
|
||||
return "-1"
|
||||
end
|
||||
daily_num = idx + Dailies::WEEKLY_OFFSET
|
||||
when -3
|
||||
# events
|
||||
raise "events?? what the hell"
|
||||
end
|
||||
|
||||
DATABASE.query("select levels.id, levels.name, levels.extra_data, levels.level_info, levels.password, levels.user_id, levels.description, levels.original, levels.game_version, levels.requested_stars, levels.version, levels.song_id, levels.length, levels.objects, levels.coins, levels.has_ldm, levels.two_player, levels.downloads, levels.likes, levels.difficulty, levels.community_difficulty, levels.demon_difficulty, levels.stars, levels.featured, levels.epic, levels.rated_coins, users.username, users.udid, users.account_id, users.registered, editor_time, editor_time_copies from levels join users on levels.user_id = users.id where levels.id = ?", level_id) do |rs|
|
||||
if rs.move_next
|
||||
id = rs.read(Int32)
|
||||
name = rs.read(String)
|
||||
|
@ -102,6 +125,7 @@ CrystalGauntlet.endpoints["/downloadGJLevel22.php"] = ->(context : HTTP::Server:
|
|||
38 => rated_coins,
|
||||
39 => requested_stars || 0,
|
||||
40 => has_ldm,
|
||||
41 => daily_num,
|
||||
42 => epic,
|
||||
# 0 for n/a, 10 for easy, 20, for medium, ...
|
||||
43 => (demon_difficulty || DemonDifficulty::Hard).to_demon_difficulty,
|
||||
|
@ -113,9 +137,13 @@ CrystalGauntlet.endpoints["/downloadGJLevel22.php"] = ->(context : HTTP::Server:
|
|||
})
|
||||
response << Hashes.gen_solo(level_data)
|
||||
|
||||
thing = [user_id, stars || 0, (difficulty && difficulty.demon?) || 0, id, rated_coins, featured, password, 0].map { |x| Format.fmt_value(x) }
|
||||
thing = [user_id, stars || 0, (difficulty && difficulty.demon?) || 0, id, rated_coins, featured, password, daily_num || 0].map { |x| Format.fmt_value(x) }
|
||||
response << Hashes.gen_solo_2(thing.join(","))
|
||||
|
||||
if daily_num
|
||||
response << [user_id, user_username, user_account_id].join(":")
|
||||
end
|
||||
|
||||
return response.join("#")
|
||||
else
|
||||
return "-1"
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
require "uri"
|
||||
|
||||
include CrystalGauntlet
|
||||
|
||||
CrystalGauntlet.endpoints["/getGJDailyLevel.php"] = ->(context : HTTP::Server::Context): String {
|
||||
params = URI::Params.parse(context.request.body.not_nil!.gets_to_end)
|
||||
LOG.debug { params.inspect }
|
||||
|
||||
weekly = params["weekly"] == "1"
|
||||
|
||||
level_id = nil
|
||||
expires = nil
|
||||
|
||||
level_id, expires, idx = Dailies.fetch_current_level(weekly)
|
||||
|
||||
if !level_id || !expires || !idx
|
||||
"-1"
|
||||
else
|
||||
if weekly
|
||||
idx += Dailies::WEEKLY_OFFSET
|
||||
end
|
||||
|
||||
[idx, expires].join("|")
|
||||
end
|
||||
}
|
|
@ -156,11 +156,13 @@ CrystalGauntlet.endpoints["/getGJLevels21.php"] = ->(context : HTTP::Server::Con
|
|||
when "13" # friends
|
||||
# todo
|
||||
when "21" # daily
|
||||
# todo
|
||||
order = "daily_levels.idx desc"
|
||||
joins << "join daily_levels on levels.id = daily_levels.level_id"
|
||||
when "22" # weekly
|
||||
# todo
|
||||
order = "weekly_levels.idx desc"
|
||||
joins << "join weekly_levels on levels.id = weekly_levels.level_id"
|
||||
when "23" # event (unused)
|
||||
# todo
|
||||
# todo..?
|
||||
end
|
||||
|
||||
if !can_see_unlisted
|
||||
|
|
|
@ -33,14 +33,12 @@ CrystalGauntlet.endpoints["/getGJLevelScores211.php"] = ->(context : HTTP::Serve
|
|||
return "-1"
|
||||
end
|
||||
|
||||
# todo: account for dailies
|
||||
|
||||
if DATABASE.scalar("select count(*) from level_scores where account_id = ? and level_id = ?", account_id, level_id).as(Int64) > 0
|
||||
if DATABASE.scalar("select count(*) from level_scores where account_id = ? and level_id = ? and daily_id is ?", account_id, level_id, daily_id).as(Int64) > 0
|
||||
# check if an update is truly necessary
|
||||
percent_old, coins_old = DATABASE.query_one("select percent, coins from level_scores where account_id = ? and level_id = ?", account_id, level_id, as: {Int32, Int32})
|
||||
percent_old, coins_old = DATABASE.query_one("select percent, coins from level_scores where account_id = ? and level_id = ? and daily_id is ?", account_id, level_id, daily_id, as: {Int32, Int32})
|
||||
|
||||
if percent > percent_old || coins > coins_old
|
||||
DATABASE.exec("update level_scores set account_id=?, level_id=?, daily_id=?, percent=?, attempts=?, clicks=?, coins=?, progress=?, time=?, set_at=? where account_id = ? and level_id = ?", account_id, level_id, daily_id, percent, attempts, clicks, coins, progress, time, Time.utc.to_s(Format::TIME_FORMAT), account_id, level_id)
|
||||
DATABASE.exec("update level_scores set account_id=?, percent=?, attempts=?, clicks=?, coins=?, progress=?, time=?, set_at=? where account_id = ? and level_id = ? and daily_id is ?", account_id, percent, attempts, clicks, coins, progress, time, Time.utc.to_s(Format::TIME_FORMAT), account_id, level_id, daily_id)
|
||||
end
|
||||
else
|
||||
DATABASE.exec("insert into level_scores (account_id, level_id, daily_id, percent, attempts, clicks, coins, progress, time) values (?, ?, ?, ?, ?, ?, ?, ?, ?)", account_id, level_id, daily_id, percent, attempts, clicks, coins, progress, time)
|
||||
|
@ -51,7 +49,7 @@ CrystalGauntlet.endpoints["/getGJLevelScores211.php"] = ->(context : HTTP::Serve
|
|||
|
||||
type = params["type"]? ? params["type"] : "1"
|
||||
|
||||
where_query = ["level_id = ?"]
|
||||
where_query = ["level_id = ? and daily_id is ?"]
|
||||
|
||||
case type
|
||||
when 0
|
||||
|
@ -68,7 +66,7 @@ CrystalGauntlet.endpoints["/getGJLevelScores211.php"] = ->(context : HTTP::Serve
|
|||
scores = [] of String
|
||||
|
||||
i = 0
|
||||
DATABASE.query_each "select percent, level_scores.coins, set_at, users.username, users.id, users.icon_type, users.color1, users.color2, users.cube, users.ship, users.ball, users.ufo, users.wave, users.robot, users.spider, users.special, users.account_id from level_scores join users on level_scores.account_id = users.account_id where (#{where_query.join(") and (")}) order by percent desc, level_scores.coins desc limit 200", level_id do |rs|
|
||||
DATABASE.query_each "select percent, level_scores.coins, set_at, users.username, users.id, users.icon_type, users.color1, users.color2, users.cube, users.ship, users.ball, users.ufo, users.wave, users.robot, users.spider, users.special, users.account_id from level_scores join users on level_scores.account_id = users.account_id where (#{where_query.join(") and (")}) order by percent desc, level_scores.coins desc limit 200", level_id, daily_id do |rs|
|
||||
i += 1
|
||||
percent = rs.read(Int32)
|
||||
coins = rs.read(Int32)
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
include CrystalGauntlet
|
||||
|
||||
module CrystalGauntlet::Dailies
|
||||
extend self
|
||||
|
||||
# todo: merge the two tables into one maybe
|
||||
|
||||
WEEKLY_OFFSET = 100001
|
||||
|
||||
def grab_new_level(weekly : Bool, prev = Time.utc) : {Int32 | Nil, Int32 | Nil, Int32 | Nil}
|
||||
begin
|
||||
level_id = DATABASE.query_one("select level_id from #{weekly ? "weekly_queue" : "daily_queue"} order by idx desc limit 1", as: {Int32})
|
||||
rescue
|
||||
return {nil, nil, nil}
|
||||
else
|
||||
next_id = IDs.get_next_id(weekly ? "weekly_levels" : "daily_levels")
|
||||
# todo: configurable?
|
||||
timespan = weekly ? 1.weeks : 1.days
|
||||
expires_at = prev + timespan
|
||||
DATABASE.exec("insert into #{weekly ? "weekly_levels" : "daily_levels"} (level_id, idx, expires_at) values (?, ?, ?)", level_id, next_id, expires_at.to_s(Format::TIME_FORMAT))
|
||||
return {level_id, timespan.total_seconds.to_i, next_id}
|
||||
end
|
||||
end
|
||||
|
||||
def fetch_current_level(weekly : Bool) : {Int32 | Nil, Int32 | Nil, Int32 | Nil}
|
||||
begin
|
||||
level_id, expires_at, idx = DATABASE.query_one("select level_id, expires_at, idx from #{weekly ? "weekly_levels" : "daily_levels"} order by idx desc limit 1", as: {Int32, String, Int32})
|
||||
rescue
|
||||
# make up a brand new daily; using current time because no previous ones have existed
|
||||
level_id, expires, idx = grab_new_level(weekly)
|
||||
else
|
||||
# check if it has expired, roll a new one if so
|
||||
expires = (Time.utc - Time.parse(expires_at, Format::TIME_FORMAT, Time::Location::UTC)).total_seconds.to_i
|
||||
if expires <= 0
|
||||
level_id, expires, idx = grab_new_level(weekly, Time.parse(expires_at, Format::TIME_FORMAT, Time::Location::UTC))
|
||||
end
|
||||
end
|
||||
|
||||
return level_id, expires, idx
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue