From 95800ffe216a83bc0eba994ecc53ed22860fe90e Mon Sep 17 00:00:00 2001 From: ilotterytea Date: Mon, 8 Dec 2025 22:17:05 +0500 Subject: upd: include paths --- 404.php | 8 +- account/change_emoteset.php | 6 +- account/delete.php | 4 +- account/index.php | 12 +- account/login/index.php | 10 +- account/login/twitch.php | 6 +- account/register.php | 10 +- account/security.php | 8 +- badges.php | 6 +- captcha.php | 8 +- emotes/delete.php | 6 +- emotes/index.php | 12 +- emotes/rate.php | 8 +- emotes/setmanip.php | 8 +- emotes/upload.php | 14 +- emotesets.php | 12 +- inbox.php | 8 +- index.php | 6 +- lib/accounts.php | 101 ++++++++++++++ lib/alert.php | 40 ++++++ lib/captcha.php | 151 ++++++++++++++++++++ lib/config.sample.php | 74 ++++++++++ lib/emote.php | 332 ++++++++++++++++++++++++++++++++++++++++++++ lib/images.php | 78 +++++++++++ lib/partials.php | 179 ++++++++++++++++++++++++ lib/user.php | 102 ++++++++++++++ lib/utils.php | 68 +++++++++ lib/version.php | 11 ++ report/index.php | 10 +- report/list.php | 10 +- report/send.php | 8 +- rules.php | 6 +- software.php | 4 +- src/accounts.php | 101 -------------- src/alert.php | 40 ------ src/captcha.php | 151 -------------------- src/config.sample.php | 74 ---------- src/emote.php | 332 -------------------------------------------- src/images.php | 78 ----------- src/partials.php | 179 ------------------------ src/user.php | 102 -------------- src/utils.php | 68 --------- src/version.php | 11 -- system/emotes/index.php | 10 +- system/emotes/verdict.php | 8 +- system/index.php | 8 +- users.php | 14 +- 47 files changed, 1251 insertions(+), 1251 deletions(-) create mode 100644 lib/accounts.php create mode 100644 lib/alert.php create mode 100644 lib/captcha.php create mode 100644 lib/config.sample.php create mode 100644 lib/emote.php create mode 100644 lib/images.php create mode 100644 lib/partials.php create mode 100644 lib/user.php create mode 100644 lib/utils.php create mode 100644 lib/version.php delete mode 100644 src/accounts.php delete mode 100644 src/alert.php delete mode 100644 src/captcha.php delete mode 100644 src/config.sample.php delete mode 100644 src/emote.php delete mode 100644 src/images.php delete mode 100644 src/partials.php delete mode 100644 src/user.php delete mode 100644 src/utils.php delete mode 100644 src/version.php diff --git a/404.php b/404.php index cd7e12e..8a74291 100644 --- a/404.php +++ b/404.php @@ -1,8 +1,8 @@ diff --git a/emotesets.php b/emotesets.php index 635f4c4..9d2fa07 100644 --- a/emotesets.php +++ b/emotesets.php @@ -1,10 +1,10 @@ 401, + "message" => "Unauthorized", + "data" => null + ]); + } else { + header("Location: /account"); + } + } + + return false; + } + + include_once "config.php"; + + $db = new PDO(DB_URL, DB_USER, DB_PASS); + + $key = $_SERVER["HTTP_AUTHORIZATION"] ?? $_COOKIE["secret_key"]; + + $stmt = $db->prepare("SELECT id, username FROM users WHERE secret_key = ?"); + $stmt->execute([$key]); + + if ($row = $stmt->fetch()) { + $_SESSION["user_id"] = $row["id"]; + $_SESSION["user_name"] = $row["username"]; + + $stmt = $db->prepare("UPDATE users SET last_active_at = UTC_TIMESTAMP WHERE id = ?"); + $stmt->execute([$row["id"]]); + + // fetching role + $stmt = $db->prepare("SELECT * FROM roles r + INNER JOIN role_assigns ra ON ra.user_id = ? + WHERE r.id = ra.role_id + "); + $stmt->execute([$row["id"]]); + + $_SESSION["user_role"] = null; + + if ($role_row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $_SESSION["user_role"] = $role_row; + } + + $stmt = $db->prepare("SELECT es.*, aes.is_default FROM emote_sets es + INNER JOIN acquired_emote_sets aes ON aes.emote_set_id = es.id + WHERE aes.user_id = ? + ORDER BY + CASE WHEN es.id = ? THEN 0 ELSE 1 END, + es.id + "); + $stmt->execute([$row["id"], $_SESSION["user_active_emote_set_id"] ?? ""]); + + $emote_sets = $stmt->fetchAll(PDO::FETCH_ASSOC); + + if (!isset($_SESSION["user_active_emote_set_id"])) { + foreach ($emote_sets as $es) { + if ($es["is_default"]) { + $_SESSION["user_active_emote_set"] = $es; + $_SESSION["user_active_emote_set_id"] = $es["id"]; + } + } + } + + $_SESSION["user_emote_sets"] = $emote_sets; + } else { + session_regenerate_id(); + session_unset(); + setcookie("secret_key", "", time() - 1000); + + if ($required) { + if (isset($_SERVER["HTTP_ACCEPT"]) && $_SERVER["HTTP_ACCEPT"] == "application/json") { + http_response_code(401); + echo json_encode([ + "status_code" => 401, + "message" => "Unauthorized", + "data" => null + ]); + } else { + header("Location: /account"); + } + } + } + + $db = null; + $stmt = null; + return isset($_SESSION["user_name"]); +} \ No newline at end of file diff --git a/lib/alert.php b/lib/alert.php new file mode 100644 index 0000000..823a97a --- /dev/null +++ b/lib/alert.php @@ -0,0 +1,40 @@ + $status, + "message" => $error, + "data" => null + ]); + } else { + header("Location: $path" . (str_contains($path, "?") ? "&" : "?") . "error_status=$status&error_reason=$error"); + } +} + +function display_alert() +{ + if (!isset($_GET["error_status"], $_GET["error_reason"])) { + return; + } + + $status = $_GET["error_status"]; + $reason = str_safe($_GET["error_reason"], 100); + $ok = substr($status, 0, 1) == '2'; + + echo '' ?> +
+ +

+
+ + + + + "COAL", + "1" => "GEM", +]); // Rating names. The schema is [ "id/rating_point" => "name" ]. +define("RATING_EMOTE_MIN_VOTES", 10); // Minimal amount of votes to display emote rating. + +// UPLOADS +define("ANONYMOUS_UPLOAD", false); // Allow anonymous upload for emotes. +define("ANONYMOUS_DEFAULT_NAME", "Anonymous"); // Default uploader name for anonymous emotes. It's also used when original uploader has been deleted. + +// EMOTES +define("EMOTE_UPLOAD", true); // Enable emote upload. +define("EMOTE_NAME_MAX_LENGTH", 100); // Max length for emote name. +define("EMOTE_COMMENT_MAX_LENGTH", 100); // Max length for emote comment. +define("EMOTE_VISIBILITY_DEFAULT", 2); // Default visibility for emotes. 0 - unlisted, 1 - public, 2 - pending approval (same as unlisted). +define("EMOTE_MAX_SIZE", [128, 128]); // Max size of emote. +define("EMOTE_NAME_REGEX", "/^[A-Za-z0-9_]+$/"); // RegEx filter for emote names. +define("EMOTE_STORE_ORIGINAL", true); // Store original uploads of emotes. + +// TAGS +define("TAGS_ENABLE", true); // Allow emote tagging. +define("TAGS_CODE_REGEX", "/^[A-Za-z0-9_]+$/"); +define("TAGS_MAX_COUNT", 10); // Maximum tags per emote. Set -1 for unlimited amount. + +// EMOTESETS +define("EMOTESET_PUBLIC_LIST", true); // Show emotesets public. + +// MODERATION +define("MOD_SYSTEM_DASHBOARD", true); // Enable system dashboard for moderators (/system). +define("MOD_EMOTES_APPROVE", true); // Enable manual emote approval (/system/emotes). + +// REPORTS +define("REPORTS_ENABLE", true); // Enable emote, user reports. + +// ACCOUNTS +define("ACCOUNT_REGISTRATION_ENABLE", true); // Enable account registration. +define("ACCOUNT_COOKIE_MAX_LIFETIME", 86400 * 30); // Remember user for a month. +define("ACCOUNT_USERNAME_REGEX", "/^[A-Za-z0-9_]+$/"); // RegEx filter for account usernames. +define("ACCOUNT_USERNAME_LENGTH", [2, 20]); // [Min, Max] length for account usernames. +define("ACCOUNT_PASSWORD_MIN_LENGTH", 10); // Minimal length for passwords. +define("ACCOUNT_SECRET_KEY_LENGTH", 32); // The length for secret keys. +define("ACCOUNT_PFP_MAX_SIZE", [128, 128]); // Max dimensions for account pictures. +define("ACCOUNT_BANNER_MAX_SIZE", [1920, 1080]); // Max dimensions for account banners. +define("ACCOUNT_BADGE_MAX_SIZE", [72, 72]); // Max dimensions for account badges. +define("ACCOUNT_PUBLIC_LIST", true); // The public list of accounts. +define("ACCOUNT_LOG_ACTIONS", true); // Log user's actions (emote addition, etc.). + +// TWITCH +define("TWITCH_REGISTRATION_ENABLE", false); // Enable account registration via Twitch. +define("TWITCH_CLIENT_ID", "AAAAAAAAA"); // Client ID of your Twitch application. +define("TWITCH_SECRET_KEY", "BBBBBBBBB"); // Secret key of your Twitch application. +define("TWITCH_REDIRECT_URI", ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https" : "http") . "://$_SERVER[HTTP_HOST]/account/login/twitch.php"); // Redirect URI of your Twitch application. + +// CAPTCHA +define("CAPTCHA_ENABLE", true); // Enable built-in captcha. +define("CAPTCHA_SIZE", [580, 220]); // Captcha size. +define("CAPTCHA_FORCE_USERS", false); // Force authorized users to solve captcha. + +// FOR DEVELOPERS +define("CLIENT_REQUIRES_JSON", isset($_SERVER["HTTP_ACCEPT"]) && $_SERVER["HTTP_ACCEPT"] == "application/json"); \ No newline at end of file diff --git a/lib/emote.php b/lib/emote.php new file mode 100644 index 0000000..ce39c09 --- /dev/null +++ b/lib/emote.php @@ -0,0 +1,332 @@ +id = $arr["id"]; + $e->code = $arr["code"]; + $e->ext = $arr["ext"] ?? "webp"; + $e->uploaded_by = $arr["uploaded_by"]; + $e->created_at = strtotime($arr["created_at"] ?? 0); + $e->is_in_user_set = $arr["is_in_user_set"] ?? false; + $e->visibility = $arr["visibility"]; + $e->source = $arr["source"] ?? null; + $e->tags = $arr["tags"] ?? []; + + if (isset($arr["total_rating"], $arr["average_rating"])) { + $e->rating = [ + "total" => $arr["total_rating"], + "average" => $arr["average_rating"] + ]; + } else { + $e->rating = $arr["rating"] ?? null; + } + + return $e; + } + + public static function from_array_with_user(array $arr, PDO &$db): Emote + { + if ($arr["uploaded_by"]) { + $arr["uploaded_by"] = User::get_user_by_id($db, $arr["uploaded_by"]); + } + + return Emote::from_array($arr); + } + + function get_id() + { + return $this->id; + } + + function get_code() + { + return $this->code; + } + + function get_ext() + { + return $this->ext; + } + + function get_created_at() + { + return $this->created_at; + } + + function get_uploaded_by() + { + return $this->uploaded_by; + } + + function is_added_by_user() + { + return $this->is_in_user_set; + } + + function get_rating() + { + return $this->rating; + } + + function get_visibility() + { + return $this->visibility; + } + + function get_source() + { + return $this->source; + } + + function get_tags(): array + { + return $this->tags; + } +} + +class Emoteset +{ + public string $id; + public string $name; + public User|null $owner; + public array $emotes; + + public bool $is_default; + + public static function from_array(array $arr): Emoteset + { + $s = new Emoteset(); + + $s->id = $arr["id"]; + $s->name = $arr["name"]; + $s->owner = $arr["owner_id"]; + $s->emotes = $arr["emotes"] ?? []; + $s->is_default = $arr["is_default"] ?? false; + + return $s; + } + + public static function from_array_extended(array $arr, string $user_id, PDO &$db): Emoteset + { + if ($arr["owner_id"]) { + $arr["owner_id"] = User::get_user_by_id($db, $arr["owner_id"]); + } + + $arr["emotes"] = fetch_all_emotes_from_emoteset($db, $arr["id"], $user_id); + + return Emoteset::from_array($arr); + } + + public static function get_all_user_emotesets(PDO &$db, string $user_id): array + { + $stmt = $db->prepare("SELECT es.*, aes.is_default FROM emote_sets es + INNER JOIN acquired_emote_sets aes ON aes.emote_set_id = es.id + WHERE aes.user_id = ? + "); + $stmt->execute([$user_id]); + + $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); + $emote_sets = []; + + foreach ($rows as $row) { + array_push($emote_sets, Emoteset::from_array_extended($row, $user_id, $db)); + } + + return $emote_sets; + } +} + +function fetch_all_emotes_from_emoteset(PDO &$db, string $emote_set_id, string $user_id, int|null $limit = null): array +{ + // fetching emotes + $sql = "SELECT + e.id, e.created_at, e.visibility, + CASE + WHEN esc.code IS NOT NULL THEN esc.code + ELSE e.code + END AS code, + CASE + WHEN esc.code IS NOT NULL THEN e.code + ELSE NULL + END AS original_code, + CASE WHEN up.private_profile = FALSE OR up.id = ? THEN e.uploaded_by ELSE NULL END AS uploaded_by + FROM emotes e + LEFT JOIN user_preferences up ON up.id = e.uploaded_by + INNER JOIN emote_set_contents AS esc + ON esc.emote_set_id = ? + WHERE esc.emote_id = e.id"; + + if ($limit) { + $sql .= " LIMIT $limit"; + } + + $stmt = $db->prepare($sql); + $stmt->execute([$user_id, $emote_set_id]); + + $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); + $emotes = []; + + // fetching uploaders + foreach ($rows as $row) { + if ($row["uploaded_by"]) { + $row["uploaded_by"] = User::get_user_by_id($db, $row["uploaded_by"]); + } + + array_push($emotes, Emote::from_array($row)); + } + + return $emotes; +} + +function html_random_emote(PDO &$db) +{ + $stmt = $db->prepare("SELECT id, code FROM emotes WHERE visibility = 1 ORDER BY RAND() LIMIT 1"); + $stmt->execute(); + + if ($row = $stmt->fetch()) { + echo '' + ?> +
+ + +
+ prepare("SELECT e.id, e.code FROM emotes e + INNER JOIN emote_sets es ON es.is_featured = TRUE + INNER JOIN emote_set_contents esc ON es.id = esc.emote_set_id + WHERE e.visibility = 1 AND e.id = esc.emote_id ORDER BY esc.added_at DESC LIMIT 1"); + $stmt->execute(); + + if ($row = $stmt->fetch()) { + echo '' + ?> + + id}'>"; + + if ($e->is_added_by_user()) { + echo ''; + } + + // icon + echo '
'; + $scale = $emote_wall ? "3" : ((string) $scale); + echo "{$e->code}"; + echo '
'; + + // info + echo '
'; + + echo "

