lightly fucked level scores

This commit is contained in:
Jill 2022-12-31 09:28:06 +03:00
parent 45bc61c3cb
commit d9a73fe813
5 changed files with 141 additions and 9 deletions

View File

@ -0,0 +1,18 @@
-- +migrate up
CREATE TABLE level_scores (
account_id INTEGER NOT NULL references accounts(id),
level_id INTEGER NOT NULL references levels(id),
daily_id INTEGER,
percent INTEGER NOT NULL,
attempts INTEGER NOT NULL DEFAULT 0,
clicks INTEGER NOT NULL DEFAULT 0,
coins INTEGER NOT NULL DEFAULT 0,
progress TEXT NOT NULL DEFAULT "",
time INTEGER NOT NULL,
set_at TEXT NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'now'))
);
-- +migrate down
DROP TABLE level_scores;

View File

@ -0,0 +1,103 @@
require "uri"
include CrystalGauntlet
CrystalGauntlet.endpoints["/getGJLevelScores211.php"] = ->(body : String): String {
params = URI::Params.parse(body)
puts params.inspect
account_id = Accounts.get_account_id_from_params(params)
if !account_id || !Accounts.verify_gjp(account_id, params["gjp"])
return "-1"
end
level_id = params["levelID"].to_i32
daily_id = params["s10"].to_i32
if daily_id == 0
daily_id = nil
end
if params["percent"]? && params["percent"]? != "0"
# set score
attempts = params["s1"].to_i - 8354
clicks = params["s2"].to_i - 3991
time = params["s3"].to_i - 4085
# todo: fix
# progress = XorCrypt.encrypt_string(GDBase64.decode_string(params["s6"]), "41274")
coins = params["s9"].to_i - 5819
if coins > 3
return "-1"
end
percent = params["percent"].to_i
if percent > 100
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
# 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})
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, "", time, Time.utc.to_s("%Y-%m-%d %H:%M:%S"), account_id, level_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, "", time)
end
end
# return set scores
type = params["type"]? ? params["type"] : "1"
case type
when 0
# friends
# todo
when 1
# global
# todo
when 2
# weekly
# todo
end
scores = [] of String
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 level_id = ? order by percent, level_scores.coins desc", level_id do |rs|
percent = rs.read(Int32)
coins = rs.read(Int32)
set_at = rs.read(String)
username = rs.read(String)
user_id = rs.read(Int32)
icon_type = rs.read(Int32)
color1 = rs.read(Int32)
color2 = rs.read(Int32)
icon_value = [rs.read(Int32), rs.read(Int32), rs.read(Int32), rs.read(Int32), rs.read(Int32), rs.read(Int32), rs.read(Int32)][icon_type]
special = rs.read(Int32)
account_id = rs.read(Int32)
scores << Format.fmt_hash({
1 => username,
2 => user_id,
9 => icon_value,
10 => color1,
11 => color2,
14 => icon_type,
15 => special,
16 => account_id,
3 => percent,
6 => percent == 100 ? 1 : (percent > 75 ? 2 : 3), # ???
13 => coins,
42 => set_at
})
end
scores.join("|")
}

View File

@ -6,8 +6,9 @@ CrystalGauntlet.endpoints["/uploadGJLevel21.php"] = ->(body : String): String {
params = URI::Params.parse(body)
puts params.inspect
# todo: green user fixes? pretty please?
ext_id = Accounts.get_ext_id_from_params(params)
if ext_id == "-1" || !Accounts.verify_gjp(ext_id, params["gjp"])
if !ext_id || !Accounts.verify_gjp(ext_id.to_i, params["gjp"])
return "-1"
end
user_id = Accounts.get_user_id(ext_id)

View File

@ -8,17 +8,18 @@ CrystalGauntlet.endpoints["/updateGJUserScore22.php"] = ->(body : String): Strin
params = URI::Params.parse(body)
puts params.inspect
account_id = Accounts.get_ext_id_from_params(params)
if !Accounts.verify_gjp(account_id, params["gjp"])
account_id = Accounts.get_account_id_from_params(params)
if !account_id || !Accounts.verify_gjp(account_id, params["gjp"])
return "-1"
end
user_id = Accounts.get_user_id(account_id)
user_id = Accounts.get_user_id(account_id.to_s)
# todo: prevent username change unless it's a capitalization change
# todo: update account username casing w/ user username
# todo: keep track of stat changes to look out for leaderboard cheating & whatnot
# todo: cap out demon count at the current amount of uploaded demons? same for stars & user coins. could be expensive though
# todo: cap icon type
DATABASE.exec("update users set username=?, stars=?, demons=?, coins=?, user_coins=?, diamonds=?, icon_type=?, color1=?, color2=?, cube=?, ship=?, ball=?, ufo=?, wave=?, robot=?, spider=?, explosion=?, special=?, glow=?, last_played=? where id=?", params["userName"], params["stars"].to_i32, params["demons"].to_i32, params["coins"].to_i32, params["userCoins"].to_i32, params["diamonds"].to_i32, params["iconType"].to_i32, params["color1"].to_i32, params["color2"].to_i32, params["accIcon"].to_i32, params["accShip"].to_i32, params["accBall"].to_i32, params["accBird"].to_i32, params["accDart"].to_i32, params["accRobot"].to_i32, params["accSpider"].to_i32, params["accExplosion"].to_i32, params["special"].to_i32, params["accGlow"].to_i32, Time.utc.to_s("%Y-%m-%d %H:%M:%S"), user_id)

View File

@ -6,16 +6,25 @@ include CrystalGauntlet
module CrystalGauntlet::Accounts
extend self
def get_ext_id_from_params(params : URI::Params) : String
def get_account_id_from_params(params : URI::Params) : Int32 | Nil
if params["accountID"]? && params["accountID"]? != "0"
# todo: validate password
params["accountID"].to_i32
else
nil
end
end
def get_ext_id_from_params(params : URI::Params) : String | Nil
return "1"
if params.has_key?("udid") && params["udid"] != ""
# todo: numeric id check
params["udid"]
elsif params.has_key?("account_id") && params["account_id"] != "" && params["account_id"] != "0"
elsif params.has_key?("accountID") && params["accountID"] != "" && params["accountID"] != "0"
# todo: validate password
params["account_id"]
params["accountID"]
else
"-1"
nil
end
end
@ -29,7 +38,7 @@ module CrystalGauntlet::Accounts
end
end
def verify_gjp(account_id : String, gjp : String) : Bool
def verify_gjp(account_id : Int32, gjp : String) : Bool
hash = DATABASE.scalar("select password from accounts where id = ?", account_id).as(String)
bcrypt = Crypto::Bcrypt::Password.new(hash)
bcrypt.verify(GJP.decrypt(gjp))