knock some long-standing issues off of the todos

This commit is contained in:
Jill 2023-01-07 11:46:18 +03:00
parent 00a24ecb8b
commit 63311de7a4
11 changed files with 45 additions and 23 deletions

View File

@ -25,6 +25,11 @@ hostname = "localhost:8080"
# spots
date = "relative"
[comments]
# comments with a like count <= this number
# will be marked as spam
spam_thres = -3
[accounts]
# allow new accounts to be created
allow_registration = true

View File

@ -16,9 +16,9 @@ CREATE TABLE accounts (
-- 0: disabled, 1: enabled
friend_requests_enabled INTEGER NOT NULL DEFAULT 1, -- frs enabled
youtube_url TEXT,
twitter_url TEXT,
twitch_url TEXT,
youtube_url VARCHAR(30),
twitter_url VARCHAR(20),
twitch_url VARCHAR(20),
created_at TEXT NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'now'))
);

View File

@ -25,6 +25,9 @@ CrystalGauntlet.endpoints["/accounts/loginGJAccount.php"] = ->(context : HTTP::S
if bcrypt.verify(password)
user_id = Accounts.get_user_id(account_id)
# update username casing
DATABASE.exec("update accounts set username = ? where id = ?", username, account_id)
DATABASE.exec("update users set username = ? where id = ?", username, user_id)
"#{account_id},#{user_id}"
else
return "-11"

View File

@ -11,8 +11,7 @@ CrystalGauntlet.endpoints["/updateGJAccSettings20.php"] = ->(context : HTTP::Ser
return "-1"
end
# todo: figure out max lengths and cap
DATABASE.exec("update accounts set messages_enabled=?, friend_requests_enabled=?, comments_enabled=?, youtube_url=?, twitter_url=?, twitch_url=? where id=?", params["mS"].to_i32, params["frS"].to_i32, params["cS"].to_i32, params["yt"], params["twitter"], params["twitch"], account_id)
DATABASE.exec("update accounts set messages_enabled=?, friend_requests_enabled=?, comments_enabled=?, youtube_url=?, twitter_url=?, twitch_url=? where id=?", params["mS"].to_i.clamp(0..2), params["frS"].to_i.clamp(0..1), params["cS"].to_i.clamp(0..2), params["yt"][..30-1], params["twitter"][..20-1], params["twitch"][..20-1], account_id)
"1"
}

View File

@ -64,7 +64,7 @@ CrystalGauntlet.endpoints["/getGJCommentHistory.php"] = ->(context : HTTP::Serve
4 => likes,
5 => 0, # dislikes; unused
6 => id,
7 => likes < -3, # todo: config?
7 => likes <= (config_get("comments.spam_thres").as?(Int64) || -3),
9 => Time.parse(created_at, Format::TIME_FORMAT, Time::Location::UTC),
}),
Format.fmt_comment({

View File

@ -44,7 +44,7 @@ CrystalGauntlet.endpoints["/getGJComments21.php"] = ->(context : HTTP::Server::C
4 => likes,
5 => 0,
6 => id,
7 => likes < -3,
7 => likes <= (config_get("comments.spam_thres").as?(Int64) || -3),
8 => account_id,
9 => Time.parse(created_at, Format::TIME_FORMAT, Time::Location::UTC),
10 => percent || 0,

View File

@ -29,7 +29,7 @@ CrystalGauntlet.endpoints["/getGJAccountComments20.php"] = ->(context : HTTP::Se
4 => likes,
5 => 0, # dislikes; unused
6 => id,
7 => likes < -3, # todo: config?
7 => likes <= (config_get("comments.spam_thres").as?(Int64) || -3),
9 => Time.parse(created_at, Format::TIME_FORMAT, Time::Location::UTC),
})
end

View File

@ -34,14 +34,10 @@ CrystalGauntlet.endpoints["/uploadGJLevel21.php"] = ->(context : HTTP::Server::C
original = nil
end
# todo: cap level length
# todo: cap coins
# todo: cap ldm to bool
# todo: cap twoplayer to bool
# todo: cap unlisted to bool
# todo: cap requested stars
if config_get("levels.parsing.enabled").as?(Bool)
# todo: parse ldm
# todo: parse level length
LOG.debug { "parsing objects" }
level_objects = Level.decode(params["levelString"])
@ -99,6 +95,8 @@ CrystalGauntlet.endpoints["/uploadGJLevel21.php"] = ->(context : HTTP::Server::C
two_player = params["twoPlayer"].to_i == 1
end
level_length = params["levelLength"].to_i.clamp(0..4)
if coins < 0 || coins > 3
return "-1"
end
@ -112,10 +110,13 @@ CrystalGauntlet.endpoints["/uploadGJLevel21.php"] = ->(context : HTTP::Server::C
return "-1"
end
# todo: verify level length
# todo: check seed2?
requested_stars = params["requestedStars"].to_i.clamp(0..10)
if requested_stars == 0
requested_stars = nil
end
if DATABASE.scalar("select count(*) from levels where id = ?", params["levelID"]).as(Int64) > 0
# update existing level
level_user_id = DATABASE.query_one("select user_id from levels where id = ?", params["levelID"].to_i, as: {Int32})
@ -124,7 +125,7 @@ CrystalGauntlet.endpoints["/uploadGJLevel21.php"] = ->(context : HTTP::Server::C
return "-1"
end
DATABASE.exec("update levels set description = ?, password = ?, requested_stars = ?, version = ?, extra_data = ?, level_info = ?, editor_time = ?, editor_time_copies = ?, song_id = ?, length = ?, objects = ?, coins = ?, has_ldm = ?, two_player = ?, modified_at = ? where id = ?", description[..140-1], params["password"] == "0" ? nil : params["password"].to_i, params["requestedStars"].to_i, params["levelVersion"].to_i, Clean.clean_special(extraString), Clean.clean_b64(params["levelInfo"]), params["wt"].to_i, params["wt2"].to_i, song_id.to_i, params["levelLength"].to_i, objects, coins, params["ldm"].to_i, two_player, Time.utc.to_s(Format::TIME_FORMAT), params["levelID"].to_i)
DATABASE.exec("update levels set description = ?, password = ?, requested_stars = ?, version = ?, extra_data = ?, level_info = ?, editor_time = ?, editor_time_copies = ?, song_id = ?, length = ?, objects = ?, coins = ?, has_ldm = ?, two_player = ?, modified_at = ? where id = ?", description[..140-1], params["password"] == "0" ? nil : params["password"].to_i, requested_stars, params["levelVersion"].to_i, Clean.clean_special(extraString), Clean.clean_b64(params["levelInfo"]), params["wt"].to_i, params["wt2"].to_i, song_id.to_i, level_length, objects, coins, params["ldm"].to_i == 1, two_player, Time.utc.to_s(Format::TIME_FORMAT), params["levelID"].to_i)
File.write(DATA_FOLDER / "levels" / "#{params["levelID"]}.lvl", Base64.decode(params["levelString"]))
@ -133,7 +134,7 @@ CrystalGauntlet.endpoints["/uploadGJLevel21.php"] = ->(context : HTTP::Server::C
# create new level
next_id = IDs.get_next_id("levels")
DATABASE.exec("insert into levels (id, name, user_id, description, original, game_version, binary_version, password, requested_stars, unlisted, version, extra_data, level_info, editor_time, editor_time_copies, song_id, length, objects, coins, has_ldm, two_player) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", next_id, Clean.clean_special(params["levelName"])[..20-1], user_id, description[..140-1], params["original"].to_i32, params["gameVersion"].to_i32, params["binaryVersion"].to_i32, params["password"] == "0" ? nil : params["password"].to_i32, params["requestedStars"].to_i32, params["unlisted"].to_i32, params["levelVersion"].to_i32, Clean.clean_special(extraString), Clean.clean_b64(params["levelInfo"]), params["wt"].to_i32, params["wt2"].to_i32, song_id.to_i32, params["levelLength"].to_i32, objects, coins, params["ldm"].to_i32, two_player)
DATABASE.exec("insert into levels (id, name, user_id, description, original, game_version, binary_version, password, requested_stars, unlisted, version, extra_data, level_info, editor_time, editor_time_copies, song_id, length, objects, coins, has_ldm, two_player) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", next_id, Clean.clean_special(params["levelName"])[..20-1], user_id, description[..140-1], params["original"].to_i, params["gameVersion"].to_i, params["binaryVersion"].to_i, params["password"] == "0" ? nil : params["password"].to_i, requested_stars, params["unlisted"].to_i == 1, params["levelVersion"].to_i, Clean.clean_special(extraString), Clean.clean_b64(params["levelInfo"]), params["wt"].to_i, params["wt2"].to_i, song_id.to_i, level_length, objects, coins, params["ldm"].to_i == 1, two_player)
File.write(DATA_FOLDER / "levels" / "#{next_id.to_s}.lvl", Base64.decode(params["levelString"]))

View File

@ -60,6 +60,7 @@ CrystalGauntlet.endpoints["/getGJRewards.php"] = ->(context : HTTP::Server::Cont
large_total, large_next = get_chest(account_id, true)
LOG.debug { "small: #{small_next}s, large: #{large_next}s" }
# todo: figure out why opening one chest resets the other visually
case params["rewardType"]
when "1"

View File

@ -11,13 +11,22 @@ CrystalGauntlet.endpoints["/updateGJUserScore22.php"] = ->(context : HTTP::Serve
return "-1"
end
# 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(Format::TIME_FORMAT), user_id)
old_username = DATABASE.query_one("select username from users where id = ?", user_id, as: {String})
new_username = old_username
# only change username if casing is the same
if params["userName"].compare(old_username, case_insensitive: true) == 0
new_username = params["userName"]
end
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=?", new_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.clamp(0..6), 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(Format::TIME_FORMAT), user_id)
if old_username != new_username && account_id
DATABASE.exec("update accounts set username = ? where id = ?", new_username, account_id)
end
user_id.to_s
}

View File

@ -148,6 +148,10 @@ module CrystalGauntlet::Songs
author_id = song_author_id
metadata = SongMetadata.new(song_name, song_author_name || "", url.not_nil!, song_source, song_author_url || "", song_duration, song_size)
else
if url == nil
# prevent disabling unoccupied IDs
return nil
end
begin
metadata = fetch_song_metadata(url.not_nil!)
rescue err