{$e->code}

"; + if ($e->get_uploaded_by()) { + echo "

{$e->uploaded_by->username}

"; + } + + echo '
'; + } +} + +function html_display_emoteset(array $emotesets) +{ + foreach ($emotesets as $es) { + echo ""; + + echo '
'; + echo "

$es->name

"; + echo '
'; + + echo '
'; + + foreach ($es->emotes as $e) { + echo "{$e->code}"; + } + + echo '
'; + + } +} + +function html_emotelist_mode() +{ + echo '' ?> + + + + + +
+ +
+
" method="GET"> + ">
+ + + + + +
+
+
+ 1) { + echo '' ?> + + id = $arr["{$prefix}badge_id"]; + + return $b; + } +} + +class Role +{ + public string $name; + public Badge|null $badge; + + public static function from_array(array $arr): Role|null + { + if (!isset($arr["role_name"])) { + return null; + } + + $r = new Role(); + + $r->name = $arr["role_name"]; + $r->badge = Badge::from_array($arr, "role"); + + return $r; + } +} + +class User +{ + public string $id; + public string $username; + public int $joined_at; + public int $last_active_at; + + public Badge|null $custom_badge; + + public Role|null $role; + + public bool $private_profile; + + public static function from_array(array $arr): User + { + $u = new User(); + + $u->id = $arr["id"]; + $u->username = $arr["username"]; + $u->joined_at = strtotime($arr["joined_at"] ?? "0"); + $u->last_active_at = strtotime($arr["last_active_at"] ?? "0"); + + $u->private_profile = $row["private_profile"] ?? false; + + $u->custom_badge = Badge::from_array($arr, "custom"); + + $u->role = Role::from_array($arr); + + return $u; + } + + public static function get_user_by_id(PDO &$db, string $user_id): User|null + { + $stmt = $db->prepare("SELECT + u.id, + u.username, + u.joined_at, + u.last_active_at, + + up.private_profile, + r.name AS role_name, + r.badge_id AS role_badge_id, + ub.badge_id AS custom_badge_id + FROM users u + INNER JOIN user_preferences up ON up.id = u.id + LEFT JOIN role_assigns ra ON ra.user_id = u.id + LEFT JOIN roles r ON r.id = ra.role_id + LEFT JOIN user_badges ub ON ub.user_id = u.id + WHERE u.id = ? + "); + $stmt->execute([$user_id]); + + $u = null; + + if ($uploader_row = $stmt->fetch()) { + $u = User::from_array($uploader_row); + } + + return $u; + } +} \ No newline at end of file diff --git a/lib/utils.php b/lib/utils.php new file mode 100644 index 0000000..87d96c6 --- /dev/null +++ b/lib/utils.php @@ -0,0 +1,68 @@ + 1 ? "s" : ""); + } else if ($days == 0 && $hours == 0) { + return "$minutes minute" . ($minutes > 1 ? "s" : ""); + } else if ($days == 0) { + return "$hours hour" . ($hours > 1 ? "s" : ""); + } else { + return "$days day" . ($days > 1 ? "s" : ""); + } +} + +function clamp(int $current, int $min, int $max): int +{ + return max($min, min($max, $current)); +} + +function in_range(float $value, float $min, float $max): bool +{ + return $min <= $value && $value <= $max; +} \ No newline at end of file diff --git a/lib/version.php b/lib/version.php new file mode 100644 index 0000000..d666783 --- /dev/null +++ b/lib/version.php @@ -0,0 +1,11 @@ + diff --git a/src/accounts.php b/src/accounts.php deleted file mode 100644 index 51cb3f6..0000000 --- a/src/accounts.php +++ /dev/null @@ -1,101 +0,0 @@ - 401, - "message" => "Unauthorized", - "data" => null - ]); - } else { - header("Location: /account"); - } - } - - return false; - } - - include_once "config.php"; - - $db = new PDO(DB_URL, DB_USER, DB_PASS); - - $key = $_SERVER["HTTP_AUTHORIZATION"] ?? $_COOKIE["secret_key"]; - - $stmt = $db->prepare("SELECT id, username FROM users WHERE secret_key = ?"); - $stmt->execute([$key]); - - if ($row = $stmt->fetch()) { - $_SESSION["user_id"] = $row["id"]; - $_SESSION["user_name"] = $row["username"]; - - $stmt = $db->prepare("UPDATE users SET last_active_at = UTC_TIMESTAMP WHERE id = ?"); - $stmt->execute([$row["id"]]); - - // fetching role - $stmt = $db->prepare("SELECT * FROM roles r - INNER JOIN role_assigns ra ON ra.user_id = ? - WHERE r.id = ra.role_id - "); - $stmt->execute([$row["id"]]); - - $_SESSION["user_role"] = null; - - if ($role_row = $stmt->fetch(PDO::FETCH_ASSOC)) { - $_SESSION["user_role"] = $role_row; - } - - $stmt = $db->prepare("SELECT es.*, aes.is_default FROM emote_sets es - INNER JOIN acquired_emote_sets aes ON aes.emote_set_id = es.id - WHERE aes.user_id = ? - ORDER BY - CASE WHEN es.id = ? THEN 0 ELSE 1 END, - es.id - "); - $stmt->execute([$row["id"], $_SESSION["user_active_emote_set_id"] ?? ""]); - - $emote_sets = $stmt->fetchAll(PDO::FETCH_ASSOC); - - if (!isset($_SESSION["user_active_emote_set_id"])) { - foreach ($emote_sets as $es) { - if ($es["is_default"]) { - $_SESSION["user_active_emote_set"] = $es; - $_SESSION["user_active_emote_set_id"] = $es["id"]; - } - } - } - - $_SESSION["user_emote_sets"] = $emote_sets; - } else { - session_regenerate_id(); - session_unset(); - setcookie("secret_key", "", time() - 1000); - - if ($required) { - if (isset($_SERVER["HTTP_ACCEPT"]) && $_SERVER["HTTP_ACCEPT"] == "application/json") { - http_response_code(401); - echo json_encode([ - "status_code" => 401, - "message" => "Unauthorized", - "data" => null - ]); - } else { - header("Location: /account"); - } - } - } - - $db = null; - $stmt = null; - return isset($_SESSION["user_name"]); -} \ No newline at end of file diff --git a/src/alert.php b/src/alert.php deleted file mode 100644 index 823a97a..0000000 --- a/src/alert.php +++ /dev/null @@ -1,40 +0,0 @@ - $status, - "message" => $error, - "data" => null - ]); - } else { - header("Location: $path" . (str_contains($path, "?") ? "&" : "?") . "error_status=$status&error_reason=$error"); - } -} - -function display_alert() -{ - if (!isset($_GET["error_status"], $_GET["error_reason"])) { - return; - } - - $status = $_GET["error_status"]; - $reason = str_safe($_GET["error_reason"], 100); - $ok = substr($status, 0, 1) == '2'; - - echo '' ?> -
- -

-
- - - - - "COAL", - "1" => "GEM", -]); // Rating names. The schema is [ "id/rating_point" => "name" ]. -define("RATING_EMOTE_MIN_VOTES", 10); // Minimal amount of votes to display emote rating. - -// UPLOADS -define("ANONYMOUS_UPLOAD", false); // Allow anonymous upload for emotes. -define("ANONYMOUS_DEFAULT_NAME", "Anonymous"); // Default uploader name for anonymous emotes. It's also used when original uploader has been deleted. - -// EMOTES -define("EMOTE_UPLOAD", true); // Enable emote upload. -define("EMOTE_NAME_MAX_LENGTH", 100); // Max length for emote name. -define("EMOTE_COMMENT_MAX_LENGTH", 100); // Max length for emote comment. -define("EMOTE_VISIBILITY_DEFAULT", 2); // Default visibility for emotes. 0 - unlisted, 1 - public, 2 - pending approval (same as unlisted). -define("EMOTE_MAX_SIZE", [128, 128]); // Max size of emote. -define("EMOTE_NAME_REGEX", "/^[A-Za-z0-9_]+$/"); // RegEx filter for emote names. -define("EMOTE_STORE_ORIGINAL", true); // Store original uploads of emotes. - -// TAGS -define("TAGS_ENABLE", true); // Allow emote tagging. -define("TAGS_CODE_REGEX", "/^[A-Za-z0-9_]+$/"); -define("TAGS_MAX_COUNT", 10); // Maximum tags per emote. Set -1 for unlimited amount. - -// EMOTESETS -define("EMOTESET_PUBLIC_LIST", true); // Show emotesets public. - -// MODERATION -define("MOD_SYSTEM_DASHBOARD", true); // Enable system dashboard for moderators (/system). -define("MOD_EMOTES_APPROVE", true); // Enable manual emote approval (/system/emotes). - -// REPORTS -define("REPORTS_ENABLE", true); // Enable emote, user reports. - -// ACCOUNTS -define("ACCOUNT_REGISTRATION_ENABLE", true); // Enable account registration. -define("ACCOUNT_COOKIE_MAX_LIFETIME", 86400 * 30); // Remember user for a month. -define("ACCOUNT_USERNAME_REGEX", "/^[A-Za-z0-9_]+$/"); // RegEx filter for account usernames. -define("ACCOUNT_USERNAME_LENGTH", [2, 20]); // [Min, Max] length for account usernames. -define("ACCOUNT_PASSWORD_MIN_LENGTH", 10); // Minimal length for passwords. -define("ACCOUNT_SECRET_KEY_LENGTH", 32); // The length for secret keys. -define("ACCOUNT_PFP_MAX_SIZE", [128, 128]); // Max dimensions for account pictures. -define("ACCOUNT_BANNER_MAX_SIZE", [1920, 1080]); // Max dimensions for account banners. -define("ACCOUNT_BADGE_MAX_SIZE", [72, 72]); // Max dimensions for account badges. -define("ACCOUNT_PUBLIC_LIST", true); // The public list of accounts. -define("ACCOUNT_LOG_ACTIONS", true); // Log user's actions (emote addition, etc.). - -// TWITCH -define("TWITCH_REGISTRATION_ENABLE", false); // Enable account registration via Twitch. -define("TWITCH_CLIENT_ID", "AAAAAAAAA"); // Client ID of your Twitch application. -define("TWITCH_SECRET_KEY", "BBBBBBBBB"); // Secret key of your Twitch application. -define("TWITCH_REDIRECT_URI", ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https" : "http") . "://$_SERVER[HTTP_HOST]/account/login/twitch.php"); // Redirect URI of your Twitch application. - -// CAPTCHA -define("CAPTCHA_ENABLE", true); // Enable built-in captcha. -define("CAPTCHA_SIZE", [580, 220]); // Captcha size. -define("CAPTCHA_FORCE_USERS", false); // Force authorized users to solve captcha. - -// FOR DEVELOPERS -define("CLIENT_REQUIRES_JSON", isset($_SERVER["HTTP_ACCEPT"]) && $_SERVER["HTTP_ACCEPT"] == "application/json"); \ No newline at end of file diff --git a/src/emote.php b/src/emote.php deleted file mode 100644 index ce39c09..0000000 --- a/src/emote.php +++ /dev/null @@ -1,332 +0,0 @@ -id = $arr["id"]; - $e->code = $arr["code"]; - $e->ext = $arr["ext"] ?? "webp"; - $e->uploaded_by = $arr["uploaded_by"]; - $e->created_at = strtotime($arr["created_at"] ?? 0); - $e->is_in_user_set = $arr["is_in_user_set"] ?? false; - $e->visibility = $arr["visibility"]; - $e->source = $arr["source"] ?? null; - $e->tags = $arr["tags"] ?? []; - - if (isset($arr["total_rating"], $arr["average_rating"])) { - $e->rating = [ - "total" => $arr["total_rating"], - "average" => $arr["average_rating"] - ]; - } else { - $e->rating = $arr["rating"] ?? null; - } - - return $e; - } - - public static function from_array_with_user(array $arr, PDO &$db): Emote - { - if ($arr["uploaded_by"]) { - $arr["uploaded_by"] = User::get_user_by_id($db, $arr["uploaded_by"]); - } - - return Emote::from_array($arr); - } - - function get_id() - { - return $this->id; - } - - function get_code() - { - return $this->code; - } - - function get_ext() - { - return $this->ext; - } - - function get_created_at() - { - return $this->created_at; - } - - function get_uploaded_by() - { - return $this->uploaded_by; - } - - function is_added_by_user() - { - return $this->is_in_user_set; - } - - function get_rating() - { - return $this->rating; - } - - function get_visibility() - { - return $this->visibility; - } - - function get_source() - { - return $this->source; - } - - function get_tags(): array - { - return $this->tags; - } -} - -class Emoteset -{ - public string $id; - public string $name; - public User|null $owner; - public array $emotes; - - public bool $is_default; - - public static function from_array(array $arr): Emoteset - { - $s = new Emoteset(); - - $s->id = $arr["id"]; - $s->name = $arr["name"]; - $s->owner = $arr["owner_id"]; - $s->emotes = $arr["emotes"] ?? []; - $s->is_default = $arr["is_default"] ?? false; - - return $s; - } - - public static function from_array_extended(array $arr, string $user_id, PDO &$db): Emoteset - { - if ($arr["owner_id"]) { - $arr["owner_id"] = User::get_user_by_id($db, $arr["owner_id"]); - } - - $arr["emotes"] = fetch_all_emotes_from_emoteset($db, $arr["id"], $user_id); - - return Emoteset::from_array($arr); - } - - public static function get_all_user_emotesets(PDO &$db, string $user_id): array - { - $stmt = $db->prepare("SELECT es.*, aes.is_default FROM emote_sets es - INNER JOIN acquired_emote_sets aes ON aes.emote_set_id = es.id - WHERE aes.user_id = ? - "); - $stmt->execute([$user_id]); - - $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); - $emote_sets = []; - - foreach ($rows as $row) { - array_push($emote_sets, Emoteset::from_array_extended($row, $user_id, $db)); - } - - return $emote_sets; - } -} - -function fetch_all_emotes_from_emoteset(PDO &$db, string $emote_set_id, string $user_id, int|null $limit = null): array -{ - // fetching emotes - $sql = "SELECT - e.id, e.created_at, e.visibility, - CASE - WHEN esc.code IS NOT NULL THEN esc.code - ELSE e.code - END AS code, - CASE - WHEN esc.code IS NOT NULL THEN e.code - ELSE NULL - END AS original_code, - CASE WHEN up.private_profile = FALSE OR up.id = ? THEN e.uploaded_by ELSE NULL END AS uploaded_by - FROM emotes e - LEFT JOIN user_preferences up ON up.id = e.uploaded_by - INNER JOIN emote_set_contents AS esc - ON esc.emote_set_id = ? - WHERE esc.emote_id = e.id"; - - if ($limit) { - $sql .= " LIMIT $limit"; - } - - $stmt = $db->prepare($sql); - $stmt->execute([$user_id, $emote_set_id]); - - $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); - $emotes = []; - - // fetching uploaders - foreach ($rows as $row) { - if ($row["uploaded_by"]) { - $row["uploaded_by"] = User::get_user_by_id($db, $row["uploaded_by"]); - } - - array_push($emotes, Emote::from_array($row)); - } - - return $emotes; -} - -function html_random_emote(PDO &$db) -{ - $stmt = $db->prepare("SELECT id, code FROM emotes WHERE visibility = 1 ORDER BY RAND() LIMIT 1"); - $stmt->execute(); - - if ($row = $stmt->fetch()) { - echo '' - ?> -
- - -
- prepare("SELECT e.id, e.code FROM emotes e - INNER JOIN emote_sets es ON es.is_featured = TRUE - INNER JOIN emote_set_contents esc ON es.id = esc.emote_set_id - WHERE e.visibility = 1 AND e.id = esc.emote_id ORDER BY esc.added_at DESC LIMIT 1"); - $stmt->execute(); - - if ($row = $stmt->fetch()) { - echo '' - ?> - - id}'>"; - - if ($e->is_added_by_user()) { - echo ''; - } - - // icon - echo '
'; - $scale = $emote_wall ? "3" : ((string) $scale); - echo "{$e->code}"; - echo '
'; - - // info - echo '
'; - - echo "

