chests
This commit is contained in:
parent
581a9cb6cc
commit
44b01501f6
|
@ -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
|
||||
|
|
|
@ -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;
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue