This commit is contained in:
Jill 2023-01-05 12:08:36 +03:00
parent 581a9cb6cc
commit 44b01501f6
4 changed files with 144 additions and 1 deletions

View File

@ -29,6 +29,36 @@ date = "relative"
# allow new accounts to be created
allow_registration = true
[chests]
enabled = true
# these are the vanilla values, but free for you to tweak
[chests.small]
# in seconds
timer = 14400 # 4hr
orbs_min = 20
orbs_max = 50
orbs_increment = 5
diamonds_min = 1
diamonds_max = 4
shards_min = 0
shards_max = 1
keys_min = 0
keys_max = 1
[chests.large]
# in seconds
timer = 86400 # 24hr
orbs_min = 100
orbs_max = 300
orbs_increment = 25
diamonds_min = 4
diamonds_max = 10
shards_min = 1
shards_max = 2
keys_min = 0
keys_max = 1
[voting]
# allow votes to influence a level's difficulty when it
# hasn't been set yet. when set to false, all unrated

View File

@ -0,0 +1,16 @@
-- +migrate up
CREATE TABLE small_chests (
account_id INTEGER NOT NULL references accounts(id),
total_opened INTEGER NOT NULL DEFAULT 0,
next_at TEXT NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'now'))
);
CREATE TABLE large_chests (
account_id INTEGER NOT NULL references accounts(id),
total_opened INTEGER NOT NULL DEFAULT 0,
next_at TEXT NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'now'))
);
-- +migrate down
DROP TABLE small_chests;
DROP TABLE large_chests;

View File

@ -0,0 +1,97 @@
require "uri"
include CrystalGauntlet
XOR_KEY = "59182"
PAD_STR = "_____" # meaningless but necessary
def get_chk_value(chk_str : String)
XorCrypt.encrypt_string(Base64.decode_string(chk_str[5..]), XOR_KEY)
end
def get_rand(type : String, large = false)
base = "chests.#{large ? "large" : "small"}.#{type}"
min = config_get("#{base}_min").as?(Int64) || 0
max = config_get("#{base}_max").as?(Int64) || 0
increment = config_get("#{base}_increment").as?(Int64) || 1
((Random.rand(min.to_f .. (max.to_f + 1)) / increment).floor() * increment).to_i
end
REWARD_TYPES = ["orbs", "diamonds", "shards", "keys"]
def get_chest(account_id : Int32, large = false) : {Int32?, Int32?}
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
def claim_chest(account_id : Int32, prev_count : Int32, large = false)
table = large ? "large_chests" : "small_chests"
timer = config_get("chests.#{large ? "large" : "small"}.timer").as?(Int64) || 0
next_at = (Time.utc + timer.seconds).to_s(Format::TIME_FORMAT)
if DATABASE.scalar("select count(*) from #{table}").as(Int64) > 0
DATABASE.exec("update #{table} set total_opened = ?, next_at = ?", prev_count + 1, next_at)
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)
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" }
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(":")
resp_str = Base64.urlsafe_encode(XorCrypt.encrypt_string(resp, XOR_KEY))
return PAD_STR + resp_str + "|" + Hashes.gen_solo_4(resp_str)
}

View File

@ -39,7 +39,7 @@ module CrystalGauntlet::Accounts
end
LOG.debug {"#{account_id || udid || "???"}: gjp cache miss"}
ext_id = Accounts.get_ext_id_from_params(params)
ext_id = Accounts.get_account_id_from_params(params)
if !ext_id || !Accounts.verify_gjp(ext_id.to_i, gjp || "")
return nil, nil
end