{$e->code}

"; - if ($e->get_uploaded_by()) { - echo "

{$e->uploaded_by->username}

"; - } - - echo '
'; - } -} - -function html_display_emoteset(array $emotesets) -{ - foreach ($emotesets as $es) { - echo ""; - - echo '
'; - echo "

$es->name

"; - echo '
'; - - echo '
'; - - foreach ($es->emotes as $e) { - echo "{$e->code}"; - } - - echo '
'; - - } -} - -function html_emotelist_mode() -{ - echo '' ?> - - - - - -
- -
-
" method="GET"> - ">
- - - - - -
-
-
- 1) { - echo '' ?> - - id = $arr["{$prefix}badge_id"]; - - return $b; - } -} - -class Role -{ - public string $name; - public Badge|null $badge; - - public static function from_array(array $arr): Role|null - { - if (!isset($arr["role_name"])) { - return null; - } - - $r = new Role(); - - $r->name = $arr["role_name"]; - $r->badge = Badge::from_array($arr, "role"); - - return $r; - } -} - -class User -{ - public string $id; - public string $username; - public int $joined_at; - public int $last_active_at; - - public Badge|null $custom_badge; - - public Role|null $role; - - public bool $private_profile; - - public static function from_array(array $arr): User - { - $u = new User(); - - $u->id = $arr["id"]; - $u->username = $arr["username"]; - $u->joined_at = strtotime($arr["joined_at"] ?? "0"); - $u->last_active_at = strtotime($arr["last_active_at"] ?? "0"); - - $u->private_profile = $row["private_profile"] ?? false; - - $u->custom_badge = Badge::from_array($arr, "custom"); - - $u->role = Role::from_array($arr); - - return $u; - } - - public static function get_user_by_id(PDO &$db, string $user_id): User|null - { - $stmt = $db->prepare("SELECT - u.id, - u.username, - u.joined_at, - u.last_active_at, - - up.private_profile, - r.name AS role_name, - r.badge_id AS role_badge_id, - ub.badge_id AS custom_badge_id - FROM users u - INNER JOIN user_preferences up ON up.id = u.id - LEFT JOIN role_assigns ra ON ra.user_id = u.id - LEFT JOIN roles r ON r.id = ra.role_id - LEFT JOIN user_badges ub ON ub.user_id = u.id - WHERE u.id = ? - "); - $stmt->execute([$user_id]); - - $u = null; - - if ($uploader_row = $stmt->fetch()) { - $u = User::from_array($uploader_row); - } - - return $u; - } -} \ No newline at end of file diff --git a/src/utils.php b/src/utils.php deleted file mode 100644 index 87d96c6..0000000 --- a/src/utils.php +++ /dev/null @@ -1,68 +0,0 @@ - 1 ? "s" : ""); - } else if ($days == 0 && $hours == 0) { - return "$minutes minute" . ($minutes > 1 ? "s" : ""); - } else if ($days == 0) { - return "$hours hour" . ($hours > 1 ? "s" : ""); - } else { - return "$days day" . ($days > 1 ? "s" : ""); - } -} - -function clamp(int $current, int $min, int $max): int -{ - return max($min, min($max, $current)); -} - -function in_range(float $value, float $min, float $max): bool -{ - return $min <= $value && $value <= $max; -} \ No newline at end of file diff --git a/src/version.php b/src/version.php deleted file mode 100644 index 8c0545a..0000000 --- a/src/version.php +++ /dev/null @@ -1,11 +0,0 @@ -