├── .env.sample ├── .gitignore ├── Dockerfile ├── admin ├── actions │ ├── BlacklistUser.php │ ├── GetUsernameFromID.php │ └── ReloadBlacklist.php ├── base.php ├── blacklist.php ├── header.php ├── index.php └── logs.php ├── api └── index.php ├── assets ├── icon-catch.svg ├── icon-mania.svg ├── icon-osu.svg └── icon-taiko.svg ├── base.php ├── beatmapSearch.php ├── callback.php ├── charts ├── INF.png ├── chart.php └── index.php ├── connection.php ├── dashboard ├── FetchScores.php ├── RetrieveRecommendations.php └── index.php ├── descriptor ├── index.php └── proposal │ ├── ChangeStatus.php │ ├── RemoveComment.php │ ├── ScrubComment.php │ ├── SubmitComment.php │ ├── SubmitVote.php │ ├── edit │ ├── SubmitEdit.php │ └── index.php │ ├── index.php │ ├── list │ └── index.php │ └── new │ ├── SubmitProposal.php │ └── index.php ├── descriptors └── index.php ├── docker-compose.yml ├── edit-queue └── index.php ├── font-awesome ├── css │ ├── font-awesome-ie7.css │ ├── font-awesome-ie7.min.css │ ├── font-awesome.css │ └── font-awesome.min.css ├── font │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ └── fontawesome-webfont.woff ├── less │ ├── bootstrap.less │ ├── core.less │ ├── extras.less │ ├── font-awesome-ie7.less │ ├── font-awesome.less │ ├── icons.less │ ├── mixins.less │ ├── path.less │ └── variables.less └── scss │ ├── _bootstrap.scss │ ├── _core.scss │ ├── _extras.scss │ ├── _icons.scss │ ├── _mixins.scss │ ├── _path.scss │ ├── _variables.scss │ ├── font-awesome-ie7.scss │ └── font-awesome.scss ├── footer.php ├── forum ├── index.php ├── new │ ├── CreatePost.php │ └── index.php ├── post │ ├── RemovePost.php │ ├── Reply.php │ └── index.php └── topic │ └── index.php ├── functions.php ├── functions ├── access.php └── bbcode.php ├── header.php ├── index.php ├── init.sql ├── list ├── HeartList.php ├── edit │ ├── DeleteList.php │ ├── GetListItemData.php │ ├── Submit.php │ └── index.php └── index.php ├── lists └── index.php ├── maintenance.php ├── maps ├── add │ ├── AddGravedMapset.php │ └── index.php └── index.php ├── mapset ├── AddToList.php ├── INF.png ├── RemoveComment.php ├── ScrubComment.php ├── SubmitComment.php ├── SubmitRating.php ├── SubmitTags.php ├── descriptor-vote │ ├── GetDescriptor.php │ ├── SubmitVote.php │ └── index.php ├── dev.php ├── edit │ ├── AcceptRequest.php │ ├── DenyRequest.php │ ├── GetUsernameFromID.php │ ├── SubmitEditRequest.php │ └── index.php ├── index.php └── ratings.php ├── profile ├── DoBlockButton.php ├── DoFriendButton.php ├── comments │ └── index.php ├── compatible │ └── index.php ├── friends │ └── index.php ├── index.php ├── rating.php ├── ratings │ └── index.php └── tabs │ ├── latest.php │ ├── lists.php │ ├── nominations.php │ ├── ratings.php │ ├── stats.php │ └── tags.php ├── project-legacy └── index.php ├── random └── index.php ├── rules └── index.php ├── script.js ├── sensitiveStrings-Example.php ├── settings ├── CreateNewApiApp.php ├── RemoveApiApp.php ├── index.php └── save.php ├── style.css ├── test.php ├── userConnect.php └── users └── index.php /.env.sample: -------------------------------------------------------------------------------- 1 | PUBLIC_URL=http://localhost:8400 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/**/workspace.xml 2 | .idea/**/tasks.xml 3 | .idea/**/usage.statistics.xml 4 | .idea/**/dictionaries 5 | .idea/**/shelf 6 | .idea/**/aws.xml 7 | .idea/**/contentModel.xml 8 | .idea/**/dataSources/ 9 | .idea/**/dataSources.ids 10 | .idea/**/dataSources.local.xml 11 | .idea/**/sqlDataSources.xml 12 | .idea/**/dynamic.xml 13 | .idea/**/uiDesigner.xml 14 | .idea/**/dbnavigator.xml 15 | .idea/**/gradle.xml 16 | .idea/**/libraries 17 | cmake-build-*/ 18 | .idea/**/mongoSettings.xml 19 | *.iws 20 | out/ 21 | .idea_modules/ 22 | atlassian-ide-plugin.xml 23 | .idea/replstate.xml 24 | .idea/sonarlint/ 25 | com_crashlytics_export_strings.xml 26 | crashlytics.properties 27 | crashlytics-build.properties 28 | fabric.properties 29 | .idea/httpRequests 30 | .idea/caches/build_file_checksums.ser 31 | sensitiveStrings.php 32 | .idea/ 33 | android-chrome-192x192.png 34 | android-chrome-512x512.png 35 | apple-touch-icon.png 36 | favicon-16x16.png 37 | favicon-32x32.png 38 | favicon.ico 39 | site.webmanifest 40 | ChartUpdate.php 41 | /docker-data 42 | /.env 43 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:8-apache 2 | RUN docker-php-ext-install mysqli 3 | -------------------------------------------------------------------------------- /admin/actions/BlacklistUser.php: -------------------------------------------------------------------------------- 1 | prepare("INSERT INTO blacklist VALUES (?)"); 8 | $stmt->bind_param("s", $blacklistUserID); 9 | $stmt->execute(); 10 | 11 | $stmt = $conn->prepare("UPDATE beatmaps AS bm 12 | SET ChartRank = NULL, 13 | ChartYearRank = NULL, 14 | Rating = NULL, 15 | RatingCount = NULL, 16 | WeightedAvg = NULl, 17 | Blacklisted = '1', 18 | BlacklistReason = 'mapper has requested blacklist' 19 | WHERE bm.BeatmapID IN ( 20 | SELECT bc1.BeatmapID 21 | FROM beatmap_creators bc1 22 | WHERE bc1.CreatorID IN ( 23 | SELECT UserID 24 | FROM blacklist 25 | ) 26 | AND NOT EXISTS ( 27 | SELECT 1 28 | FROM beatmap_creators bc2 29 | WHERE bc1.BeatmapID = bc2.BeatmapID 30 | AND bc2.CreatorID NOT IN ( 31 | SELECT UserID 32 | FROM blacklist 33 | ) 34 | ) 35 | );"); 36 | $stmt->execute(); 37 | 38 | //header("Location: ../blacklist.php"); 39 | die(); -------------------------------------------------------------------------------- /admin/actions/GetUsernameFromID.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT Username FROM mappernames WHERE UserID = ?"); 8 | $stmt->bind_param('i', $id); 9 | $stmt->execute(); 10 | $result = $stmt->get_result(); 11 | 12 | echo $result->fetch_assoc()["Username"]; -------------------------------------------------------------------------------- /admin/actions/ReloadBlacklist.php: -------------------------------------------------------------------------------- 1 | prepare("UPDATE beatmaps SET Blacklisted = '0' WHERE BlacklistReason = 'mapper has requested blacklist';"); 6 | $stmt->execute(); 7 | 8 | $stmt = $conn->prepare("UPDATE beatmaps AS bm 9 | SET ChartRank = NULL, 10 | ChartYearRank = NULL, 11 | Rating = NULL, 12 | Blacklisted = '1', 13 | BlacklistReason = 'mapper has requested blacklist' 14 | WHERE bm.BeatmapID IN ( 15 | SELECT bc1.BeatmapID 16 | FROM beatmap_creators bc1 17 | WHERE bc1.CreatorID IN ( 18 | SELECT UserID 19 | FROM blacklist 20 | ) 21 | AND NOT EXISTS ( 22 | SELECT 1 23 | FROM beatmap_creators bc2 24 | WHERE bc1.BeatmapID = bc2.BeatmapID 25 | AND bc2.CreatorID NOT IN ( 26 | SELECT UserID 27 | FROM blacklist 28 | ) 29 | ) 30 | );"); 31 | $stmt->execute(); 32 | 33 | header("Location: ../blacklist.php"); 34 | die(); -------------------------------------------------------------------------------- /admin/base.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | 20 | 21 |

blacklist

22 | 23 | 24 | 25 | 26 |
27 | 28 |
29 | 30 |
31 | 32 |


33 | 34 |
35 | 36 | 37 | 38 | 39 | 40 | prepare("SELECT m.* FROM blacklist JOIN mappernames m on blacklist.UserID = m.UserID;"); 42 | $stmt->execute(); 43 | $result = $stmt->get_result(); 44 | 45 | while ($row = $result->fetch_assoc()) { 46 | echo ""; 47 | echo ""; 48 | echo ""; 49 | echo ""; 50 | } 51 | ?> 52 |
User IDUsername
" . $row["UserID"] . "" . $row["Username"] . "
53 |
54 | 55 | -------------------------------------------------------------------------------- /admin/header.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | Admin Panel | OMDB 8 | 9 | 10 | 11 | 12 | 49 | 50 | 51 | 62 | 63 |
-------------------------------------------------------------------------------- /admin/index.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT e.*, b.SetID, b.Title, b.DifficultyName FROM beatmap_edit_requests e JOIN beatmaps b on e.BeatmapID = b.BeatmapID ORDER BY e.`Timestamp` DESC LIMIT 50;"); 5 | $stmt = $conn->prepare("SELECT users.Username, descriptors.Name, beatmaps.SetID, s.Title, beatmaps.SetID, beatmaps.DifficultyName, Vote FROM descriptor_votes LEFT JOIN users ON users.UserID = descriptor_votes.UserID LEFT JOIN descriptors ON 6 | descriptors.DescriptorID = descriptor_votes.DescriptorID LEFT JOIN beatmaps ON beatmaps.BeatmapID = descriptor_votes.BeatmapID LEFT JOIN beatmapsets s on beatmaps.SetID = s.SetID ORDER BY VoteID DESC LIMIT 150;"); 7 | $stmt->execute(); 8 | $result = $stmt->get_result(); 9 | 10 | echo "Open edit requests:
"; 11 | while($row = $result->fetch_assoc()) { 12 | //$name = GetUserNameFromId($row["UserID"], $conn); 13 | //$status = "Pending"; 14 | //if ($row["Status"] != "Pending"){ 15 | // $editorName = GetUserNameFromId($row["EditorID"], $conn); 16 | // $status = "{$row["Status"]} by {$editorName}"; 17 | //} 18 | echo "{$row["Username"]} on {$row["Title"]} [{$row["DifficultyName"]}] {$row["Name"]} {$row["Vote"]}
"; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /admin/logs.php: -------------------------------------------------------------------------------- 1 | 4 | 5 |

logs

6 | 7 |
8 | prepare("SELECT LogID, UserID, LogData FROM omdb.logs ORDER BY LogID DESC;"); 10 | if (!$stmt) { 11 | die("Query preparation failed: " . $conn->error); 12 | } 13 | 14 | if (!$stmt->execute()) { 15 | die("Query execution failed: " . $stmt->error); 16 | } 17 | 18 | $stmt->bind_result($logID, $userID, $logData); 19 | 20 | while ($stmt->fetch()) { 21 | echo "Log ID: $logID
"; 22 | echo "User ID: $userID
"; 23 | 24 | $jsonData = json_decode($logData, true); 25 | if ($jsonData === null) { 26 | echo "JSON decoding failed: " . json_last_error_msg() . "
"; 27 | } else { 28 | echo "Log Data:
"; 29 | displayTree($jsonData, 1); 30 | echo "
"; 31 | } 32 | } 33 | 34 | $stmt->close(); 35 | ?> 36 | 37 | $value) { 40 | echo str_repeat(" ", $indent * 4) . "$key: "; 41 | if (is_array($value)) { 42 | echo "
"; 43 | displayTree($value, $indent + 1); 44 | } else { 45 | echo "$value
"; 46 | } 47 | } 48 | } 49 | ?> 50 | 51 |
-------------------------------------------------------------------------------- /assets/icon-catch.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /assets/icon-mania.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /assets/icon-osu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /assets/icon-taiko.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /base.php: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /beatmapSearch.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT SetID, Title, Artist FROM `beatmapsets` WHERE `SetID`= ?;"); 11 | $stmt->bind_param('s', $setID); 12 | $stmt->execute(); 13 | $res = $stmt->get_result(); 14 | $row = $res->fetch_row(); 15 | $value = $row ? $row : null; 16 | if ($value == null){ 17 | die("Mapset not found!"); 18 | } 19 | ?> 20 |
21 | prepare("(SELECT DISTINCT `UserID`, `Username` FROM users WHERE username LIKE ?) UNION (SELECT DISTINCT `UserID`, `Username` FROM mappernames WHERE username LIKE ?) LIMIT 5;"); 26 | $like = "%$q%"; 27 | $stmt->bind_param("ss", $like, $like); 28 | $stmt->execute(); 29 | $stmt->bind_result($userID, $username); 30 | $stmt->store_result(); 31 | 32 | if ($stmt->num_rows > 0){ 33 | echo "
Users
"; 34 | while ($stmt->fetch()) { 35 | ?> 36 |
37 | close(); 42 | 43 | $stmt = $conn->prepare("SELECT s.`SetID`, s.Title, s.Artist, b.DifficultyName 44 | FROM `beatmaps` b 45 | LEFT JOIN beatmapsets s ON b.SetID = s.SetID 46 | WHERE (b.DifficultyName LIKE ? OR s.Artist LIKE ? OR s.Title LIKE ?) 47 | AND b.Mode = ? 48 | ORDER BY RatingCount DESC 49 | LIMIT 25;"); 50 | $stmt->bind_param("sssi", $like, $like, $like, $mode); 51 | $stmt->execute(); 52 | $stmt->bind_result($setId, $title, $artist, $difficultyName); 53 | $stmt->store_result(); 54 | 55 | if ($stmt->num_rows > 0){ 56 | echo "
Maps
"; 57 | while ($stmt->fetch()) { 58 | ?> 59 |
60 | close(); 65 | 66 | $stmt = $conn->prepare("SELECT * FROM `lists` WHERE MATCH (Title) AGAINST (? IN NATURAL LANGUAGE MODE) LIMIT 5;"); 67 | $stmt->bind_param("s", $like); 68 | $stmt->execute(); 69 | $result = $stmt->get_result(); 70 | 71 | if ($result->num_rows > 0){ 72 | echo "
Lists
"; 73 | while ($row = $result->fetch_assoc()) { 74 | $stmt = $conn->prepare("SELECT * FROM list_items WHERE `ListID` = ? AND `order` = 1;"); 75 | $stmt->bind_param("i", $row["ListID"]); 76 | $stmt->execute(); 77 | $item = $stmt->get_result()->fetch_assoc(); 78 | 79 | list($imageUrl, $title, $linkUrl) = getListItemDisplayInformation($item, $conn); 80 | ?> 81 |
82 |
83 | "> by 84 |
85 |
86 | close(); 91 | 92 | 93 | -------------------------------------------------------------------------------- /callback.php: -------------------------------------------------------------------------------- 1 | $clientID, 22 | "client_secret" => $clientSecret, 23 | "code" => $code, 24 | "grant_type" => "authorization_code", 25 | "redirect_uri" => relUrl("/callback.php"), 26 | )); 27 | 28 | $curl = curl_init(); 29 | 30 | curl_setopt_array($curl, array( 31 | CURLOPT_URL => 'https://osu.ppy.sh/oauth/token', 32 | CURLOPT_CUSTOMREQUEST => 'POST', 33 | CURLOPT_ENCODING => '', 34 | CURLOPT_MAXREDIRS => 10, 35 | CURLOPT_POST => true, 36 | CURLOPT_POSTFIELDS => $fields, 37 | CURLOPT_RETURNTRANSFER => true, 38 | CURLOPT_HTTPHEADER => ['Accept: application/json', 'Content-Type: application/json'], 39 | CURLOPT_FOLLOWLOCATION => true, 40 | CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, 41 | )); 42 | 43 | $response = curl_exec($curl); 44 | curl_close($curl); 45 | 46 | $json = json_decode($response, true); 47 | 48 | $accessToken = $json["access_token"]; 49 | $refreshToken = $json["refresh_token"]; 50 | $expiresIn = (int) $json["expires_in"]; 51 | 52 | $curl = curl_init(); 53 | 54 | curl_setopt_array($curl, array( 55 | CURLOPT_URL => 'https://osu.ppy.sh/api/v2/me/osu', 56 | CURLOPT_HTTPHEADER => ['Accept: application/json', 'Content-Type: application/json', 'Authorization: Bearer ' . $accessToken], 57 | CURLOPT_RETURNTRANSFER => true, 58 | CURLOPT_ENCODING => '', 59 | CURLOPT_MAXREDIRS => 10, 60 | CURLOPT_TIMEOUT => 0, 61 | CURLOPT_FOLLOWLOCATION => true, 62 | CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, 63 | CURLOPT_CUSTOMREQUEST => 'GET', 64 | )); 65 | 66 | $response = curl_exec($curl); 67 | curl_close($curl); 68 | 69 | $json = json_decode($response, true); 70 | $userId = $json["id"]; 71 | $username = $json["username"]; 72 | $country = $json["country"]; 73 | 74 | $stmt = $conn->prepare("SELECT * FROM `users` WHERE `UserID` = ?"); 75 | $stmt->bind_param("s", $userId); 76 | $stmt->execute(); 77 | $result = $stmt->get_result(); 78 | 79 | 80 | if ($result && $result->num_rows == 0) { 81 | $stmt = $conn->prepare("INSERT INTO `users` (UserID, Username, AccessToken, RefreshToken) VALUES (?, ?, ?, ?);"); 82 | $stmt->bind_param("ssss", $userId, $username, $accessToken, $refreshToken); 83 | $stmt->execute(); 84 | $stmt->close(); 85 | } else { 86 | $stmt = $conn->prepare("UPDATE `users` SET `AccessToken` = ?, `RefreshToken` = ?, `Username` = ? WHERE `UserID` = ?"); 87 | $stmt->bind_param("ssss", $accessToken, $refreshToken, $username, $userId); 88 | $stmt->execute(); 89 | $stmt->close(); 90 | } 91 | 92 | $stmt = $conn->prepare("SELECT * FROM `mappernames` WHERE `UserID` = ?"); 93 | $stmt->bind_param("s", $userId); 94 | $stmt->execute(); 95 | $result = $stmt->get_result(); 96 | 97 | 98 | if ($result && $result->num_rows == 0) { 99 | $stmt = $conn->prepare("INSERT INTO `mappernames` (UserID, Username, Country) VALUES (?, ?, ?);"); 100 | $stmt->bind_param("iss", $userId, $username, $country->code); 101 | $stmt->execute(); 102 | $stmt->close(); 103 | } else { 104 | $stmt = $conn->prepare("UPDATE `mappernames` SET `Username` = ?, `Country` = ? WHERE `UserID` = ?"); 105 | $stmt->bind_param("ssi", $username, $country->code, $userId); 106 | $stmt->execute(); 107 | $stmt->close(); 108 | } 109 | 110 | setcookie("AccessToken", $accessToken, time() + $expiresIn); 111 | siteRedirect($redirect_url); 112 | ?> 113 | -------------------------------------------------------------------------------- /charts/INF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollo-dw/omdb/14be6ecb9b37de79d3871133c449db814a3db727/charts/INF.png -------------------------------------------------------------------------------- /connection.php: -------------------------------------------------------------------------------- 1 | connect_error) { 6 | die("Connection failed: " . $conn->connect_error); 7 | } 8 | ?> -------------------------------------------------------------------------------- /dashboard/FetchScores.php: -------------------------------------------------------------------------------- 1 | 'https://osu.ppy.sh/api/v2/users/' . $userId . '/scores/recent?mode=' . $modeString . '&limit=10', 25 | CURLOPT_HTTPHEADER => ['Accept: application/json', 'Content-Type: application/json', 'Authorization: Bearer ' . $user['AccessToken']], 26 | CURLOPT_RETURNTRANSFER => true, 27 | CURLOPT_ENCODING => '', 28 | CURLOPT_MAXREDIRS => 10, 29 | CURLOPT_TIMEOUT => 0, 30 | CURLOPT_FOLLOWLOCATION => true, 31 | CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, 32 | CURLOPT_CUSTOMREQUEST => 'GET', 33 | )); 34 | 35 | $response = curl_exec($curl); 36 | curl_close($curl); 37 | 38 | $scores = json_decode($response); 39 | 40 | $stmt = $conn->prepare("SELECT `Score` FROM `ratings` WHERE `BeatmapID`=? AND `UserID`=?;"); 41 | $stmt->bind_param("si", $bID, $userId); 42 | 43 | foreach ($scores as &$score) { 44 | $bID = $score->beatmap->id; 45 | $stmt->execute(); 46 | $result = $stmt->get_result()->fetch_row()[0] ?? "-1"; 47 | $score->rating = $result; 48 | } 49 | 50 | $response = json_encode(array_reverse($scores)); 51 | 52 | echo $response; 53 | -------------------------------------------------------------------------------- /dashboard/RetrieveRecommendations.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT IF(user1_id = ?, user2_id, user1_id) AS correlated_user, correlation FROM user_correlations 6 | WHERE ? IN (user1_id, user2_id) AND correlation > 0.33 ORDER BY correlation DESC LIMIT 150;"); 7 | $stmt->bind_param("ii", $userID, $userID); 8 | $stmt->execute(); 9 | 10 | $result = $stmt->get_result(); 11 | if($result->num_rows == 0) 12 | return (array("error" => "No correlated users")); 13 | 14 | $correlated_users = []; 15 | while ($row = $result->fetch_assoc()) { 16 | $correlated_users[$row['correlated_user']] = $row['correlation']; 17 | } 18 | $stmt->close(); 19 | 20 | $correlated_ids = implode(', ', array_keys($correlated_users)); 21 | 22 | $stmt = $conn->prepare("SELECT r.BeatmapID 23 | FROM ratings r 24 | JOIN beatmap_creators bc ON r.BeatmapID = bc.BeatmapID 25 | JOIN beatmaps b ON bc.BeatmapID = b.BeatmapID 26 | JOIN beatmapsets s ON b.SetID = s.SetID 27 | WHERE r.UserID IN ($correlated_ids) 28 | AND r.BeatmapID NOT IN (SELECT BeatmapID FROM ratings WHERE UserID = ?) 29 | AND bc.CreatorID <> ? AND s.CreatorID <> ? 30 | GROUP BY r.BeatmapID 31 | HAVING COUNT(DISTINCT CASE WHEN r.UserID IN ($correlated_ids) THEN r.UserID END) > 5 32 | ORDER BY AVG(CASE WHEN r.UserID IN ($correlated_ids) THEN r.Score END) DESC 33 | LIMIT ?;"); 34 | $stmt->bind_param('iiii', $userID, $userID, $userID, $number_of_recommendations); 35 | $stmt->execute(); 36 | 37 | $result = $stmt->get_result(); 38 | $rated_beatmaps = []; 39 | while ($row = $result->fetch_assoc()) { 40 | $rated_beatmaps[] = $row['BeatmapID']; 41 | } 42 | $stmt->close(); 43 | 44 | $result_correlated_ratings = $conn->query("SELECT UserID, BeatmapID, Score FROM ratings WHERE UserID IN ($correlated_ids) AND BeatmapID IN (" . implode(',', $rated_beatmaps) . ")"); 45 | 46 | $recommendation_scores = []; 47 | $correlated_ratings = []; 48 | 49 | while ($row = $result_correlated_ratings->fetch_assoc()) { 50 | $user_id = $row['UserID']; 51 | $beatmap_id = $row['BeatmapID']; 52 | $rating = $row['Score']; 53 | 54 | if (!isset($correlated_ratings[$beatmap_id])) { 55 | $correlated_ratings[$beatmap_id] = ['sum_similarities' => 0, 'weighted_sum' => 0]; 56 | } 57 | 58 | $correlation = $correlated_users[$user_id]; 59 | $correlated_ratings[$beatmap_id]['sum_similarities'] += $correlation; 60 | $correlated_ratings[$beatmap_id]['weighted_sum'] += $rating * $correlation; 61 | } 62 | 63 | foreach ($rated_beatmaps as $beatmap_id) { 64 | if (isset($correlated_ratings[$beatmap_id]) && $correlated_ratings[$beatmap_id]['sum_similarities'] > 0) { 65 | $predicted_rating = $correlated_ratings[$beatmap_id]['weighted_sum'] / $correlated_ratings[$beatmap_id]['sum_similarities']; 66 | } else { 67 | $predicted_rating = -1; 68 | } 69 | 70 | $recommendation_scores[$beatmap_id] = $predicted_rating; 71 | } 72 | 73 | arsort($recommendation_scores); 74 | $sorted_recommendations = array_slice($recommendation_scores, 0, $number_of_recommendations, true); 75 | 76 | $beatmap_details_array = []; 77 | foreach ($sorted_recommendations as $beatmap_id => $score) { 78 | $stmt = $conn->prepare("SELECT artist, title, difficultyname, s.setid, SR, DateRanked FROM beatmaps b JOIN beatmapsets s ON b.SetID = s.SetID WHERE BeatmapID = ?;"); 79 | $stmt->bind_param('i', $beatmap_id); 80 | $stmt->execute(); 81 | 82 | $result = $stmt->get_result(); 83 | $beatmap_details = $result->fetch_row(); 84 | 85 | if ($beatmap_details) { 86 | list($artist, $title, $difficultyname, $setid, $sr, $date) = $beatmap_details; 87 | $beatmap_details_array[] = [ 88 | 'BeatmapID' => $beatmap_id, 89 | 'SetID' => $setid, 90 | 'Artist' => $artist, 91 | 'Title' => $title, 92 | 'DifficultyName' => $difficultyname, 93 | 'SR' => $sr, 94 | 'DateRanked' => $date, 95 | 'Score' => round($score, 2), 96 | ]; 97 | } 98 | } 99 | 100 | return $beatmap_details_array; 101 | } 102 | -------------------------------------------------------------------------------- /descriptor/proposal/ChangeStatus.php: -------------------------------------------------------------------------------- 1 | prepare("UPDATE descriptor_proposals SET `Status` = ?, `EditorID` = ? WHERE `ProposalID` = ?"); 19 | $updateStmt->bind_param("sii", $newStatus, $userId, $proposalID); 20 | $updateStmt->execute(); 21 | 22 | $response = array('status' => 'success', 'message' => 'Status submitted successfully'); 23 | header('Content-Type: application/json'); 24 | echo json_encode($response); -------------------------------------------------------------------------------- /descriptor/proposal/RemoveComment.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM `descriptor_proposal_comments` WHERE `CommentID` = ? and `ProposalID` = ?;"); 19 | $stmt->bind_param("ii", $commentId, $proposalID); 20 | $stmt->execute(); 21 | $result = $stmt->get_result()->fetch_assoc(); 22 | 23 | $array = array( 24 | "type" => "comment_deletion", 25 | "data" => array( 26 | "CommentID" => $result["CommentID"], 27 | "UserID" => $result["UserID"], 28 | "ProposalID" => $result["ProposalID"], 29 | "Comment" => $result["Comment"], 30 | "Date" => $result["date"], 31 | )); 32 | 33 | $json = json_encode($array); 34 | 35 | $stmt = $conn->prepare("INSERT INTO logs (UserID, LogData) VALUES (?, ?);"); 36 | $stmt->bind_param("is", $userId, $json); 37 | $stmt->execute(); 38 | $stmt->close(); 39 | 40 | if ($result["UserID"] != $userId && $userName != "apollodw") { 41 | header('HTTP/1.0 403 Forbidden'); 42 | http_response_code(403); 43 | die("Forbidden"); 44 | } 45 | 46 | $array = array( 47 | "type" => "comment_deletion", 48 | "data" => array( 49 | "CommentID" => $result["CommentID"], 50 | "UserID" => $result["UserID"], 51 | "ProposalID" => $result["ProposalID"], 52 | "Comment" => $result["Comment"], 53 | "Date" => $result["date"], 54 | )); 55 | 56 | $json = json_encode($array); 57 | 58 | echo $json; 59 | 60 | $stmt = $conn->prepare("DELETE FROM `descriptor_proposal_comments` WHERE `CommentID` = ? AND `ProposalID` = ?"); 61 | $stmt->bind_param("ii", $commentId, $proposalID); 62 | $stmt->execute(); 63 | $stmt->close(); 64 | ?> -------------------------------------------------------------------------------- /descriptor/proposal/ScrubComment.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM `descriptor_proposal_comments` WHERE `CommentID` = ? and `ProposalID` = ?;"); 25 | $stmt->bind_param("ii", $commentId, $proposalID); 26 | $stmt->execute(); 27 | $result = $stmt->get_result()->fetch_assoc(); 28 | 29 | $array = array( 30 | "type" => "comment_scrubbed", 31 | "data" => array( 32 | "CommentID" => $result["CommentID"], 33 | "UserID" => $result["UserID"], 34 | "ProposalID" => $result["ProposalID"], 35 | "Comment" => $result["Comment"], 36 | "Date" => $result["date"], 37 | )); 38 | 39 | $json = json_encode($array); 40 | 41 | $stmt = $conn->prepare("INSERT INTO logs (UserID, LogData) VALUES (?, ?);"); 42 | $stmt->bind_param("is", $userId, $json); 43 | $stmt->execute(); 44 | $stmt->close(); 45 | 46 | $stmt = $conn->prepare("UPDATE `descriptor_proposal_comments` SET `Comment`='[comment removed]' WHERE `CommentID` = ? AND `ProposalID` = ?;"); 47 | $stmt->bind_param("ii", $commentId, $proposalID); 48 | $stmt->execute(); 49 | $stmt->close(); 50 | 51 | ?> -------------------------------------------------------------------------------- /descriptor/proposal/SubmitComment.php: -------------------------------------------------------------------------------- 1 | 8000){ 15 | die("LONG"); 16 | } 17 | 18 | $stmt = $conn->prepare("SELECT COUNT(*) FROM `descriptor_proposals` WHERE `ProposalID`= ? AND `Status` = 'pending';"); 19 | $stmt->bind_param("i", $proposalID); 20 | $stmt->execute(); 21 | 22 | if($stmt->get_result()->fetch_row()[0] == 0){ 23 | die ("NO - Cant Find Proposal In DB"); 24 | } 25 | 26 | $stmt->close(); 27 | 28 | if ($loggedIn === false) { 29 | die ("NO - Not Logged In"); 30 | } 31 | 32 | $stmt = $conn->prepare("INSERT INTO `descriptor_proposal_comments` (UserID, ProposalID, Comment) VALUES (?, ?, ?);"); 33 | $stmt->bind_param("sss", $userId, $proposalID, $comment); 34 | $stmt->execute(); 35 | $stmt->close(); 36 | ?> -------------------------------------------------------------------------------- /descriptor/proposal/SubmitVote.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM descriptor_proposals WHERE ProposalID = ? AND `Status` = 'pending';"); 13 | $stmt->bind_param('i', $proposalID); 14 | $stmt->execute(); 15 | $result = $stmt->get_result(); 16 | 17 | if ($result->num_rows == 0) 18 | die(array("error" => "NO PROPOSAL FOUND")); 19 | 20 | $checkVoteStmt = $conn->prepare("SELECT VoteID, Vote FROM descriptor_proposal_votes WHERE ProposalID = ? AND UserID = ?"); 21 | $checkVoteStmt->bind_param("ii", $proposalID, $userId); 22 | $checkVoteStmt->execute(); 23 | $checkVoteResult = $checkVoteStmt->get_result(); 24 | 25 | if ($checkVoteResult->num_rows === 0) { 26 | $insertStmt = $conn->prepare("INSERT INTO descriptor_proposal_votes (UserID, Vote, ProposalID) VALUES (?, ?, ?)"); 27 | $insertStmt->bind_param("isi", $userId, $vote, $proposalID); 28 | $insertStmt->execute(); 29 | } else { 30 | $voteIDRow = $checkVoteResult->fetch_assoc(); 31 | $voteID = $voteIDRow["VoteID"]; 32 | 33 | if ($voteIDRow["Vote"] != $vote && $vote != "unvoted") { 34 | $updateStmt = $conn->prepare("UPDATE descriptor_proposal_votes SET Vote = ? WHERE VoteID = ?"); 35 | $updateStmt->bind_param("si", $vote, $voteID); 36 | $updateStmt->execute(); 37 | } else { 38 | $removeStmt = $conn->prepare("DELETE FROM descriptor_proposal_votes WHERE VoteID = ?"); 39 | $removeStmt->bind_param("i", $voteID); 40 | $removeStmt->execute(); 41 | } 42 | } 43 | 44 | $response = array('status' => 'success', 'message' => 'Vote submitted successfully'); 45 | header('Content-Type: application/json'); 46 | echo json_encode($response); -------------------------------------------------------------------------------- /descriptor/proposal/edit/SubmitEdit.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM `descriptor_proposals` WHERE ProposalID = ?;"); 15 | $stmt->bind_param("i", $proposalID); 16 | $stmt->execute(); 17 | $stmt->execute(); 18 | $proposal = $stmt->get_result()->fetch_assoc(); 19 | $stmt->close(); 20 | 21 | if ($parentID === ""){ 22 | $parentID = null; 23 | } 24 | 25 | $stmt = $conn->prepare("UPDATE `descriptor_proposals` SET Name = ?, ShortDescription = ?, ParentID = ?, Usable = ? WHERE ProposerID = ? AND ProposalID = ?;"); 26 | $stmt->bind_param("ssssii", $descriptorName, $shortDescription, $parentID, $usable, $userId, $proposalID); 27 | $stmt->execute(); 28 | $stmt->close(); 29 | 30 | header('Location: ../?id=' . $proposalID); -------------------------------------------------------------------------------- /descriptor/proposal/edit/index.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM `descriptor_proposals` WHERE `ProposalID` = ?;"); 7 | $stmt->bind_param("i", $proposal_id); 8 | $stmt->execute(); 9 | $proposal = $stmt->get_result()->fetch_assoc(); 10 | 11 | if (is_null($proposal)) 12 | die("Proposal not found"); 13 | 14 | if (!$loggedIn) 15 | die("You need to be logged in"); 16 | 17 | if ($proposal["ProposerID"] != $userId) 18 | die("This is not your proposal!"); 19 | 20 | ?> 21 | 22 | 50 | 51 |

Edit descriptor proposal

52 |
53 |
54 | 55 | 56 | 57 | 60 | 63 | 64 | 65 | 68 | 71 | 72 | 73 | 76 | 79 | 80 | 81 | 84 | 91 | 92 | 93 | 95 | 100 | 101 |
58 |
59 |
61 | " required/> 62 |
66 | 67 | 69 | 70 |
74 |
75 |
77 | "/>
78 |
82 |
83 |
85 |
89 | Can this descriptor be used on beatmaps?
Some descriptors exist as a way to group other descriptors (such as "style").
90 |
94 | 96 | 97 |
98 | It is recommended to leave a comment detailing your edits after you've made some changes. 99 |
102 |
103 |
104 | 105 | 108 | -------------------------------------------------------------------------------- /descriptor/proposal/list/index.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | 30 | 31 | prepare("SELECT * FROM `descriptor_proposals` WHERE Status = 'pending';"); 33 | $stmt->execute(); 34 | $proposals = $stmt->get_result(); 35 | $stmt->close(); 36 | ?> 37 | 38 | 39 |

Descriptor proposals

40 | 41 |
42 | fetch_assoc()) { 44 | ?> 45 |
46 | 52 |
53 | 56 |
57 | 58 |
59 | 60 | Create new descriptor proposal 61 | 62 | 65 | -------------------------------------------------------------------------------- /descriptor/proposal/new/SubmitProposal.php: -------------------------------------------------------------------------------- 1 | prepare("INSERT INTO `descriptor_proposals` (Name, ShortDescription, ParentID, Usable, Type, ProposerID) VALUES (?, ?, ?, ?, ?, ?);"); 24 | $stmt->bind_param("sssssi", $descriptorName, $shortDescription, $parentID, $usable, $type, $userId); 25 | $stmt->execute(); 26 | $descriptorId = $stmt->insert_id; 27 | $stmt->close(); 28 | 29 | $stmt = $conn->prepare("INSERT INTO `descriptor_proposal_comments` (UserID, ProposalID, Comment) VALUES (?, ?, ?);"); 30 | $stmt->bind_param("iis", $userId, $descriptorId, $entryComment); 31 | $stmt->execute(); 32 | $stmt->close(); 33 | 34 | header('Location: ../?id=' . $descriptorId); -------------------------------------------------------------------------------- /descriptor/proposal/new/index.php: -------------------------------------------------------------------------------- 1 | query("SELECT * FROM `descriptor_proposals` WHERE Status = 'pending';")->num_rows; 8 | ?> 9 | 10 | 38 | 39 |

Propose new descriptor

40 |
41 | = $MAX_PROPOSAL_COUNT) { ?> 42 |
43 |

Sorry!

44 | There is a maximum on the amount of active proposals at any given time. ()
45 | There are proposals open currently.
46 | Please wait! 47 |
48 | 49 |
50 | 51 | 52 | 55 | 58 | 59 | 60 | 63 | 66 | 67 | 68 | 71 | 74 | 75 | 76 | 79 | 86 | 87 | 88 | 91 | 95 | 96 | 97 | 99 | 102 | 103 |
53 |
54 |
56 | 57 |
61 | 62 | 64 | 65 |
69 |
70 |
72 |
73 |
77 |
78 |
80 |
84 | Can this descriptor be used on beatmaps?
Some descriptors exist as a way to group other descriptors (such as "style").
85 |
89 | 90 | 92 | 93 | Explain why this would be good as a descriptor.
Cite sources for naming and existing usage if applicable.
94 |
98 | 100 | 101 |
104 |
105 | 106 |
107 | 108 | 111 | -------------------------------------------------------------------------------- /descriptors/index.php: -------------------------------------------------------------------------------- 1 | '; 8 | foreach ($tree as $node) { 9 | $html .= '
  • ' . $node['name'] . ''; 10 | if (!empty($node['ShortDescription'])) { 11 | $html .= '
    ' . $node['ShortDescription'] . ' '; 12 | } 13 | if (isset($node['children'])) { 14 | $html .= generateTreeHTML($node['children']); 15 | } 16 | $html .= '
  • '; 17 | } 18 | $html .= ''; 19 | return $html; 20 | } 21 | 22 | function buildTree(array &$elements, $parentID = null) { 23 | $branch = array(); 24 | foreach ($elements as $element) { 25 | if ($element['parentID'] === $parentID) { 26 | $children = buildTree($elements, $element['descriptorID']); 27 | if ($children) { 28 | $element['children'] = $children; 29 | } 30 | $branch[] = $element; 31 | } 32 | } 33 | return $branch; 34 | } 35 | ?> 36 | 37 |

    Descriptors

    38 | 39 | prepare("SELECT descriptorID, name, ShortDescription, parentID FROM descriptors"); 41 | $stmt->execute(); 42 | $result = $stmt->get_result(); 43 | $descriptors = $result->fetch_all(MYSQLI_ASSOC); 44 | 45 | $tree = buildTree($descriptors); 46 | echo generateTreeHTML($tree); 47 | ?> 48 | 49 | 52 | 53 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | omdb: 5 | build: . 6 | ports: [8400:80] 7 | env_file: .env 8 | volumes: 9 | - .:/var/www/html 10 | 11 | db: 12 | image: mysql:8 13 | # NOTE: use of "mysql_native_password" is not recommended: https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password 14 | # (this is just an example, not intended to be a production configuration) 15 | command: --default-authentication-plugin=mysql_native_password 16 | environment: 17 | - MYSQL_ROOT_PASSWORD=example 18 | - MYSQL_DATABASE=omdb 19 | volumes: 20 | - ./docker-data/mysql:/var/lib/mysql 21 | - ./init.sql:/docker-entrypoint-initdb.d/init.sql 22 | -------------------------------------------------------------------------------- /edit-queue/index.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT e.*, b.SetID as SetID, e.SetID as EditSetID, s.Title as Title, b.DifficultyName FROM beatmap_edit_requests e LEFT JOIN beatmaps b on e.BeatmapID = b.BeatmapID LEFT JOIN beatmapsets s on e.SetID = s.SetID WHERE e.Status = 'Pending' ORDER BY e.`Timestamp`;"); 7 | $stmt->execute(); 8 | $result = $stmt->get_result(); 9 | 10 | 11 | ?> 12 | 13 | 27 | 28 |

    Edit queue

    29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | fetch_assoc()) { 42 | $isEditingSet = !is_null($row["EditSetID"]); 43 | $setId = $row['SetID']; 44 | $title = $row["Title"]; 45 | 46 | 47 | if ($isEditingSet){ 48 | $setId = $row['EditSetID']; 49 | // Look, I know this is not good. The answer to this is just keep queue sizes small : 50 | $title = $conn->query("SELECT Title FROM beatmapsets WHERE SetID = {$setId} LIMIT 1;")->fetch_assoc()["Title"]; 51 | } 52 | 53 | $name = GetUserNameFromId($row["UserID"], $conn); 54 | $mapsetLink = "../mapset/edit/?id={$setId}"; 55 | echo ""; 56 | echo ""; 57 | echo ""; 58 | if ($isEditingSet) { 59 | echo ""; 60 | } else { 61 | echo ""; 62 | } 63 | echo ""; 64 | echo ""; 65 | } 66 | ?> 67 | 68 |
    NameTitleDifficultyDate
    {$name}{$title}Mapset (general edit){$row["DifficultyName"]}{$row["Timestamp"]}
    69 | 70 | 73 | -------------------------------------------------------------------------------- /font-awesome/font/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollo-dw/omdb/14be6ecb9b37de79d3871133c449db814a3db727/font-awesome/font/FontAwesome.otf -------------------------------------------------------------------------------- /font-awesome/font/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollo-dw/omdb/14be6ecb9b37de79d3871133c449db814a3db727/font-awesome/font/fontawesome-webfont.eot -------------------------------------------------------------------------------- /font-awesome/font/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollo-dw/omdb/14be6ecb9b37de79d3871133c449db814a3db727/font-awesome/font/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /font-awesome/font/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollo-dw/omdb/14be6ecb9b37de79d3871133c449db814a3db727/font-awesome/font/fontawesome-webfont.woff -------------------------------------------------------------------------------- /font-awesome/less/bootstrap.less: -------------------------------------------------------------------------------- 1 | /* BOOTSTRAP SPECIFIC CLASSES 2 | * -------------------------- */ 3 | 4 | /* Bootstrap 2.0 sprites.less reset */ 5 | [class^="icon-"], 6 | [class*=" icon-"] { 7 | display: inline; 8 | width: auto; 9 | height: auto; 10 | line-height: normal; 11 | vertical-align: baseline; 12 | background-image: none; 13 | background-position: 0% 0%; 14 | background-repeat: repeat; 15 | margin-top: 0; 16 | } 17 | 18 | /* more sprites.less reset */ 19 | .icon-white, 20 | .nav-pills > .active > a > [class^="icon-"], 21 | .nav-pills > .active > a > [class*=" icon-"], 22 | .nav-list > .active > a > [class^="icon-"], 23 | .nav-list > .active > a > [class*=" icon-"], 24 | .navbar-inverse .nav > .active > a > [class^="icon-"], 25 | .navbar-inverse .nav > .active > a > [class*=" icon-"], 26 | .dropdown-menu > li > a:hover > [class^="icon-"], 27 | .dropdown-menu > li > a:hover > [class*=" icon-"], 28 | .dropdown-menu > .active > a > [class^="icon-"], 29 | .dropdown-menu > .active > a > [class*=" icon-"], 30 | .dropdown-submenu:hover > a > [class^="icon-"], 31 | .dropdown-submenu:hover > a > [class*=" icon-"] { 32 | background-image: none; 33 | } 34 | 35 | 36 | /* keeps Bootstrap styles with and without icons the same */ 37 | .btn, .nav { 38 | [class^="icon-"], 39 | [class*=" icon-"] { 40 | // display: inline; 41 | &.icon-large { line-height: .9em; } 42 | &.icon-spin { display: inline-block; } 43 | } 44 | } 45 | .nav-tabs, .nav-pills { 46 | [class^="icon-"], 47 | [class*=" icon-"] { 48 | &, &.icon-large { line-height: .9em; } 49 | } 50 | } 51 | .btn { 52 | [class^="icon-"], 53 | [class*=" icon-"] { 54 | &.pull-left, &.pull-right { 55 | &.icon-2x { margin-top: .18em; } 56 | } 57 | &.icon-spin.icon-large { line-height: .8em; } 58 | } 59 | } 60 | .btn.btn-small { 61 | [class^="icon-"], 62 | [class*=" icon-"] { 63 | &.pull-left, &.pull-right { 64 | &.icon-2x { margin-top: .25em; } 65 | } 66 | } 67 | } 68 | .btn.btn-large { 69 | [class^="icon-"], 70 | [class*=" icon-"] { 71 | margin-top: 0; // overrides bootstrap default 72 | &.pull-left, &.pull-right { 73 | &.icon-2x { margin-top: .05em; } 74 | } 75 | &.pull-left.icon-2x { margin-right: .2em; } 76 | &.pull-right.icon-2x { margin-left: .2em; } 77 | } 78 | } 79 | 80 | /* Fixes alignment in nav lists */ 81 | .nav-list [class^="icon-"], 82 | .nav-list [class*=" icon-"] { 83 | line-height: inherit; 84 | } 85 | -------------------------------------------------------------------------------- /font-awesome/less/core.less: -------------------------------------------------------------------------------- 1 | /* FONT AWESOME CORE 2 | * -------------------------- */ 3 | 4 | [class^="icon-"], 5 | [class*=" icon-"] { 6 | .icon-FontAwesome(); 7 | } 8 | 9 | [class^="icon-"]:before, 10 | [class*=" icon-"]:before { 11 | text-decoration: inherit; 12 | display: inline-block; 13 | speak: none; 14 | } 15 | 16 | /* makes the font 33% larger relative to the icon container */ 17 | .icon-large:before { 18 | vertical-align: -10%; 19 | font-size: 4/3em; 20 | } 21 | 22 | /* makes sure icons active on rollover in links */ 23 | a { 24 | [class^="icon-"], 25 | [class*=" icon-"] { 26 | display: inline; 27 | } 28 | } 29 | 30 | /* increased font size for icon-large */ 31 | [class^="icon-"], 32 | [class*=" icon-"] { 33 | &.icon-fixed-width { 34 | display: inline-block; 35 | width: 16/14em; 36 | text-align: right; 37 | padding-right: 4/14em; 38 | &.icon-large { 39 | width: 20/14em; 40 | } 41 | } 42 | } 43 | 44 | .icons-ul { 45 | margin-left: @icons-li-width; 46 | list-style-type: none; 47 | 48 | > li { position: relative; } 49 | 50 | .icon-li { 51 | position: absolute; 52 | left: -@icons-li-width; 53 | width: @icons-li-width; 54 | text-align: center; 55 | line-height: inherit; 56 | } 57 | } 58 | 59 | // allows usage of the hide class directly on font awesome icons 60 | [class^="icon-"], 61 | [class*=" icon-"] { 62 | &.hide { 63 | display: none; 64 | } 65 | } 66 | 67 | .icon-muted { color: @iconMuted; } 68 | .icon-light { color: @iconLight; } 69 | .icon-dark { color: @iconDark; } 70 | 71 | // Icon Borders 72 | // ------------------------- 73 | 74 | .icon-border { 75 | border: solid 1px @borderColor; 76 | padding: .2em .25em .15em; 77 | .border-radius(3px); 78 | } 79 | 80 | // Icon Sizes 81 | // ------------------------- 82 | 83 | .icon-2x { 84 | font-size: 2em; 85 | &.icon-border { 86 | border-width: 2px; 87 | .border-radius(4px); 88 | } 89 | } 90 | .icon-3x { 91 | font-size: 3em; 92 | &.icon-border { 93 | border-width: 3px; 94 | .border-radius(5px); 95 | } 96 | } 97 | .icon-4x { 98 | font-size: 4em; 99 | &.icon-border { 100 | border-width: 4px; 101 | .border-radius(6px); 102 | } 103 | } 104 | 105 | .icon-5x { 106 | font-size: 5em; 107 | &.icon-border { 108 | border-width: 5px; 109 | .border-radius(7px); 110 | } 111 | } 112 | 113 | 114 | // Floats & Margins 115 | // ------------------------- 116 | 117 | // Quick floats 118 | .pull-right { float: right; } 119 | .pull-left { float: left; } 120 | 121 | [class^="icon-"], 122 | [class*=" icon-"] { 123 | &.pull-left { 124 | margin-right: .3em; 125 | } 126 | &.pull-right { 127 | margin-left: .3em; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /font-awesome/less/extras.less: -------------------------------------------------------------------------------- 1 | /* EXTRAS 2 | * -------------------------- */ 3 | 4 | /* Stacked and layered icon */ 5 | .icon-stack(); 6 | 7 | /* Animated rotating icon */ 8 | .icon-spin { 9 | display: inline-block; 10 | -moz-animation: spin 2s infinite linear; 11 | -o-animation: spin 2s infinite linear; 12 | -webkit-animation: spin 2s infinite linear; 13 | animation: spin 2s infinite linear; 14 | } 15 | 16 | /* Prevent stack and spinners from being taken inline when inside a link */ 17 | a .icon-stack, 18 | a .icon-spin { 19 | display: inline-block; 20 | text-decoration: none; 21 | } 22 | 23 | @-moz-keyframes spin { 24 | 0% { -moz-transform: rotate(0deg); } 25 | 100% { -moz-transform: rotate(359deg); } 26 | } 27 | @-webkit-keyframes spin { 28 | 0% { -webkit-transform: rotate(0deg); } 29 | 100% { -webkit-transform: rotate(359deg); } 30 | } 31 | @-o-keyframes spin { 32 | 0% { -o-transform: rotate(0deg); } 33 | 100% { -o-transform: rotate(359deg); } 34 | } 35 | @-ms-keyframes spin { 36 | 0% { -ms-transform: rotate(0deg); } 37 | 100% { -ms-transform: rotate(359deg); } 38 | } 39 | @keyframes spin { 40 | 0% { transform: rotate(0deg); } 41 | 100% { transform: rotate(359deg); } 42 | } 43 | 44 | /* Icon rotations and mirroring */ 45 | .icon-rotate-90:before { 46 | -webkit-transform: rotate(90deg); 47 | -moz-transform: rotate(90deg); 48 | -ms-transform: rotate(90deg); 49 | -o-transform: rotate(90deg); 50 | transform: rotate(90deg); 51 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); 52 | } 53 | 54 | .icon-rotate-180:before { 55 | -webkit-transform: rotate(180deg); 56 | -moz-transform: rotate(180deg); 57 | -ms-transform: rotate(180deg); 58 | -o-transform: rotate(180deg); 59 | transform: rotate(180deg); 60 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); 61 | } 62 | 63 | .icon-rotate-270:before { 64 | -webkit-transform: rotate(270deg); 65 | -moz-transform: rotate(270deg); 66 | -ms-transform: rotate(270deg); 67 | -o-transform: rotate(270deg); 68 | transform: rotate(270deg); 69 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); 70 | } 71 | 72 | .icon-flip-horizontal:before { 73 | -webkit-transform: scale(-1, 1); 74 | -moz-transform: scale(-1, 1); 75 | -ms-transform: scale(-1, 1); 76 | -o-transform: scale(-1, 1); 77 | transform: scale(-1, 1); 78 | } 79 | 80 | .icon-flip-vertical:before { 81 | -webkit-transform: scale(1, -1); 82 | -moz-transform: scale(1, -1); 83 | -ms-transform: scale(1, -1); 84 | -o-transform: scale(1, -1); 85 | transform: scale(1, -1); 86 | } 87 | 88 | /* ensure rotation occurs inside anchor tags */ 89 | a { 90 | .icon-rotate-90, .icon-rotate-180, .icon-rotate-270, .icon-flip-horizontal, .icon-flip-vertical { 91 | &:before { display: inline-block; } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /font-awesome/less/font-awesome.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 3.2.1 3 | * the iconic font designed for Bootstrap 4 | * ------------------------------------------------------------------------------ 5 | * The full suite of pictographic icons, examples, and documentation can be 6 | * found at http://fontawesome.io. Stay up to date on Twitter at 7 | * http://twitter.com/fontawesome. 8 | * 9 | * License 10 | * ------------------------------------------------------------------------------ 11 | * - The Font Awesome font is licensed under SIL OFL 1.1 - 12 | * http://scripts.sil.org/OFL 13 | * - Font Awesome CSS, LESS, and SASS files are licensed under MIT License - 14 | * http://opensource.org/licenses/mit-license.html 15 | * - Font Awesome documentation licensed under CC BY 3.0 - 16 | * http://creativecommons.org/licenses/by/3.0/ 17 | * - Attribution is no longer required in Font Awesome 3.0, but much appreciated: 18 | * "Font Awesome by Dave Gandy - http://fontawesome.io" 19 | * 20 | * Author - Dave Gandy 21 | * ------------------------------------------------------------------------------ 22 | * Email: dave@fontawesome.io 23 | * Twitter: http://twitter.com/davegandy 24 | * Work: Lead Product Designer @ Kyruus - http://kyruus.com 25 | */ 26 | 27 | @import "variables.less"; 28 | @import "mixins.less"; 29 | @import "path.less"; 30 | @import "core.less"; 31 | @import "bootstrap.less"; 32 | @import "extras.less"; 33 | @import "icons.less"; 34 | -------------------------------------------------------------------------------- /font-awesome/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | .icon(@icon) { 5 | .icon-FontAwesome(); 6 | content: @icon; 7 | } 8 | 9 | .icon-FontAwesome() { 10 | font-family: FontAwesome; 11 | font-weight: normal; 12 | font-style: normal; 13 | text-decoration: inherit; 14 | -webkit-font-smoothing: antialiased; 15 | *margin-right: .3em; // fixes ie7 issues 16 | } 17 | 18 | .border-radius(@radius) { 19 | -webkit-border-radius: @radius; 20 | -moz-border-radius: @radius; 21 | border-radius: @radius; 22 | } 23 | 24 | .icon-stack(@width: 2em, @height: 2em, @top-font-size: 1em, @base-font-size: 2em) { 25 | .icon-stack { 26 | position: relative; 27 | display: inline-block; 28 | width: @width; 29 | height: @height; 30 | line-height: @width; 31 | vertical-align: -35%; 32 | [class^="icon-"], 33 | [class*=" icon-"] { 34 | display: block; 35 | text-align: center; 36 | position: absolute; 37 | width: 100%; 38 | height: 100%; 39 | font-size: @top-font-size; 40 | line-height: inherit; 41 | *line-height: @height; 42 | } 43 | .icon-stack-base { 44 | font-size: @base-font-size; 45 | *line-height: @height / @base-font-size; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /font-awesome/less/path.less: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('@{FontAwesomePath}/fontawesome-webfont.eot?v=@{FontAwesomeVersion}'); 7 | src: url('@{FontAwesomePath}/fontawesome-webfont.eot?#iefix&v=@{FontAwesomeVersion}') format('embedded-opentype'), 8 | url('@{FontAwesomePath}/fontawesome-webfont.woff?v=@{FontAwesomeVersion}') format('woff'), 9 | url('@{FontAwesomePath}/fontawesome-webfont.ttf?v=@{FontAwesomeVersion}') format('truetype'), 10 | url('@{FontAwesomePath}/fontawesome-webfont.svg#fontawesomeregular?v=@{FontAwesomeVersion}') format('svg'); 11 | // src: url('@{FontAwesomePath}/FontAwesome.otf') format('opentype'); // used when developing fonts 12 | font-weight: normal; 13 | font-style: normal; 14 | } 15 | -------------------------------------------------------------------------------- /font-awesome/scss/_bootstrap.scss: -------------------------------------------------------------------------------- 1 | /* BOOTSTRAP SPECIFIC CLASSES 2 | * -------------------------- */ 3 | 4 | /* Bootstrap 2.0 sprites.less reset */ 5 | [class^="icon-"], 6 | [class*=" icon-"] { 7 | display: inline; 8 | width: auto; 9 | height: auto; 10 | line-height: normal; 11 | vertical-align: baseline; 12 | background-image: none; 13 | background-position: 0% 0%; 14 | background-repeat: repeat; 15 | margin-top: 0; 16 | } 17 | 18 | /* more sprites.less reset */ 19 | .icon-white, 20 | .nav-pills > .active > a > [class^="icon-"], 21 | .nav-pills > .active > a > [class*=" icon-"], 22 | .nav-list > .active > a > [class^="icon-"], 23 | .nav-list > .active > a > [class*=" icon-"], 24 | .navbar-inverse .nav > .active > a > [class^="icon-"], 25 | .navbar-inverse .nav > .active > a > [class*=" icon-"], 26 | .dropdown-menu > li > a:hover > [class^="icon-"], 27 | .dropdown-menu > li > a:hover > [class*=" icon-"], 28 | .dropdown-menu > .active > a > [class^="icon-"], 29 | .dropdown-menu > .active > a > [class*=" icon-"], 30 | .dropdown-submenu:hover > a > [class^="icon-"], 31 | .dropdown-submenu:hover > a > [class*=" icon-"] { 32 | background-image: none; 33 | } 34 | 35 | 36 | /* keeps Bootstrap styles with and without icons the same */ 37 | .btn, .nav { 38 | [class^="icon-"], 39 | [class*=" icon-"] { 40 | // display: inline; 41 | &.icon-large { line-height: .9em; } 42 | &.icon-spin { display: inline-block; } 43 | } 44 | } 45 | .nav-tabs, .nav-pills { 46 | [class^="icon-"], 47 | [class*=" icon-"] { 48 | &, &.icon-large { line-height: .9em; } 49 | } 50 | } 51 | .btn { 52 | [class^="icon-"], 53 | [class*=" icon-"] { 54 | &.pull-left, &.pull-right { 55 | &.icon-2x { margin-top: .18em; } 56 | } 57 | &.icon-spin.icon-large { line-height: .8em; } 58 | } 59 | } 60 | .btn.btn-small { 61 | [class^="icon-"], 62 | [class*=" icon-"] { 63 | &.pull-left, &.pull-right { 64 | &.icon-2x { margin-top: .25em; } 65 | } 66 | } 67 | } 68 | .btn.btn-large { 69 | [class^="icon-"], 70 | [class*=" icon-"] { 71 | margin-top: 0; // overrides bootstrap default 72 | &.pull-left, &.pull-right { 73 | &.icon-2x { margin-top: .05em; } 74 | } 75 | &.pull-left.icon-2x { margin-right: .2em; } 76 | &.pull-right.icon-2x { margin-left: .2em; } 77 | } 78 | } 79 | 80 | /* Fixes alignment in nav lists */ 81 | .nav-list [class^="icon-"], 82 | .nav-list [class*=" icon-"] { 83 | line-height: inherit; 84 | } 85 | -------------------------------------------------------------------------------- /font-awesome/scss/_core.scss: -------------------------------------------------------------------------------- 1 | /* FONT AWESOME CORE 2 | * -------------------------- */ 3 | 4 | [class^="icon-"], 5 | [class*=" icon-"] { 6 | @include icon-FontAwesome(); 7 | } 8 | 9 | [class^="icon-"]:before, 10 | [class*=" icon-"]:before { 11 | text-decoration: inherit; 12 | display: inline-block; 13 | speak: none; 14 | } 15 | 16 | /* makes the font 33% larger relative to the icon container */ 17 | .icon-large:before { 18 | vertical-align: -10%; 19 | font-size: (4em/3); 20 | } 21 | 22 | /* makes sure icons active on rollover in links */ 23 | a { 24 | [class^="icon-"], 25 | [class*=" icon-"] { 26 | display: inline; 27 | } 28 | } 29 | 30 | /* increased font size for icon-large */ 31 | [class^="icon-"], 32 | [class*=" icon-"] { 33 | &.icon-fixed-width { 34 | display: inline-block; 35 | width: (16em/14); 36 | text-align: right; 37 | padding-right: (4em/14); 38 | &.icon-large { 39 | width: (20em/14); 40 | } 41 | } 42 | } 43 | 44 | .icons-ul { 45 | margin-left: $icons-li-width; 46 | list-style-type: none; 47 | 48 | > li { position: relative; } 49 | 50 | .icon-li { 51 | position: absolute; 52 | left: -$icons-li-width; 53 | width: $icons-li-width; 54 | text-align: center; 55 | line-height: inherit; 56 | } 57 | } 58 | 59 | // allows usage of the hide class directly on font awesome icons 60 | [class^="icon-"], 61 | [class*=" icon-"] { 62 | &.hide { 63 | display: none; 64 | } 65 | } 66 | 67 | .icon-muted { color: $iconMuted; } 68 | .icon-light { color: $iconLight; } 69 | .icon-dark { color: $iconDark; } 70 | 71 | // Icon Borders 72 | // ------------------------- 73 | 74 | .icon-border { 75 | border: solid 1px $borderColor; 76 | padding: .2em .25em .15em; 77 | @include border-radius(3px); 78 | } 79 | 80 | // Icon Sizes 81 | // ------------------------- 82 | 83 | .icon-2x { 84 | font-size: 2em; 85 | &.icon-border { 86 | border-width: 2px; 87 | @include border-radius(4px); 88 | } 89 | } 90 | .icon-3x { 91 | font-size: 3em; 92 | &.icon-border { 93 | border-width: 3px; 94 | @include border-radius(5px); 95 | } 96 | } 97 | .icon-4x { 98 | font-size: 4em; 99 | &.icon-border { 100 | border-width: 4px; 101 | @include border-radius(6px); 102 | } 103 | } 104 | 105 | .icon-5x { 106 | font-size: 5em; 107 | &.icon-border { 108 | border-width: 5px; 109 | @include border-radius(7px); 110 | } 111 | } 112 | 113 | 114 | // Floats & Margins 115 | // ------------------------- 116 | 117 | // Quick floats 118 | .pull-right { float: right; } 119 | .pull-left { float: left; } 120 | 121 | [class^="icon-"], 122 | [class*=" icon-"] { 123 | &.pull-left { 124 | margin-right: .3em; 125 | } 126 | &.pull-right { 127 | margin-left: .3em; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /font-awesome/scss/_extras.scss: -------------------------------------------------------------------------------- 1 | /* EXTRAS 2 | * -------------------------- */ 3 | 4 | /* Stacked and layered icon */ 5 | @include icon-stack(); 6 | 7 | /* Animated rotating icon */ 8 | .icon-spin { 9 | display: inline-block; 10 | -moz-animation: spin 2s infinite linear; 11 | -o-animation: spin 2s infinite linear; 12 | -webkit-animation: spin 2s infinite linear; 13 | animation: spin 2s infinite linear; 14 | } 15 | 16 | /* Prevent stack and spinners from being taken inline when inside a link */ 17 | a .icon-stack, 18 | a .icon-spin { 19 | display: inline-block; 20 | text-decoration: none; 21 | } 22 | 23 | @-moz-keyframes spin { 24 | 0% { -moz-transform: rotate(0deg); } 25 | 100% { -moz-transform: rotate(359deg); } 26 | } 27 | @-webkit-keyframes spin { 28 | 0% { -webkit-transform: rotate(0deg); } 29 | 100% { -webkit-transform: rotate(359deg); } 30 | } 31 | @-o-keyframes spin { 32 | 0% { -o-transform: rotate(0deg); } 33 | 100% { -o-transform: rotate(359deg); } 34 | } 35 | @-ms-keyframes spin { 36 | 0% { -ms-transform: rotate(0deg); } 37 | 100% { -ms-transform: rotate(359deg); } 38 | } 39 | @keyframes spin { 40 | 0% { transform: rotate(0deg); } 41 | 100% { transform: rotate(359deg); } 42 | } 43 | 44 | /* Icon rotations and mirroring */ 45 | .icon-rotate-90:before { 46 | -webkit-transform: rotate(90deg); 47 | -moz-transform: rotate(90deg); 48 | -ms-transform: rotate(90deg); 49 | -o-transform: rotate(90deg); 50 | transform: rotate(90deg); 51 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); 52 | } 53 | 54 | .icon-rotate-180:before { 55 | -webkit-transform: rotate(180deg); 56 | -moz-transform: rotate(180deg); 57 | -ms-transform: rotate(180deg); 58 | -o-transform: rotate(180deg); 59 | transform: rotate(180deg); 60 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); 61 | } 62 | 63 | .icon-rotate-270:before { 64 | -webkit-transform: rotate(270deg); 65 | -moz-transform: rotate(270deg); 66 | -ms-transform: rotate(270deg); 67 | -o-transform: rotate(270deg); 68 | transform: rotate(270deg); 69 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); 70 | } 71 | 72 | .icon-flip-horizontal:before { 73 | -webkit-transform: scale(-1, 1); 74 | -moz-transform: scale(-1, 1); 75 | -ms-transform: scale(-1, 1); 76 | -o-transform: scale(-1, 1); 77 | transform: scale(-1, 1); 78 | } 79 | 80 | .icon-flip-vertical:before { 81 | -webkit-transform: scale(1, -1); 82 | -moz-transform: scale(1, -1); 83 | -ms-transform: scale(1, -1); 84 | -o-transform: scale(1, -1); 85 | transform: scale(1, -1); 86 | } 87 | 88 | /* ensure rotation occurs inside anchor tags */ 89 | a { 90 | .icon-rotate-90, .icon-rotate-180, .icon-rotate-270, .icon-flip-horizontal, .icon-flip-vertical { 91 | &:before { display: inline-block; } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /font-awesome/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | @mixin icon($icon) { 5 | @include icon-FontAwesome(); 6 | content: $icon; 7 | } 8 | 9 | @mixin icon-FontAwesome() { 10 | font-family: FontAwesome; 11 | font-weight: normal; 12 | font-style: normal; 13 | text-decoration: inherit; 14 | -webkit-font-smoothing: antialiased; 15 | *margin-right: .3em; // fixes ie7 issues 16 | } 17 | 18 | @mixin border-radius($radius) { 19 | -webkit-border-radius: $radius; 20 | -moz-border-radius: $radius; 21 | border-radius: $radius; 22 | } 23 | 24 | @mixin icon-stack($width: 2em, $height: 2em, $top-font-size: 1em, $base-font-size: 2em) { 25 | .icon-stack { 26 | position: relative; 27 | display: inline-block; 28 | width: $width; 29 | height: $height; 30 | line-height: $width; 31 | vertical-align: -35%; 32 | [class^="icon-"], 33 | [class*=" icon-"] { 34 | display: block; 35 | text-align: center; 36 | position: absolute; 37 | width: 100%; 38 | height: 100%; 39 | font-size: $top-font-size; 40 | line-height: inherit; 41 | *line-height: $height; 42 | } 43 | .icon-stack-base { 44 | font-size: $base-font-size; 45 | *line-height: #{$height / $base-font-size}em; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /font-awesome/scss/_path.scss: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('#{$FontAwesomePath}/fontawesome-webfont.eot?v=#{$FontAwesomeVersion}'); 7 | src: url('#{$FontAwesomePath}/fontawesome-webfont.eot?#iefix&v=#{$FontAwesomeVersion}') format('embedded-opentype'), 8 | url('#{$FontAwesomePath}/fontawesome-webfont.woff?v=#{$FontAwesomeVersion}') format('woff'), 9 | url('#{$FontAwesomePath}/fontawesome-webfont.ttf?v=#{$FontAwesomeVersion}') format('truetype'), 10 | url('#{$FontAwesomePath}/fontawesome-webfont.svg#fontawesomeregular?v=#{$FontAwesomeVersion}') format('svg'); 11 | // src: url('#{$FontAwesomePath}/FontAwesome.otf') format('opentype'); // used when developing fonts 12 | font-weight: normal; 13 | font-style: normal; 14 | } 15 | -------------------------------------------------------------------------------- /font-awesome/scss/font-awesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 3.2.1 3 | * the iconic font designed for Bootstrap 4 | * ------------------------------------------------------------------------------ 5 | * The full suite of pictographic icons, examples, and documentation can be 6 | * found at http://fontawesome.io. Stay up to date on Twitter at 7 | * http://twitter.com/fontawesome. 8 | * 9 | * License 10 | * ------------------------------------------------------------------------------ 11 | * - The Font Awesome font is licensed under SIL OFL 1.1 - 12 | * http://scripts.sil.org/OFL 13 | * - Font Awesome CSS, LESS, and SASS files are licensed under MIT License - 14 | * http://opensource.org/licenses/mit-license.html 15 | * - Font Awesome documentation licensed under CC BY 3.0 - 16 | * http://creativecommons.org/licenses/by/3.0/ 17 | * - Attribution is no longer required in Font Awesome 3.0, but much appreciated: 18 | * "Font Awesome by Dave Gandy - http://fontawesome.io" 19 | * 20 | * Author - Dave Gandy 21 | * ------------------------------------------------------------------------------ 22 | * Email: dave@fontawesome.io 23 | * Twitter: http://twitter.com/davegandy 24 | * Work: Lead Product Designer @ Kyruus - http://kyruus.com 25 | */ 26 | 27 | @import "variables"; 28 | @import "mixins"; 29 | @import "path"; 30 | @import "core"; 31 | @import "bootstrap"; 32 | @import "extras"; 33 | @import "icons"; 34 | -------------------------------------------------------------------------------- /footer.php: -------------------------------------------------------------------------------- 1 | 4 | 5 |
    6 |
    7 | rules | 8 | discord | 9 | descriptors | 10 | edit queue | 11 | project legacy
    12 | s 13 |
    14 | 15 | -------------------------------------------------------------------------------- /forum/index.php: -------------------------------------------------------------------------------- 1 | query("SELECT 7 | ft.TopicID, 8 | ft.Name AS TopicName, 9 | ft.Description AS TopicDescription, 10 | tt.TotalThreads, 11 | tp.TotalPosts 12 | FROM 13 | forum_topics ft 14 | LEFT JOIN ( 15 | SELECT 16 | TopicID, 17 | COUNT(DISTINCT ThreadID) AS TotalThreads 18 | FROM 19 | forum_threads 20 | GROUP BY 21 | TopicID 22 | ) tt ON ft.TopicID = tt.TopicID 23 | LEFT JOIN ( 24 | SELECT 25 | ft.TopicID, 26 | COUNT(fp.PostID) AS TotalPosts 27 | FROM 28 | forum_threads ft 29 | LEFT JOIN 30 | forum_posts fp ON ft.ThreadID = fp.ThreadID 31 | GROUP BY 32 | ft.TopicID 33 | ) tp ON ft.TopicID = tp.TopicID;"); 34 | 35 | if ($username !== "moonpoint") { 36 | die("What"); 37 | } 38 | ?> 39 | 40 | 41 | 53 | 54 |

    Forums

    55 |
    56 | 57 | prepare("SELECT ft.ThreadID, ft.Title AS ThreadTitle, ft.CreatedAt AS ThreadCreatedAt, 59 | fp.PostID, fp.UserID AS PostUserID, fp.CreatedAt AS PostCreatedAt 60 | FROM forum_threads ft 61 | LEFT JOIN forum_posts fp ON ft.ThreadID = fp.ThreadID 62 | WHERE ft.TopicID = ? 63 | ORDER BY fp.CreatedAt DESC 64 | LIMIT 1"); 65 | while ($row = $stmt->fetch_assoc()) { 66 | $thread_stmt->bind_param("i", $row["TopicID"]); 67 | $thread_stmt->execute(); 68 | $latestThread = $thread_stmt->get_result()->fetch_assoc(); 69 | ?> 70 |
    71 |
    72 | ">


    73 | 74 |
    75 |
    76 |
    77 |
    78 | "> 79 | 80 | 81 | 82 |
    83 | 84 |
    85 |
    86 | posts
    87 | threads 88 |
    89 |
    90 |
    91 | 94 | 95 | 98 | -------------------------------------------------------------------------------- /forum/new/CreatePost.php: -------------------------------------------------------------------------------- 1 | prepare("INSERT INTO forum_threads (Title, TopicID, UserID) VALUES (?, ?, ?);"); 12 | $stmt->bind_param("sii", $title, $topicId, $userId); 13 | $stmt->execute(); 14 | $threadId = $stmt->insert_id; 15 | $stmt->close(); 16 | 17 | $stmt = $conn->prepare("INSERT INTO forum_posts (ThreadID, UserID, Content) VALUES (?, ?, ?);"); 18 | $stmt->bind_param("iis", $threadId, $userId, $body); 19 | $stmt->execute(); 20 | $stmt->close(); 21 | 22 | header("Location: ../post/?id=" . $threadId); 23 | die(); -------------------------------------------------------------------------------- /forum/new/index.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT Name FROM forum_topics WHERE TopicID = ?;"); 8 | $stmt->bind_param("i", $topicId); 9 | $stmt->execute(); 10 | $topic = $stmt->get_result()->fetch_assoc()["Name"]; 11 | 12 | if (is_null($topic) || !is_numeric($topicId)) 13 | die("AHHH"); 14 | 15 | if (!$loggedIn) 16 | die("Please log in"); 17 | ?> 18 | 19 | 46 | 47 |
    48 |
    49 |

    New post

    50 | 51 |
    52 | 53 | 54 |
    55 |

    56 | 57 |
    58 |

    59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 |

    68 |
    69 | 70 |
    71 | Forums are subject to the OMDB rules and code of conduct. 72 |

    73 | 74 |
    75 |
    76 | 77 | 100 | 101 | -------------------------------------------------------------------------------- /forum/post/RemovePost.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM `forum_posts` WHERE `PostID` = ? and `ThreadID` = ?;"); 19 | $stmt->bind_param("ii", $postId, $threadId); 20 | $stmt->execute(); 21 | $result = $stmt->get_result()->fetch_assoc(); 22 | 23 | if (!($result["UserID"] === $userId || $userId === 9558549)) { 24 | die("NO"); 25 | } 26 | 27 | $array = array( 28 | "type" => "post_deletion", 29 | "data" => array( 30 | "CommentID" => $result["CommentID"], 31 | "UserID" => $result["UserID"], 32 | "ThreadID" => $threadId, 33 | "Content" => $result["Content"], 34 | "Date" => $result["date"], 35 | )); 36 | 37 | $json = json_encode($array); 38 | 39 | $stmt = $conn->prepare("INSERT INTO logs (UserID, LogData) VALUES (?, ?);"); 40 | $stmt->bind_param("is", $userId, $json); 41 | $stmt->execute(); 42 | $stmt->close(); 43 | 44 | $stmt = $conn->prepare("DELETE FROM `forum_posts` WHERE `PostID` = ? AND `ThreadID` = ?;"); 45 | $stmt->bind_param("ii", $postId, $threadId); 46 | $stmt->execute(); 47 | $stmt->close(); 48 | ?> -------------------------------------------------------------------------------- /forum/post/Reply.php: -------------------------------------------------------------------------------- 1 | prepare("INSERT INTO forum_posts (ThreadID, UserID, Content) VALUES (?, ?, ?);"); 11 | $stmt->bind_param("iis", $threadId, $userId, $body); 12 | $stmt->execute(); 13 | $postId = $stmt->insert_id; 14 | $stmt->close(); 15 | 16 | header("Location: ../post/?id=" . $threadId . "#post-" . $postId); 17 | die(); -------------------------------------------------------------------------------- /forum/topic/index.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM forum_topics WHERE TopicID = ?;"); 7 | $stmt->bind_param("i", $topicId); 8 | $stmt->execute(); 9 | $topic = $stmt->get_result()->fetch_assoc(); 10 | $stmt->close(); 11 | 12 | if (is_null($topic) || !is_numeric($topicId) || !is_numeric($page)) 13 | die("ahhh"); 14 | 15 | $PageTitle = $topic["Name"]; 16 | require_once '../../header.php'; 17 | 18 | $limit = 50; 19 | $stmt = $conn->prepare("SELECT COUNT(*) FROM forum_threads WHERE TopicID = ?;"); 20 | $stmt->bind_param("i", $topicId); 21 | $stmt->execute(); 22 | $stmt->bind_result($count); 23 | $stmt->fetch(); 24 | $stmt->close(); 25 | $pageCount = floor($count / $limit) + 1; 26 | $prevPage = max($page - 1, 1); 27 | $nextPage = min($page + 1, $pageCount); 28 | $pageString = "LIMIT {$limit}"; 29 | 30 | if ($page > 1) { 31 | $lower = ($page - 1) * $limit; 32 | $pageString = "LIMIT {$lower}, {$limit}"; 33 | } 34 | 35 | $stmt = $conn->prepare("SELECT 36 | ft.ThreadID, 37 | ft.Title, 38 | ft.TopicID, 39 | ft.UserID AS ThreadUserID, 40 | ft.CreatedAt AS ThreadCreatedAt, 41 | COUNT(fp.PostID) AS TotalPosts, 42 | MAX(fp.CreatedAt) AS LatestPostCreatedAt, 43 | (SELECT fp.UserID FROM forum_posts fp WHERE ft.ThreadID = fp.ThreadID ORDER BY fp.CreatedAt DESC LIMIT 1) AS LatestPostUserID, 44 | (SELECT MAX(fp.PostID) FROM forum_posts fp WHERE ft.ThreadID = fp.ThreadID) AS LatestPostID, 45 | (SELECT MAX(fp.CreatedAt) FROM forum_posts fp WHERE ft.ThreadID = fp.ThreadID) AS LatestPostCreatedAt 46 | FROM forum_threads ft 47 | LEFT JOIN forum_posts fp ON ft.ThreadID = fp.ThreadID 48 | WHERE ft.TopicID = ? 49 | GROUP BY ft.ThreadID 50 | ORDER BY LatestPostCreatedAt DESC {$pageString};"); 51 | 52 | $stmt->bind_param("i", $topicId); 53 | $stmt->execute(); 54 | $threads = $stmt->get_result(); 55 | $stmt->close(); 56 | ?> 57 | 58 | 72 | 73 |

    74 |
    75 | 76 | 77 |
    Create new post
    78 | 79 |
    80 |
    81 | 82 | fetch_assoc()) { 84 | ?> 85 |
    86 |
    87 | ">
    88 | 89 | by "> 90 | 91 | | 92 | 93 |
    94 |
    95 |
    96 | "> 97 | " style="height:32px;width:32px;" title=""/> 98 | 99 |
    100 | "> 101 | 102 | 103 | 104 |
    105 | 106 |
    107 |
    108 | posts 109 |
    110 |
    111 |
    112 | 115 | 116 |
    117 | 124 |
    125 | 126 | -------------------------------------------------------------------------------- /functions/access.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /header.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | <?php echo $PageTitle; ?> | OMDB 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
    30 | OMDB 31 | 32 | 33 |
    34 | 35 | 39 |
    40 | 41 | 42 |
    43 | 44 |
    45 |
    46 | 47 | $csrf_token, 57 | "redirect_url" => $redirect_url, 58 | ); 59 | $state_encoded = urlencode(json_encode($state)); 60 | 61 | // the creation of the local function scope in php was a disaster for humanity -t 62 | $oauthFields = array( 63 | "client_id" => $oauthClientID, 64 | "redirect_uri" => relUrl("/callback.php"), 65 | "response_type" => "code", 66 | "scope" => "identify public", 67 | "state" => $state_encoded, 68 | ); 69 | return 'https://osu.ppy.sh/oauth/authorize?' . http_build_query($oauthFields); 70 | } 71 | ?> 72 | 73 | 74 |
    75 | 76 | 81 |
    82 |
    83 | "; break; 88 | case 1: 89 | echo "
    "; break; 90 | case 2: 91 | echo "
    "; break; 92 | case 3: 93 | echo "
    "; break; 94 | } 95 | ?> 96 |
    97 | 103 |
    104 | 107 | 108 | 109 | 110 | 111 | 115 | >log in 116 | 119 | 120 | 121 | 122 |
    123 | 124 |
    125 |
    omdb will be going down on march 1st 2025 13:00 UTC+00
    🥀🥀🥀
    read more here
    126 |
    -------------------------------------------------------------------------------- /list/HeartList.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT ListID FROM `lists` WHERE `ListID`= ?;"); 14 | $stmt->bind_param("i", $listId); 15 | $stmt->execute(); 16 | 17 | if(is_null($stmt->get_result()->fetch_assoc())){ 18 | die ("NO"); 19 | } 20 | 21 | $stmt->close(); 22 | 23 | $stmtCheckHeart = $conn->prepare("SELECT UserID FROM `list_hearts` WHERE `ListID` = ? AND `UserID` = ?"); 24 | $stmtCheckHeart->bind_param("ii", $listId, $userId); 25 | $stmtCheckHeart->execute(); 26 | 27 | $existingHeart = $stmtCheckHeart->get_result()->fetch_assoc(); 28 | 29 | if ($existingHeart) { 30 | $stmtRemoveHeart = $conn->prepare("DELETE FROM `list_hearts` WHERE `ListID` = ? AND `UserID` = ?;"); 31 | $stmtRemoveHeart->bind_param("ii", $listId, $userId); 32 | $stmtRemoveHeart->execute(); 33 | 34 | $stmtRemoveHeart->close(); 35 | 36 | echo json_encode(array("state" => 0)); 37 | } else { 38 | $stmtAddHeart = $conn->prepare("INSERT INTO `list_hearts` (`ListID`, `UserID`) VALUES (?, ?)"); 39 | $stmtAddHeart->bind_param("ii", $listId, $userId); 40 | $stmtAddHeart->execute(); 41 | 42 | $stmtAddHeart->close(); 43 | 44 | echo json_encode(array("state" => 1)); 45 | } 46 | 47 | $stmtCheckHeart->close(); 48 | 49 | -------------------------------------------------------------------------------- /list/edit/DeleteList.php: -------------------------------------------------------------------------------- 1 | "id not valid"))); 9 | 10 | if (!$loggedIn) 11 | die(json_encode(array("error" => "no logged in"))); 12 | 13 | $stmt = $conn->prepare("SELECT UserID FROM lists WHERE UserID = ? AND ListID = ?;"); 14 | $stmt->bind_param("ii", $userId, $id); 15 | $stmt->execute(); 16 | $list = $stmt->get_result()->fetch_assoc(); 17 | $stmt->close(); 18 | 19 | if (is_null($list)) 20 | die(json_encode(array("error" => "not yours, or doesn't exist"))); 21 | 22 | $stmt = $conn->prepare("DELETE FROM list_hearts WHERE ListID = ?;"); 23 | $stmt->bind_param("i", $id); 24 | $stmt->execute(); 25 | $stmt->close(); 26 | 27 | $stmt = $conn->prepare("DELETE FROM list_items WHERE ListID = ?;"); 28 | $stmt->bind_param("i", $id); 29 | $stmt->execute(); 30 | $stmt->close(); 31 | 32 | $stmt = $conn->prepare("DELETE FROM lists WHERE ListID = ?;"); 33 | $stmt->bind_param("i", $id); 34 | $stmt->execute(); 35 | $stmt->close(); -------------------------------------------------------------------------------- /list/edit/GetListItemData.php: -------------------------------------------------------------------------------- 1 | "missing data"))); 10 | 11 | if (!is_numeric($id)) 12 | die(json_encode(array("error" => "id not valid"))); 13 | 14 | $response = array(); 15 | 16 | switch ($type){ 17 | case "person": 18 | $username = GetUserNameFromId($id, $conn); 19 | if ($username == "") 20 | die(json_encode(array("error" => "user not found"))); 21 | 22 | $response = array( 23 | "imageUrl" => "https://s.ppy.sh/a/" . $id, 24 | "itemTitle" => $username, 25 | ); 26 | 27 | break; 28 | case "beatmap": 29 | $stmt = $conn->prepare("SELECT s.SetID, s.Artist, s.Title, b.DifficultyName 30 | FROM `beatmapsets` s 31 | INNER JOIN `beatmaps` b ON s.SetID = b.SetID 32 | WHERE b.BeatmapID = ?;"); 33 | $stmt->bind_param("i", $id); 34 | $stmt->execute(); 35 | $result = $stmt->get_result(); 36 | if ($result->num_rows != 1) 37 | die(json_encode(array("error" => "beatmap not found"))); 38 | 39 | $map = $result->fetch_assoc(); 40 | $title = "{$map["Artist"]} - {$map["Title"]} [{$map["DifficultyName"]}]"; 41 | $response = array( 42 | "imageUrl" => "https://b.ppy.sh/thumb/" . $map["SetID"] . "l.jpg", 43 | "itemTitle" => $title, 44 | ); 45 | 46 | break; 47 | case "beatmapset": 48 | $stmt = $conn->prepare("SELECT Artist, Title FROM `beatmapsets` WHERE `SetID` = ? LIMIT 1;"); 49 | $stmt->bind_param("i", $id); 50 | $stmt->execute(); 51 | $result = $stmt->get_result(); 52 | if ($result->num_rows != 1) 53 | die(json_encode(array("error" => "set not found"))); 54 | 55 | $set = $result->fetch_assoc(); 56 | $title = "{$set["Artist"]} - {$set["Title"]}"; 57 | $response = array( 58 | "imageUrl" => "https://b.ppy.sh/thumb/" . $id . "l.jpg", 59 | "itemTitle" => $title, 60 | ); 61 | 62 | break; 63 | } 64 | 65 | echo json_encode($response); -------------------------------------------------------------------------------- /list/edit/Submit.php: -------------------------------------------------------------------------------- 1 | "log in"))); 7 | } 8 | 9 | $postData = file_get_contents("php://input"); 10 | $decodedData = json_decode($postData, true); 11 | 12 | if ($decodedData !== null) { 13 | $listTitle = $decodedData["listTitle"]; 14 | $listDescription = $decodedData["listDescription"]; 15 | $items = $decodedData["items"]; 16 | $listId = $decodedData["listId"] ?? ""; 17 | 18 | if ($listId === "") { 19 | $stmt = $conn->prepare("INSERT INTO lists (Title, Description, UserID) VALUES (?, ?, ?);"); 20 | $stmt->bind_param("ssi", $listTitle, $listDescription, $userId); 21 | $stmt->execute(); 22 | $listId = $stmt->insert_id; 23 | $stmt->close(); 24 | } else { 25 | $stmt = $conn->prepare("SELECT UserID FROM lists WHERE UserID = ? AND ListID = ?;"); 26 | $stmt->bind_param("ii", $userId, $listId); 27 | $stmt->execute(); 28 | $existingList = $stmt->get_result()->fetch_assoc(); 29 | 30 | if (is_null($existingList)) 31 | die(json_encode(array("error" => "not yours"))); 32 | 33 | $stmt->close(); 34 | 35 | $stmt = $conn->prepare("UPDATE lists SET Title = ?, Description = ?, UpdatedAt = CURRENT_TIMESTAMP WHERE ListID = ? AND UserID = ?;"); 36 | $stmt->bind_param("ssii", $listTitle, $listDescription, $listId, $userId); 37 | $stmt->execute(); 38 | $stmt->close(); 39 | 40 | $stmt = $conn->prepare("DELETE FROM list_items WHERE ListID = ?;"); 41 | $stmt->bind_param("i", $listId); 42 | $stmt->execute(); 43 | $stmt->close(); 44 | } 45 | 46 | $stmt = $conn->prepare("INSERT INTO list_items (`ListID`, `Type`, `SubjectID`, `Description`, `order`) VALUES (?, ?, ?, ?, ?);"); 47 | foreach ($items as $item) { 48 | $type = $item["type"]; 49 | $subjectId = $item["id"]; 50 | $description = $item["description"]; 51 | $order = $item["order"]; 52 | 53 | $stmt->bind_param("isisi", $listId, $type, $subjectId, $description, $order); 54 | $stmt->execute(); 55 | } 56 | $stmt->close(); 57 | 58 | echo json_encode(array("id" => $listId)); 59 | } -------------------------------------------------------------------------------- /list/index.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM `lists` WHERE `ListID` = ?;"); 8 | $stmt->bind_param("i", $listId); 9 | $stmt->execute(); 10 | $list = $stmt->get_result()->fetch_assoc(); 11 | $stmt->close(); 12 | 13 | $title = htmlspecialchars($list['Title']); 14 | 15 | if (is_null($list)) 16 | die("List not found"); 17 | if (!is_numeric($listId)) 18 | die("How dare you"); 19 | 20 | $stmt = $conn->prepare("SELECT Count(*) as count from `list_hearts` WHERE UserID = ? AND ListID = ?;"); 21 | $stmt->bind_param("ii", $userId, $listId); 22 | $stmt->execute(); 23 | $userHasLikedList = $stmt->get_result()->fetch_assoc()["count"] >= 1; 24 | $stmt->close(); 25 | 26 | $stmt = $conn->prepare("SELECT Count(*) as count from `list_hearts` WHERE ListID = ?;"); 27 | $stmt->bind_param("i", $listId); 28 | $stmt->execute(); 29 | $listHeartCount = $stmt->get_result()->fetch_assoc()["count"]; 30 | $stmt->close(); 31 | ?> 32 | 33 | 68 | 69 |
    70 | 71 |
    72 | [] 73 | "> 74 |
    75 | 76 |

    77 | 78 | Made by ">
    79 |
    80 |
    81 |
    82 | 83 |
    84 |
    85 | 86 | 87 |
    88 | Edit 89 |
    90 | 91 |
    92 | 93 |
    94 | prepare("SELECT * FROM list_items WHERE ListID = ?;"); 96 | $stmt->bind_param("i", $listId); 97 | $stmt->execute(); 98 | $result = $stmt->get_result(); 99 | $stmt->close(); 100 | 101 | while ($listItem = $result->fetch_assoc()){ 102 | list($imageUrl, $title, $linkUrl) = getListItemDisplayInformation($listItem, $conn); 103 | ?> 104 |
    105 |
    106 | # 107 |
    108 |
    109 |
    110 | 111 |
    112 |
    113 | 114 |
    115 |
    116 | 119 |
    120 | 121 | 138 | 139 | -------------------------------------------------------------------------------- /lists/index.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | 20 |

    Lists

    21 | This listing shows the 25 latest updated lists.

    22 | 23 | Create new list 24 |
    25 | 26 |
    27 | prepare("SELECT l.ListID, l.Title, l.Description, l.UserID, 29 | (SELECT COUNT(*) FROM list_hearts lh WHERE lh.ListID = l.ListID) AS HeartCount, 30 | (SELECT COUNT(*) FROM list_items li WHERE li.ListID = l.ListID) AS ItemCount 31 | FROM lists l ORDER BY UpdatedAt DESC LIMIT 25;"); 32 | $stmt->execute(); 33 | $result = $stmt->get_result(); 34 | $stmt->close(); 35 | 36 | while ($row = $result->fetch_assoc()) { 37 | $stmt = $conn->prepare("SELECT * FROM list_items WHERE `ListID` = ? AND `order` = 1;"); 38 | $stmt->bind_param("i", $row["ListID"]); 39 | $stmt->execute(); 40 | $item = $stmt->get_result()->fetch_assoc(); 41 | 42 | list($imageUrl, $title, $linkUrl) = getListItemDisplayInformation($item, $conn); 43 | ?> 44 |
    45 |
    46 | "> 47 |
    48 |
    49 | "> by "> 50 | ( items)
    51 |

    52 | 53 | 54 |
    55 |
    56 | 59 |
    60 | 61 | -------------------------------------------------------------------------------- /maintenance.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Maintenance | OMDB 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 34 | 35 | 36 |
    37 |

    OMDB is currently undergoing maintenance.

    38 | 39 |
    doing stuff

    40 | go look at this art
    41 |
    42 | -------------------------------------------------------------------------------- /maps/add/AddGravedMapset.php: -------------------------------------------------------------------------------- 1 | "https://osu.ppy.sh/api/get_beatmaps?k=${apiV1Key}&s=${requestedSetId}", 18 | CURLOPT_HTTPHEADER => ['Accept: application/json', 'Content-Type: application/json'], 19 | CURLOPT_RETURNTRANSFER => true, 20 | CURLOPT_ENCODING => '', 21 | CURLOPT_MAXREDIRS => 10, 22 | CURLOPT_TIMEOUT => 0, 23 | CURLOPT_FOLLOWLOCATION => true, 24 | CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, 25 | CURLOPT_CUSTOMREQUEST => 'GET', 26 | )); 27 | 28 | $response = curl_exec($curl); 29 | curl_close($curl); 30 | 31 | $array = json_decode($response, true); 32 | 33 | $beatmap_stmt = $conn->prepare("INSERT INTO `beatmaps` (BeatmapID, SetID, SR, DifficultyName, Mode, Status, Blacklisted, BlacklistReason, Timestamp) 34 | VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);"); 35 | $beatmap_stmt->bind_param("iidsiiiss", $beatmapID, $setID, $SR, $difficultyName, $mode, $status, $blacklisted, $blacklist_reason, $dateRanked); 36 | 37 | $beatmapset_stmt = $conn->prepare("INSERT INTO beatmapsets (DateRanked, Artist, SetID, CreatorID, Genre, Lang, Title, Status, HasStoryboard, HasVideo) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); 38 | $beatmapset_stmt->bind_param("ssiiiisiii", $dateRanked, $artist, $setID, $creatorID, $genre, $lang, $title, $status, $hasStoryboard, $hasVideo); 39 | 40 | $creators_stmt = $conn->prepare("INSERT INTO beatmap_creators (BeatmapID, CreatorID) VALUES (?, ?)"); 41 | $creators_stmt->bind_param("ii", $beatmapID, $creatorID); 42 | 43 | if (sizeof($array) == 0) { 44 | die("there are no maps found from this id (did u paste in beatmap id)"); 45 | } 46 | 47 | foreach($array as $diff){ 48 | if($diff["approved"] != -2){ 49 | continue; 50 | } 51 | 52 | $query1 = $conn->prepare("SELECT * FROM `beatmaps` WHERE `BeatmapID` = ?"); 53 | $query1->bind_param("i", $diff["beatmap_id"]); 54 | $query1->execute(); 55 | $query1->store_result(); 56 | if ($query1->num_rows > 0) { 57 | $query1->close(); 58 | continue; 59 | } 60 | $query1->close(); 61 | 62 | $currentTimestamp = time(); 63 | $sixMonthsAgo = strtotime("-6 months", $currentTimestamp); 64 | if (strtotime($diff["last_update"]) > $sixMonthsAgo) { 65 | die("No - not old enough"); 66 | } 67 | 68 | $dateRanked = date("Y-m-d", strtotime($diff["last_update"])); 69 | $artist = $diff["artist"]; 70 | $beatmapID = $diff["beatmap_id"]; 71 | $creatorID = $diff["creator_id"]; 72 | $setID = $diff["beatmapset_id"]; 73 | $SR = $diff["difficultyrating"]; 74 | $genre = $diff["genre_id"]; 75 | $lang = $diff["language_id"]; 76 | $title = $diff["title"]; 77 | $difficultyName = $diff["version"]; 78 | $mode = $diff["mode"]; 79 | $status = $diff["approved"]; 80 | $blacklisted = 0; 81 | $hasStoryboard = $diff["storyboard"]; 82 | $hasVideo = $diff["video"]; 83 | 84 | $query2 = $conn->prepare("SELECT * FROM blacklist WHERE UserID = ?"); 85 | $query2->bind_param("i", $creatorID); 86 | $query2->execute(); 87 | $query2->store_result(); 88 | if ($query2->num_rows > 0) { 89 | $query2->close(); 90 | die("No"); 91 | } 92 | $query2->close(); 93 | 94 | $query3 = $conn->prepare("SELECT * FROM beatmapsets WHERE SetID = ?"); 95 | $query3->bind_param("i", $setID); 96 | $query3->execute(); 97 | $query3->store_result(); 98 | if ($query3->num_rows == 0) { 99 | $beatmapset_stmt->execute(); 100 | } 101 | 102 | $beatmap_stmt->execute(); 103 | $creators_stmt->execute(); 104 | } 105 | 106 | header("Location: ../../mapset/" . $requestedSetId); 107 | die(); 108 | ?> -------------------------------------------------------------------------------- /maps/add/index.php: -------------------------------------------------------------------------------- 1 | 5 | 6 | 15 | 16 |

    Add graved set

    17 | 18 |
    19 | # 20 | Add a new graved set to OMDB through this page! Some things to note: 21 | 27 |
    28 | 29 |
    30 |
    31 | 32 | 33 |
    34 | 35 | You need to be logged in to add maps! 36 | 37 |
    38 | 39 | -------------------------------------------------------------------------------- /maps/index.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT COUNT(DISTINCT s.SetID) FROM `beatmapsets` s LEFT JOIN beatmaps b ON s.SetID = b.SetID WHERE MONTH(DateRanked) = ? AND YEAR(DateRanked) = ? AND EXISTS ( 26 | SELECT 1 27 | FROM `beatmaps` bm 28 | WHERE bm.SetID = s.SetID AND bm.Mode = ? 29 | );"); 30 | $stmt->bind_param("iii", $month, $year, $mode); 31 | $stmt->execute(); 32 | $stmt->bind_result($count); 33 | $stmt->fetch(); 34 | $stmt->close(); 35 | $amntOfPages = floor($count / $limit) + 1; $prevPage = max($page - 1, 1); 36 | $nextPage = min($page + 1, $amntOfPages); 37 | 38 | $year = htmlspecialchars($year, ENT_QUOTES, 'UTF-8'); 39 | $month = htmlspecialchars($month, ENT_QUOTES, 'UTF-8'); 40 | ?> 41 | 42 |

    Map List - format('F') . " " . $year; ?>

    43 | 44 | 55 | 66 | 67 | 68 |
    69 | 76 |
    77 | 78 | 1){ 82 | $lower = ($page - 1) * $limit; 83 | $pageString = "LIMIT {$lower}, {$limit}"; 84 | } 85 | 86 | $stmt = $conn->prepare("SELECT s.SetID, s.Artist, s.Title, s.CreatorID as SetCreatorID, s.DateRanked, 87 | COUNT(DISTINCT r.BeatmapID) as RatedMapCount, 88 | COUNT(DISTINCT b.BeatmapID) as MapCount 89 | FROM `beatmapsets` s 90 | LEFT JOIN `beatmaps` b ON s.SetID = b.SetID 91 | LEFT JOIN `ratings` r ON b.BeatmapID = r.BeatmapID AND r.UserID = ? 92 | WHERE MONTH(s.DateRanked) = ? AND YEAR(s.DateRanked) = ? 93 | AND EXISTS ( 94 | SELECT 1 95 | FROM `beatmaps` bm 96 | WHERE bm.SetID = s.SetID AND bm.Mode = ? 97 | ) 98 | GROUP BY s.SetID 99 | ORDER BY s.DateRanked DESC 100 | {$pageString};"); 101 | 102 | $stmt->bind_param("iiii", $userId, $month, $year, $mode); 103 | $stmt->execute(); 104 | $result = $stmt->get_result(); 105 | while($row = $result->fetch_assoc()) { 106 | $mapperName = GetUserNameFromId($row["SetCreatorID"], $conn); 107 | 108 | $userRatedState = 0; 109 | if ($row["RatedMapCount"] == $row["MapCount"]) 110 | $userRatedState = 2; 111 | elseif ($row["RatedMapCount"] > 0) 112 | $userRatedState = 1; 113 | ?> 114 |
    115 | 118 |
    119 | "> by {$mapperName}"; ?>
    120 | rated"; 124 | break; 125 | case 2: 126 | echo "fully rated"; 127 | break; 128 | } 129 | ?> 130 |
    131 |
    132 | 133 |
    134 |
    135 | prepare("SELECT ROUND(AVG(Score), 2), COUNT(*) FROM `ratings` WHERE BeatmapID IN (SELECT BeatmapID FROM beatmaps WHERE SetID = ?)"); 137 | $stmt->bind_param("i", $row["SetID"]); 138 | $stmt->execute(); 139 | $stmt->bind_result($averageScore, $voteCount); 140 | $stmt->fetch(); 141 | $stmt->close(); 142 | ?> 143 | 144 | / 5.00 from votes
    145 |
    146 |
    147 | 150 | 151 |
    152 | 159 |
    160 | 161 | -------------------------------------------------------------------------------- /mapset/AddToList.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT ListID FROM `lists` WHERE `ListID`= ? AND `UserID` = ?;"); 12 | $stmt->bind_param("ii", $listId, $userId); 13 | $stmt->execute(); 14 | 15 | if($stmt->get_result()->fetch_row()[0] == 0){ 16 | die ("no - list doesnt exist"); 17 | } 18 | 19 | $stmt->close(); 20 | 21 | if ($loggedIn == false) { 22 | die ("NO - Not Logged In"); 23 | } 24 | 25 | $stmt = $conn->prepare("INSERT INTO `comments` (UserID, SetID, Comment) VALUES (?, ?, ?);"); 26 | $stmt->bind_param("sss", $userId, $setId, $comment); 27 | 28 | $stmt->execute(); 29 | $stmt->close(); 30 | ?> -------------------------------------------------------------------------------- /mapset/INF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollo-dw/omdb/14be6ecb9b37de79d3871133c449db814a3db727/mapset/INF.png -------------------------------------------------------------------------------- /mapset/RemoveComment.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM `comments` WHERE `CommentID` = ? and `SetID` = ?;"); 19 | $stmt->bind_param("ii", $commentId, $setId); 20 | $stmt->execute(); 21 | $result = $stmt->get_result()->fetch_assoc(); 22 | 23 | if (!($userName === "apollodw" || $result["UserID"] === $userId)) { 24 | header('HTTP/1.0 403 Forbidden'); 25 | http_response_code(403); 26 | die("Forbidden"); 27 | } 28 | 29 | $array = array( 30 | "type" => "comment_deletion", 31 | "data" => array( 32 | "CommentID" => $result["CommentID"], 33 | "UserID" => $result["UserID"], 34 | "SetID" => $result["SetID"], 35 | "Comment" => $result["Comment"], 36 | "Date" => $result["date"], 37 | )); 38 | 39 | $json = json_encode($array); 40 | 41 | $stmt = $conn->prepare("INSERT INTO logs (UserID, LogData) VALUES (?, ?);"); 42 | $stmt->bind_param("is", $userId, $json); 43 | $stmt->execute(); 44 | $stmt->close(); 45 | 46 | $stmt = $conn->prepare("DELETE FROM `comments` WHERE `CommentID` = ? AND `SetID` = ?"); 47 | $stmt->bind_param("ii", $commentId, $setId); 48 | $stmt->execute(); 49 | $stmt->close(); 50 | ?> -------------------------------------------------------------------------------- /mapset/ScrubComment.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM `comments` WHERE `CommentID` = ? and `SetID` = ?;"); 25 | $stmt->bind_param("ii", $commentId, $setId); 26 | $stmt->execute(); 27 | $result = $stmt->get_result()->fetch_assoc(); 28 | 29 | $array = array( 30 | "type" => "comment_scrubbed", 31 | "data" => array( 32 | "CommentID" => $result["CommentID"], 33 | "UserID" => $result["UserID"], 34 | "SetID" => $result["SetID"], 35 | "Comment" => $result["Comment"], 36 | "Date" => $result["date"], 37 | )); 38 | 39 | $json = json_encode($array); 40 | 41 | $stmt = $conn->prepare("INSERT INTO logs (UserID, LogData) VALUES (?, ?);"); 42 | $stmt->bind_param("is", $userId, $json); 43 | $stmt->execute(); 44 | $stmt->close(); 45 | 46 | $stmt = $conn->prepare("UPDATE `comments` SET `Comment`='[comment removed]' WHERE `CommentID` = ? AND `SetID` = ?;"); 47 | $stmt->bind_param("ii", $commentId, $setId); 48 | $stmt->execute(); 49 | $stmt->close(); 50 | 51 | echo "Hello"; 52 | ?> -------------------------------------------------------------------------------- /mapset/SubmitComment.php: -------------------------------------------------------------------------------- 1 | 8000){ 15 | die("LONG"); 16 | } 17 | 18 | $stmt = $conn->prepare("SELECT COUNT(*) FROM `beatmaps` WHERE `SetID`= ?;"); 19 | $stmt->bind_param("i", $setId); 20 | $stmt->execute(); 21 | 22 | if($stmt->get_result()->fetch_row()[0] == 0){ 23 | die ("NO - Cant Find Map In DB"); 24 | } 25 | 26 | $stmt->close(); 27 | 28 | if ($loggedIn == false) { 29 | die ("NO - Not Logged In"); 30 | } 31 | 32 | $stmt = $conn->prepare("INSERT INTO `comments` (UserID, SetID, Comment) VALUES (?, ?, ?);"); 33 | $stmt->bind_param("sss", $userId, $setId, $comment); 34 | 35 | $stmt->execute(); 36 | $stmt->close(); 37 | ?> -------------------------------------------------------------------------------- /mapset/SubmitRating.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT COUNT(*) FROM `beatmaps` WHERE `BeatmapID`= ?;"); 16 | $stmt->bind_param("i", $beatmapId); 17 | $stmt->execute(); 18 | 19 | if($stmt->get_result()->fetch_row()[0] != 1){ 20 | die ("NO"); 21 | } 22 | 23 | $stmt->close(); 24 | 25 | if ($loggedIn == false) { 26 | die ("NO"); 27 | } 28 | 29 | SubmitRating($conn, $beatmapId, $userId, $rating); -------------------------------------------------------------------------------- /mapset/SubmitTags.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT COUNT(*) FROM `beatmaps` WHERE `BeatmapID`= ?;"); 8 | $stmt->bind_param("i", $beatmapID); 9 | $stmt->execute(); 10 | 11 | if($stmt->get_result()->fetch_row()[0] == 0){ 12 | die ("NO - Cant Find Map In DB"); 13 | } 14 | 15 | $stmt->close(); 16 | 17 | if ($loggedIn == false) { 18 | die ("NO - Not Logged In"); 19 | } 20 | 21 | $tagList = explode(',', $tags); 22 | 23 | $deleteStmt = $conn->prepare("DELETE FROM rating_tags WHERE BeatmapID = ? AND UserID = ?"); 24 | $deleteStmt->bind_param("ii", $beatmapID, $userId); 25 | $deleteStmt->execute(); 26 | $deleteStmt->close(); 27 | 28 | $insertStmt = $conn->prepare("INSERT INTO rating_tags (UserID, BeatmapID, Tag) VALUES (?, ?, ?)"); 29 | $insertStmt->bind_param("iis", $userId, $beatmapID, $tag); 30 | 31 | foreach ($tagList as $tag) { 32 | $tag = trim($tag); 33 | 34 | if (empty($tag)) 35 | continue; 36 | 37 | $insertStmt->execute(); 38 | } 39 | 40 | $insertStmt->close(); -------------------------------------------------------------------------------- /mapset/descriptor-vote/GetDescriptor.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM descriptors WHERE DescriptorID = ?;"); 12 | $stmt->bind_param('i', $descriptorID); 13 | $stmt->execute(); 14 | $result = $stmt->get_result(); 15 | $descriptorData = $result->fetch_assoc(); 16 | 17 | echo json_encode($descriptorData); -------------------------------------------------------------------------------- /mapset/descriptor-vote/SubmitVote.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT BeatmapID FROM beatmaps WHERE BeatmapID = ?;"); 14 | $stmt->bind_param('i', $beatmapID); 15 | $stmt->execute(); 16 | $result = $stmt->get_result(); 17 | 18 | if ($result->num_rows == 0) 19 | die(array("error" => "NO BEATMAP FOUND")); 20 | 21 | $stmt = $conn->prepare("SELECT * FROM descriptors WHERE DescriptorID = ?;"); 22 | $stmt->bind_param('i', $descriptorID); 23 | $stmt->execute(); 24 | $result = $stmt->get_result(); 25 | 26 | if ($result->num_rows == 0) 27 | die(array("error" => "NO DESCRIPTOR FOUND")); 28 | 29 | $checkVoteStmt = $conn->prepare("SELECT VoteID, Vote FROM descriptor_votes WHERE BeatmapID = ? AND UserID = ? AND DescriptorID = ?"); 30 | $checkVoteStmt->bind_param("iii", $beatmapID, $userId, $descriptorID); 31 | $checkVoteStmt->execute(); 32 | $checkVoteResult = $checkVoteStmt->get_result(); 33 | 34 | if ($checkVoteResult->num_rows === 0) { 35 | $insertStmt = $conn->prepare("INSERT INTO descriptor_votes (BeatmapID, UserID, Vote, DescriptorID) VALUES (?, ?, ?, ?)"); 36 | $insertStmt->bind_param("iiii", $beatmapID, $userId, $vote, $descriptorID); 37 | $insertStmt->execute(); 38 | } else { 39 | $voteIDRow = $checkVoteResult->fetch_assoc(); 40 | $voteID = $voteIDRow["VoteID"]; 41 | 42 | if ($voteIDRow["Vote"] != $vote) { 43 | $updateStmt = $conn->prepare("UPDATE descriptor_votes SET Vote = ? WHERE VoteID = ?"); 44 | $updateStmt->bind_param("ii", $vote, $voteID); 45 | $updateStmt->execute(); 46 | } else { 47 | $removeStmt = $conn->prepare("DELETE FROM descriptor_votes WHERE VoteID = ?"); 48 | $removeStmt->bind_param("i", $voteID); 49 | $removeStmt->execute(); 50 | } 51 | } 52 | 53 | $stmt = $conn->prepare("SELECT SUM(CASE WHEN Vote = 1 THEN 1 ELSE 0 END) AS upvotes, SUM(CASE WHEN Vote = 0 THEN 1 ELSE 0 END) AS downvotes FROM descriptor_votes WHERE BeatmapID = ? AND DescriptorID = ?"); 54 | $stmt->bind_param('ii', $beatmapID, $descriptorID); 55 | $stmt->execute(); 56 | $result = $stmt->get_result(); 57 | $voteData = $result->fetch_assoc(); 58 | 59 | $stmt = $conn->prepare( "SELECT users.Username FROM descriptor_votes INNER JOIN users ON descriptor_votes.UserID = users.UserID WHERE descriptor_votes.BeatmapID = ? AND descriptor_votes.DescriptorID = ? AND descriptor_votes.Vote = 1;"); 60 | $stmt->bind_param('ii', $beatmapID, $descriptorID); 61 | $stmt->execute(); 62 | $result = $stmt->get_result(); 63 | 64 | $upvoteUsernames = array(); 65 | while ($row = $result->fetch_assoc()) 66 | $upvoteUsernames[] = $row['Username']; 67 | 68 | $stmt = $conn->prepare("SELECT users.Username FROM descriptor_votes INNER JOIN users ON descriptor_votes.UserID = users.UserID WHERE descriptor_votes.BeatmapID = ? AND descriptor_votes.DescriptorID = ? AND descriptor_votes.Vote = 0;"); 69 | $stmt->bind_param('ii', $beatmapID, $descriptorID); 70 | $stmt->execute(); 71 | $result = $stmt->get_result(); 72 | 73 | $downvoteUsernames = array(); 74 | while ($row = $result->fetch_assoc()) 75 | $downvoteUsernames[] = $row['Username']; 76 | 77 | $response = array( 78 | 'upvotes' => $voteData['upvotes'], 79 | 'downvotes' => $voteData['downvotes'], 80 | 'upvoteUsernames' => $upvoteUsernames, 81 | 'downvoteUsernames' => $downvoteUsernames 82 | ); 83 | 84 | echo json_encode($response); -------------------------------------------------------------------------------- /mapset/edit/AcceptRequest.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT Count(*) FROM beatmaps WHERE SetID = ?;"); 16 | $stmt->bind_param('i', $setID); 17 | $stmt->execute(); 18 | $result = $stmt->get_result(); 19 | 20 | if ($result->num_rows == 0) 21 | die("NO"); 22 | 23 | $stmt = $conn->prepare("SELECT * FROM beatmap_edit_requests WHERE `SetID` = ? AND Status = 'Pending';"); 24 | $stmt->bind_param('i', $setID); 25 | $stmt->execute(); 26 | $result = $stmt->get_result(); 27 | $request = $result->fetch_assoc(); 28 | 29 | if ($request) { 30 | $editDataArray = json_decode($request['EditData'], true); 31 | $newNominators = $editDataArray["Mappers"]; 32 | $newCredits = $editDataArray["Credits"]; 33 | 34 | $stmt = $conn->prepare("DELETE FROM beatmapset_nominators WHERE `SetID` = ?;"); 35 | $stmt->bind_param('i', $setID); 36 | $stmt->execute(); 37 | 38 | $stmt = $conn->prepare("INSERT INTO beatmapset_nominators (`SetID`, `NominatorID`) VALUES (?, ?);"); 39 | $stmt->bind_param('ii', $setID, $nominatorID); 40 | foreach ($newNominators as $nominatorID) { 41 | $stmt->execute(); 42 | } 43 | 44 | $stmt = $conn->prepare("DELETE FROM beatmapset_credits WHERE `SetID` = ?;"); 45 | $stmt->bind_param('i', $setID); 46 | $stmt->execute(); 47 | 48 | $stmt = $conn->prepare("INSERT INTO beatmapset_credits (`SetID`, `MapID`, `RoleID`, `UserID`) VALUES (?, NULL, ?, ?);"); 49 | $stmt->bind_param('iii', $setID, $roleID, $userID); 50 | 51 | foreach ($newCredits as $credit) { 52 | $roleIDStmt = $conn->prepare("SELECT RoleID FROM beatmap_roles WHERE Name = ?"); 53 | $roleIDStmt->bind_param('s', $credit['role']); 54 | $roleIDStmt->execute(); 55 | $roleIDResult = $roleIDStmt->get_result(); 56 | $roleIDRow = $roleIDResult->fetch_assoc(); 57 | $roleID = $roleIDRow['RoleID']; 58 | 59 | $userID = $credit['userID']; 60 | $stmt->execute(); 61 | } 62 | 63 | $stmt = $conn->prepare("UPDATE beatmap_edit_requests SET Status = 'Approved', EditorID = ? WHERE `EditID` = ?;"); 64 | $stmt->bind_param('ii', $userId, $request['EditID']); 65 | $stmt->execute(); 66 | } 67 | } else { 68 | $stmt = $conn->prepare("SELECT SetID FROM beatmaps WHERE BeatmapID = ?;"); 69 | $stmt->bind_param('i', $beatmapID); 70 | $stmt->execute(); 71 | $result = $stmt->get_result(); 72 | 73 | if ($result->num_rows == 0) 74 | die("NO"); 75 | 76 | $setID = $result->fetch_assoc()["SetID"]; 77 | 78 | $stmt = $conn->prepare("SELECT * FROM beatmap_edit_requests WHERE `BeatmapID` = ? AND Status = 'Pending';"); 79 | $stmt->bind_param('i', $beatmapID); 80 | $stmt->execute(); 81 | $result = $stmt->get_result(); 82 | $request = $result->fetch_assoc(); 83 | 84 | if ($request) { 85 | $editDataArray = json_decode($request['EditData'], true); 86 | $newMappers = $editDataArray["Mappers"]; 87 | 88 | $stmt = $conn->prepare("DELETE FROM beatmap_creators WHERE `BeatmapID` = ?;"); 89 | $stmt->bind_param('i', $beatmapID); 90 | $stmt->execute(); 91 | 92 | $stmt = $conn->prepare("INSERT INTO beatmap_creators (`BeatmapID`, `CreatorID`) VALUES (?, ?);"); 93 | $stmt->bind_param('ii', $beatmapID, $creatorID); 94 | foreach ($newMappers as $creatorID) { 95 | $stmt->execute(); 96 | } 97 | 98 | $stmt = $conn->prepare("UPDATE beatmap_edit_requests SET Status = 'Approved', EditorID = ? WHERE `EditID` = ?;"); 99 | $stmt->bind_param('ii', $userId, $request['EditID']); 100 | $stmt->execute(); 101 | } 102 | } 103 | 104 | header('Location: ../edit/?id=' . $setID); -------------------------------------------------------------------------------- /mapset/edit/DenyRequest.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT Count(*) FROM beatmaps WHERE SetID = ?;"); 10 | $stmt->bind_param('i', $setID); 11 | $stmt->execute(); 12 | $result = $stmt->get_result(); 13 | 14 | if ($result->num_rows == 0) 15 | die("NO"); 16 | 17 | $stmt = $conn->prepare("SELECT * FROM beatmap_edit_requests WHERE `SetID` = ? AND Status = 'Pending';"); 18 | $stmt->bind_param('i', $setID); 19 | $stmt->execute(); 20 | $result = $stmt->get_result(); 21 | 22 | if ($result->num_rows == 0) 23 | die("NO SET"); 24 | 25 | } else { 26 | $stmt = $conn->prepare("SELECT SetID FROM beatmaps WHERE BeatmapID = ?;"); 27 | $stmt->bind_param('i', $beatmapID); 28 | $stmt->execute(); 29 | $result = $stmt->get_result(); 30 | 31 | if ($result->num_rows == 0) 32 | die("NO"); 33 | 34 | $setID = $result->fetch_assoc()["SetID"]; 35 | 36 | $stmt = $conn->prepare("SELECT * FROM beatmap_edit_requests WHERE `BeatmapID` = ? AND Status = 'Pending';"); 37 | $stmt->bind_param('i', $beatmapID); 38 | $stmt->execute(); 39 | $result = $stmt->get_result(); 40 | 41 | if ($result->num_rows == 0) 42 | die("NO MAP"); 43 | } 44 | 45 | $request = $result->fetch_assoc(); 46 | if (!$loggedIn || !(isIdEditRequestAdmin($userId) || 47 | $userId == $request['UserID'])) { 48 | header('HTTP/1.0 403 Forbidden'); 49 | http_response_code(403); 50 | die("Forbidden"); 51 | } 52 | 53 | if ($request) { 54 | $stmt = $conn->prepare("UPDATE beatmap_edit_requests SET Status = 'Denied', EditorID = ? WHERE `EditID` = ?;"); 55 | $stmt->bind_param('ii', $userId, $request['EditID']); 56 | $stmt->execute(); 57 | 58 | header('Location: ../edit/?id=' . $setID); 59 | } 60 | -------------------------------------------------------------------------------- /mapset/edit/GetUsernameFromID.php: -------------------------------------------------------------------------------- 1 | $meta, 16 | "Mappers" => json_decode($mappers), 17 | "Credits" => json_decode($credits) 18 | ]; 19 | 20 | $json = json_encode($array); 21 | 22 | if ($isEditingSet){ 23 | $stmt = $conn->prepare("SELECT Count(*) FROM beatmaps WHERE SetID = ?;"); 24 | $stmt->bind_param('i', $setID); 25 | $stmt->execute(); 26 | $result = $stmt->get_result(); 27 | 28 | if ($result->num_rows == 0) 29 | die("NO"); 30 | 31 | $stmt = $conn->prepare("SELECT Status FROM `beatmap_edit_requests` WHERE SetID = ? AND `Status` = 'Pending';"); 32 | $stmt->bind_param('i', $setID); 33 | $stmt->execute(); 34 | $result = $stmt->get_result(); 35 | 36 | if ($result->num_rows > 0) 37 | die("NO"); 38 | 39 | $stmt = $conn->prepare("INSERT INTO `beatmap_edit_requests` (SetID, UserID, EditData) VALUES (?, ?, ?);"); 40 | $stmt->bind_param('iis', $setID, $userId, $json); 41 | $stmt->execute(); 42 | } else { 43 | $stmt = $conn->prepare("SELECT SetID FROM beatmaps WHERE BeatmapID = ?;"); 44 | $stmt->bind_param('i', $beatmapID); 45 | $stmt->execute(); 46 | $result = $stmt->get_result(); 47 | 48 | if ($result->num_rows == 0) 49 | die("NO"); 50 | 51 | $setID = $result->fetch_assoc()["SetID"]; 52 | 53 | $stmt = $conn->prepare("SELECT Status FROM `beatmap_edit_requests` WHERE BeatmapID = ? AND `Status` = 'Pending';"); 54 | $stmt->bind_param('i', $beatmapID); 55 | $stmt->execute(); 56 | $result = $stmt->get_result(); 57 | 58 | if ($result->num_rows > 0) 59 | die("NO"); 60 | 61 | $stmt = $conn->prepare("INSERT INTO `beatmap_edit_requests` (BeatmapID, UserID, EditData) VALUES (?, ?, ?);"); 62 | $stmt->bind_param('iis', $beatmapID, $userId, $json); 63 | $stmt->execute(); 64 | } 65 | 66 | header('Location: ../edit/?id=' . $setID); -------------------------------------------------------------------------------- /mapset/ratings.php: -------------------------------------------------------------------------------- 1 | prepare($countQuery); 47 | $stmt->bind_param($bindParams, ...$bindValues); 48 | $stmt->execute(); 49 | 50 | $lim = 18; 51 | $numberOfSetRatings = $stmt->get_result()->fetch_row()[0]; 52 | $amountOfSetPages = floor($numberOfSetRatings / $lim) + 1; 53 | 54 | $pageString = "LIMIT {$lim}"; 55 | 56 | if ($page > 1){ 57 | $lower = ($page - 1) * $lim; 58 | $pageString = "LIMIT {$lower}, {$lim}"; 59 | } 60 | 61 | $stmt = $conn->prepare($mainQuery . " " . $pageString); 62 | $stmt->bind_param($bindParamsMain, ...$bindValuesMain); 63 | $stmt->execute(); 64 | $result = $stmt->get_result(); 65 | 66 | while($row = $result->fetch_assoc()) { 67 | ?> 68 |
    "> 69 | 72 |
    73 | "> 74 | 75 | 76 | prepare("SELECT DifficultyName FROM `beatmaps` WHERE `BeatmapID`=?"); 78 | $stmt2->bind_param("s", $row["BeatmapID"]); 79 | $stmt2->execute(); 80 | $result2 = $stmt2->get_result(); 81 | $row2 = $result2->fetch_row(); 82 | echo RenderUserRating($conn, $row) . " on " . htmlspecialchars(mb_strimwidth($row2[0], 0, 40, "...")); 83 | ?> 84 |
    85 |
    86 | 0) { ?> 87 | 88 | 89 | 90 |
    91 |
    92 | 93 | 96 | 97 | 100 | 115 |
    116 | 117 | 120 | 125 | 126 |
    127 | 132 |
    133 | 134 | 167 | -------------------------------------------------------------------------------- /profile/DoBlockButton.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT COUNT(*) FROM `users` WHERE `UserID` = ?;");; 12 | $stmt->bind_param("i", $user_id_to); 13 | $stmt->execute(); 14 | if ($stmt->get_result()->fetch_row()[0] == 0) 15 | die("NOOO"); 16 | $stmt->close(); 17 | 18 | // Check if the user has already blocked 19 | $stmt_check = $conn->prepare("SELECT * FROM user_relations WHERE UserIDFrom = ? AND UserIDTo = ? AND type = 2"); 20 | $stmt_check->bind_param("ii", $user_id_from, $user_id_to); 21 | $stmt_check->execute(); 22 | $result = $stmt_check->get_result(); 23 | 24 | if ($result->num_rows > 0) { 25 | // User already blocked, so time to unblock 26 | $stmt_remove = $conn->prepare("DELETE FROM user_relations WHERE UserIDFrom = ? AND UserIDTo = ? AND type = 2"); 27 | $stmt_remove->bind_param("ii", $user_id_from, $user_id_to); 28 | $stmt_remove->execute(); 29 | $stmt_remove->close(); 30 | } else{ 31 | // Time to block. 32 | // Remove friend connections first. (soft-block) 33 | $stmt_delete_friends = $conn->prepare("DELETE FROM user_relations WHERE UserIDFrom = ? AND UserIDTo = ? AND type = 1"); 34 | $stmt_delete_friends->bind_param("ii", $user_id_from, $user_id_to); 35 | $stmt_delete_friends->execute(); 36 | $stmt_delete_friends->close(); 37 | 38 | $stmt_delete_friends = $conn->prepare("DELETE FROM user_relations WHERE UserIDFrom = ? AND UserIDTo = ? AND type = 1"); 39 | $stmt_delete_friends->bind_param("ii", $user_id_to, $user_id_from); 40 | $stmt_delete_friends->execute(); 41 | $stmt_delete_friends->close(); 42 | 43 | // And now add the blocked relation. 44 | $stmt_add = $conn->prepare("INSERT INTO user_relations (UserIDFrom, UserIDTo, type) VALUES (?, ?, 2)"); 45 | $stmt_add->bind_param("ii", $user_id_from, $user_id_to); 46 | $stmt_add->execute(); 47 | $stmt_add->close(); 48 | } 49 | ?> -------------------------------------------------------------------------------- /profile/DoFriendButton.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT COUNT(*) FROM `users` WHERE `UserID` = ?;");; 12 | $stmt->bind_param("i", $user_id_to); 13 | $stmt->execute(); 14 | if ($stmt->get_result()->fetch_row()[0] == 0) 15 | die("NOOO"); 16 | $stmt->close(); 17 | 18 | 19 | // Check if the users are already friends 20 | $stmt_check = $conn->prepare("SELECT * FROM user_relations WHERE UserIDFrom = ? AND UserIDTo = ? AND type = 1"); 21 | $stmt_check->bind_param("ii", $user_id_from, $user_id_to); 22 | $stmt_check->execute(); 23 | $result = $stmt_check->get_result(); 24 | 25 | if ($result->num_rows > 0) { 26 | // The users are already friends, so remove the friend connection 27 | $stmt_remove = $conn->prepare("DELETE FROM user_relations WHERE UserIDFrom = ? AND UserIDTo = ? AND type = 1"); 28 | $stmt_remove->bind_param("ii", $user_id_from, $user_id_to); 29 | $stmt_remove->execute(); 30 | 31 | echo 'removed'; 32 | $stmt_remove->close(); 33 | } else { 34 | // The users are not friends, so add the friend connection 35 | $stmt_add = $conn->prepare("INSERT INTO user_relations (UserIDFrom, UserIDTo, type) VALUES (?, ?, 1)"); 36 | $stmt_add->bind_param("ii", $user_id_from, $user_id_to); 37 | $stmt_add->execute(); 38 | 39 | // Check if the relationship is mutual 40 | $stmt_mutual = $conn->prepare("SELECT * FROM user_relations WHERE UserIDFrom = ? AND UserIDTo = ? AND type = 1"); 41 | $stmt_mutual->bind_param("ii", $user_id_to, $user_id_from); 42 | $stmt_mutual->execute(); 43 | $mutual_result = $stmt_mutual->get_result(); 44 | 45 | if ($mutual_result->num_rows > 0) { 46 | echo 'mutual'; 47 | } else { 48 | echo 'added'; 49 | } 50 | 51 | $stmt_mutual->close(); 52 | $stmt_add->close(); 53 | } 54 | 55 | $stmt_check->close(); -------------------------------------------------------------------------------- /profile/comments/index.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM `users` WHERE `UserID` = ?"); 14 | $stmt->bind_param("i", $profileId); 15 | $stmt->execute(); 16 | $result = $stmt->get_result(); 17 | $profile = $result->fetch_assoc(); 18 | $stmt->close(); 19 | $isUser = true; 20 | 21 | if ($profile == NULL) 22 | die("Can't view this bros friends cuz they aint an OMDB user"); 23 | 24 | $limit = 25; 25 | $prevPage = $page - 1; 26 | $nextPage = $page + 1; 27 | $stmt = $conn->prepare("SELECT COUNT(*) FROM `comments` WHERE `UserID` = ?"); 28 | $stmt->bind_param("i", $profileId); 29 | $stmt->execute(); 30 | $stmt->bind_result($count); 31 | $stmt->fetch(); 32 | $stmt->close(); 33 | 34 | $amntOfPages = floor($count / $limit) + 1; 35 | ?> 36 |

    's comments

    37 | 38 |
    39 | 40 |
    41 | 46 |
    47 | 48 |
    49 | 1){ 54 | $lower = ($page - 1) * $limit; 55 | $pageString = "LIMIT ${lower}, {$limit}"; 56 | } 57 | 58 | $stmt = $conn->prepare("SELECT * FROM `comments` WHERE `UserID`=? ORDER BY date DESC {$pageString}"); 59 | $stmt->bind_param("s", $profileId); 60 | $stmt->execute(); 61 | $result = $stmt->get_result(); 62 | if ($result->num_rows != 0) { 63 | while ($row = $result->fetch_assoc()) { 64 | $stmt = $conn->prepare("SELECT * FROM `beatmapsets` WHERE `SetID` = ?"); 65 | $stmt->bind_param("i", $row["SetID"]); 66 | $stmt->execute(); 67 | $beatmap = $stmt->get_result()->fetch_assoc(); 68 | ?> 69 |
    70 | 73 |
    74 | "> on "> 75 |
    76 |
    77 | "> 78 |
    79 |
    80 | 86 | 90 |
    91 | 92 |
    93 | 98 |
    99 | 100 | 101 | -------------------------------------------------------------------------------- /profile/compatible/index.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM `users` WHERE `UserID` = ?"); 13 | $stmt->bind_param("i", $profileId); 14 | $stmt->execute(); 15 | $result = $stmt->get_result(); 16 | $profile = $result->fetch_assoc(); 17 | $stmt->close(); 18 | $isUser = true; 19 | 20 | if ($profile == NULL) 21 | die("Can't view this bros friends cuz they aint an OMDB user"); 22 | 23 | $stmt = $conn->prepare(" 24 | SELECT users.*, correlated_users.correlation 25 | FROM users 26 | INNER JOIN ( 27 | SELECT IF(user1_id = ?, user2_id, user1_id) AS id, correlation 28 | FROM user_correlations 29 | WHERE ? IN (user1_id, user2_id) 30 | ORDER BY correlation DESC 31 | LIMIT 50 32 | ) AS correlated_users 33 | ON users.UserID = correlated_users.id; 34 | "); 35 | 36 | $stmt->bind_param("ii", $profileId, $profileId); 37 | $stmt->execute(); 38 | $similarUsers = $stmt->get_result(); 39 | $stmt->close(); 40 | ?> 41 | 42 |

    's most similar users

    43 | 44 |
    45 | fetch_assoc()) { 47 | ?> 48 | 53 | 56 |
    57 | 58 | 59 | -------------------------------------------------------------------------------- /profile/friends/index.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM `users` WHERE `UserID` = ?"); 13 | $stmt->bind_param("i", $profileId); 14 | $stmt->execute(); 15 | $result = $stmt->get_result(); 16 | $profile = $result->fetch_assoc(); 17 | $stmt->close(); 18 | $isUser = true; 19 | 20 | if ($profile == NULL) 21 | die("Can't view this bros friends cuz they aint an OMDB user"); 22 | 23 | $stmt = $conn->prepare(" 24 | SELECT u.UserID AS ID, u.Username AS username, 25 | CASE 26 | WHEN ur1.UserIDTo IS NOT NULL AND ur2.UserIDFrom IS NOT NULL THEN 1 27 | WHEN ur1.UserIDTo IS NOT NULL AND ur2.UserIDFrom IS NULL THEN 0 28 | ELSE 0 29 | END AS isMutualFriend 30 | FROM users u 31 | LEFT JOIN user_relations ur1 ON u.UserID = ur1.UserIDFrom AND ur1.UserIDTo = ? 32 | LEFT JOIN user_relations ur2 ON u.UserID = ur2.UserIDTo AND ur2.UserIDFrom = ? 33 | WHERE (ur1.UserIDTo IS NOT NULL OR ur2.UserIDFrom IS NOT NULL) 34 | AND ur1.type = 1 35 | ORDER BY LastAccessedSite DESC, ID; 36 | "); 37 | $stmt->bind_param("ii", $profileId, $profileId); 38 | $stmt->execute(); 39 | $friends = $stmt->get_result(); 40 | $stmt->close(); 41 | 42 | ?> 43 |

    's friends

    44 | 45 |
    46 | fetch_assoc()) { 48 | $friendClass = $row["isMutualFriend"] ? "pink-background" : ""; 49 | ?> 50 | 58 | 61 |
    62 | 63 | 64 | -------------------------------------------------------------------------------- /profile/rating.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT Count(*) as count FROM rating_tags WHERE UserID = ?;"); 6 | $stmt->bind_param("i", $profileId); 7 | $stmt->execute(); 8 | $tagCount = $stmt->get_result()->fetch_assoc()["count"]; 9 | $stmt->close(); 10 | 11 | $stmt = $conn->prepare("SELECT Count(*) as count FROM beatmapset_nominators WHERE NominatorID = ?;"); 12 | $stmt->bind_param("i", $profileId); 13 | $stmt->execute(); 14 | $nominationCount = $stmt->get_result()->fetch_assoc()["count"]; 15 | $stmt->close(); 16 | 17 | $stmt = $conn->prepare("SELECT Count(*) as count FROM lists WHERE UserID = ?;"); 18 | $stmt->bind_param("i", $profileId); 19 | $stmt->execute(); 20 | $listCount = $stmt->get_result()->fetch_assoc()["count"]; 21 | $stmt->close(); 22 | ?> 23 | 24 | 40 | 41 |
    42 | 43 | 44 | 45 | 0) { ?> 46 | 47 | 48 | 49 | 0) { ?> 50 | 51 | 52 | 53 | 0) { ?> 54 | 55 | 56 |
    57 | 58 |
    59 | 0) { 62 | include 'tabs/nominations.php'; 63 | } ?> 64 |
    65 | 66 | 108 | -------------------------------------------------------------------------------- /profile/tabs/latest.php: -------------------------------------------------------------------------------- 1 | 11 | 12 |
    13 | prepare("SELECT r.*, b.*, t.Tags, s.* 19 | FROM ( 20 | SELECT r.`RatingID`, GROUP_CONCAT(t.`Tag` SEPARATOR ', ') AS Tags 21 | FROM `ratings` r 22 | JOIN `beatmaps` b ON r.`BeatmapID` = b.`BeatmapID` 23 | LEFT JOIN `rating_tags` t ON t.`BeatmapID` = b.`BeatmapID` AND t.`UserID` = r.`UserID` 24 | WHERE r.`UserID` = ? AND b.`Mode` = ? 25 | GROUP BY r.`RatingID` 26 | ) AS t 27 | JOIN `ratings` r ON t.`RatingID` = r.`RatingID` 28 | JOIN `beatmaps` b ON r.`BeatmapID` = b.`BeatmapID` 29 | JOIN `beatmapsets` s on b.SetID = s.SetID 30 | ${hideBlacklistedMapsCondition} 31 | ORDER BY r.`date` DESC 32 | LIMIT 50"); 33 | $stmt->bind_param("ii", $profileId, $mode); 34 | $stmt->execute(); 35 | $result = $stmt->get_result(); 36 | 37 | while ($beatmap = $result->fetch_assoc()) { 38 | $tags = htmlspecialchars($beatmap['Tags'], ENT_COMPAT, "ISO-8859-1") 39 | ?> 40 |
    41 |
    42 | "> 43 |
    44 |
    45 | on "> 46 |
    47 | 48 |
    49 |
    50 | (only you can see this rating)'; } ?> 51 | 52 |
    53 |
    54 | 57 | ... see more! 58 |
    59 |
    60 | 61 | -------------------------------------------------------------------------------- /profile/tabs/lists.php: -------------------------------------------------------------------------------- 1 | 6 | 7 |
    8 | prepare("SELECT 10 | l.ListID, 11 | l.Title, 12 | (SELECT COUNT(*) FROM list_items li WHERE li.ListID = l.ListID) AS ItemCount 13 | FROM 14 | lists l 15 | WHERE 16 | l.UserID = ?;"); 17 | $stmt->bind_param("i", $profileId); 18 | $stmt->execute(); 19 | $result = $stmt->get_result(); 20 | $stmt->close(); 21 | 22 | while ($row = $result->fetch_assoc()) { 23 | $stmt = $conn->prepare("SELECT * FROM list_items WHERE `ListID` = ? AND `order` = 1;"); 24 | $stmt->bind_param("i", $row["ListID"]); 25 | $stmt->execute(); 26 | $item = $stmt->get_result()->fetch_assoc(); 27 | 28 | list($imageUrl, $title, $linkUrl) = getListItemDisplayInformation($item, $conn); 29 | ?> 30 |
    31 |
    32 | "> 33 |
    34 |
    35 | "> 36 | ( items) 37 |
    38 |
    39 | 42 |
    43 | -------------------------------------------------------------------------------- /profile/tabs/nominations.php: -------------------------------------------------------------------------------- 1 | 7 | 8 |
    9 | this display will be way more epic later. for now i'll just show highest charting nominated maps
    10 | prepare("SELECT bm.*, s.* FROM beatmaps bm JOIN beatmapsets s ON bm.SetID = s.SetID JOIN beatmapset_nominators bn ON bm.SetID = bn.SetID WHERE bn.NominatorID = ? AND bm.Mode = ? ORDER BY -ChartRank DESC, RatingCount DESC;"); 14 | $stmt->bind_param("ii", $profileId, $mode); 15 | $stmt->execute(); 16 | $result = $stmt->get_result(); 17 | 18 | while($row = $result->fetch_assoc()){ 19 | if (in_array($row["SetID"], $usedSets)) 20 | continue; 21 | 22 | $artist = htmlspecialchars($row["Artist"]); 23 | $title = htmlspecialchars($row["Title"]); 24 | $diffname = htmlspecialchars($row["DifficultyName"]); 25 | $avgRating = number_format($row["Rating"], 2); 26 | 27 | ?> 28 |
    29 |
    30 | 31 |
    32 |
    33 |
    34 | / 5.00 from votes 35 | , 36 | # overall 37 |
    38 |
    39 | 46 |
    47 | -------------------------------------------------------------------------------- /profile/tabs/ratings.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM `users` WHERE `UserID` = ?"); 7 | $stmt->bind_param("i", $profileId); 8 | $stmt->execute(); 9 | $result = $stmt->get_result(); 10 | $profile = $result->fetch_assoc(); 11 | $stmt->close(); 12 | 13 | $stmt = $conn->prepare("SELECT r.`Score`, COUNT(*) AS count 14 | FROM `ratings` r 15 | JOIN `beatmaps` b ON r.`BeatmapID` = b.`BeatmapID` 16 | WHERE r.`UserID` = ? AND b.`Mode` = ? 17 | GROUP BY r.`Score`"); 18 | $stmt->bind_param("ii", $profileId, $mode); 19 | $stmt->execute(); 20 | $result = $stmt->get_result(); 21 | 22 | $ratingCounts = array(); 23 | while ($row = $result->fetch_assoc()) { 24 | $ratingCounts[$row['Score']] = $row['count']; 25 | } 26 | $stmt->close(); 27 | 28 | $maxRating = sizeof($ratingCounts) >= 1 ? max($ratingCounts) : 2; 29 | 30 | $stmt = $conn->prepare("SELECT u.UserID as ID, u.Username as username FROM users u 31 | JOIN user_relations ur1 ON u.UserID = ur1.UserIDTo 32 | JOIN user_relations ur2 ON u.UserID = ur2.UserIDFrom 33 | WHERE ur1.UserIDFrom = ? AND ur2.UserIDTo = ? 34 | AND ur1.type = 1 AND ur2.type = 1 35 | ORDER BY LastAccessedSite DESC, ID"); 36 | $stmt->bind_param("ii", $profileId, $profileId); 37 | $stmt->execute(); 38 | $mutuals = $stmt->get_result(); 39 | $mutualCount = $mutuals->num_rows; 40 | $stmt->close(); 41 | ?> 42 | 43 | 67 | 68 |
    69 | 70 | = 0.0; $rating -= 0.5){ ?> 71 | 76 | 77 | 84 | 87 | 90 | 91 | 92 |
    78 |
    79 | 80 | 81 | 82 |
    83 |
    85 | 86 | 88 |
     
    89 |
    93 |
    94 | -------------------------------------------------------------------------------- /profile/tabs/tags.php: -------------------------------------------------------------------------------- 1 | 6 | 7 |
    8 | prepare("SELECT Tag, COUNT(*) AS TagCount FROM rating_tags WHERE UserID = ? GROUP BY Tag ORDER BY TagCount DESC;"); 10 | $stmt->bind_param('i', $profileId); 11 | $stmt->execute(); 12 | $result = $stmt->get_result(); 13 | 14 | while ($row = $result->fetch_assoc()) { 15 | $tag = htmlspecialchars($row["Tag"], ENT_COMPAT, "ISO-8859-1"); 16 | $encodedTag = urlencode($tag); 17 | echo "{$tag} ({$row["TagCount"]})
    "; 18 | } 19 | ?> 20 |
    21 | -------------------------------------------------------------------------------- /project-legacy/index.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT COUNT(DISTINCT bm.SetID) as count FROM beatmaps bm LEFT JOIN beatmapset_nominators bn ON bm.SetID = bn.SetID WHERE bn.SetID IS NULL AND Status IN (1, 2) AND bm.Mode = ?;"); 5 | $stmt->bind_param("i", $mode); 6 | $stmt->execute(); 7 | $setsLeft = $stmt->get_result()->fetch_assoc()["count"]; 8 | $stmt->close(); 9 | 10 | $edits = $conn->query("SELECT UserID, COUNT(*) as count FROM beatmap_edit_requests WHERE setid IS NOT NULL AND status = 'approved' GROUP BY UserID ORDER BY count DESC LIMIT 60;"); 11 | ?> 12 | 13 |
    14 |

    sets left.

    15 | There are sets from modding v1 that have missing nominator data, and this project tracks progress on backfilling it.
    16 | 17 | #1 gets 6 months supporter
    18 | #2 gets 4 months supporter
    19 | #3 gets 2 months supporter
    20 |
    21 | everyone who gets more than 300 edits will get 1 month supporter
    22 | anyone above 50 edits will get a user title on your omdb profile
    23 |
    24 | thank you hivie for offering #1 - #3 rewards! 25 |
    26 |
    27 | 28 |
    29 |
    30 | Most approved nominator edits 31 | fetch_assoc()){ 34 | $counter += 1; 35 | $username = GetUserNameFromId($row["UserID"], $conn); 36 | 37 | echo "
    38 | #{$counter} 39 | 40 | 41 | 42 | {$username} - {$row["count"]} 43 |
    "; 44 | } 45 | ?> 46 |
    47 |
    48 | Oldest maps without nominator data 49 |
    50 | prepare("SELECT * FROM beatmaps b JOIN beatmapsets s on b.SetID = s.SetID WHERE s.SetID NOT IN (SELECT DISTINCT SetID FROM beatmapset_nominators) AND s.SetID NOT IN (SELECT DISTINCT SetID FROM beatmap_edit_requests WHERE Status = 'Pending' AND SetID IS NOT NULL) AND Mode = ? AND s.Status IN (1, 2) ORDER BY DateRanked LIMIT 250;"); 54 | $stmt->bind_param("i", $mode); 55 | $stmt->execute(); 56 | $result = $stmt->get_result(); 57 | while($row = $result->fetch_assoc()){ 58 | if (in_array($row["SetID"], $usedSets)) 59 | continue; 60 | 61 | echo ""; 64 | 65 | $usedSets[] = $row["SetID"]; 66 | } 67 | ?> 68 |
    69 | 70 | Newest maps without nominator data 71 |
    72 | prepare("SELECT * FROM beatmapsets s LEFT JOIN beatmaps b ON s.SetID = b.SetID WHERE s.SetID NOT IN (SELECT DISTINCT SetID FROM beatmapset_nominators) AND s.SetID NOT IN (SELECT DISTINCT SetID FROM beatmap_edit_requests WHERE Status = 'Pending' AND SetID IS NOT NULL) AND Mode = ? AND s.Status IN (1, 2) ORDER BY DateRanked DESC LIMIT 250;"); 76 | $stmt->bind_param("i", $mode); 77 | $stmt->execute(); 78 | $result = $stmt->get_result(); 79 | while($row = $result->fetch_assoc()){ 80 | if (in_array($row["SetID"], $usedSets)) 81 | continue; 82 | 83 | echo ""; 86 | 87 | $usedSets[] = $row["SetID"]; 88 | } 89 | ?> 90 |
    91 |
    92 |
    93 | 94 | -------------------------------------------------------------------------------- /random/index.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT `SetID` FROM `beatmaps` WHERE `Mode` = ? ORDER BY RAND() LIMIT 1;"); 12 | $stmt->bind_param("i", $mode); 13 | $stmt->execute(); 14 | $stmt->bind_result($result); 15 | $stmt->fetch(); 16 | $stmt->close(); 17 | 18 | siteRedirect("/mapset/" . strval($result)); 19 | } 20 | 21 | // lol 22 | $setID = $object["beatmapsets"][rand(0,49)]["beatmaps"][0]["beatmapset_id"]; 23 | 24 | if ($setID == NULL){ 25 | $stmt = $conn->prepare("SELECT `SetID` FROM `beatmaps` WHERE `Mode` = ? ORDER BY RAND() LIMIT 1;"); 26 | $stmt->bind_param("i", $mode); 27 | $stmt->execute(); 28 | $stmt->bind_result($result); 29 | $stmt->fetch(); 30 | $stmt->close(); 31 | 32 | siteRedirect("/mapset/" . strval($result)); 33 | } 34 | 35 | siteRedirect("/mapset/" . $setID); 36 | } 37 | 38 | } 39 | 40 | $stmt = $conn->prepare("SELECT `SetID` FROM `beatmaps` WHERE `Mode` = ? ORDER BY RAND() LIMIT 1;"); 41 | $stmt->bind_param("i", $mode); 42 | $stmt->execute(); 43 | $stmt->bind_result($result); 44 | $stmt->fetch(); 45 | $stmt->close(); 46 | 47 | if (!$result || !count($result)) { 48 | http_response_code(404); 49 | echo "No beatmaps"; 50 | } else { 51 | siteRedirect("/mapset/" . strval($result)); 52 | } 53 | -------------------------------------------------------------------------------- /rules/index.php: -------------------------------------------------------------------------------- 1 | 5 | 6 |
    7 |

    Rules & Code of Conduct

    8 |

    Community

    9 |
      10 |
    1. Treat fellow OMDB users with respect.
    2. 11 |
    3. Avoid actions that disrespects the site's intended functionality (such as manipulating votes in a group, or using multiaccounts).
    4. 12 |
    5. Do not encourage other users who are engaging in rule-breaking behaviour.
    6. 13 |
    14 |

    Violation of these rules may lead to permanent account suspension.

    15 |
    16 |

    Comments

    17 |
      18 |
    1. Please only use English for your comments to ensure everyone can understand and participate.
    2. 19 |
    3. Do not post insensitive content. This includes racism, sexism, homophobia and transphobia.
    4. 20 |
    5. Engage in discussions with respect and courtesy. Disagreements are fine, but avoid personal attacks and insults.
    6. 21 |
    7. Remember that tastes vary. Be open to different viewpoints and diverse preferences.
    8. 22 |
    9. Derailing ongoing conversations are not allowed. Do not be disruptive.
    10. 23 |
    24 |

    Violation of these rules may result in comments being removed. Repeated offenses can lead to permanent account suspension.

    25 |
    26 |

    Last updated: 27th August 2023

    27 |

    28 | at the end of the day, this is my little passion project and i want to have an inviting userbase that fosters interesting discussions about maps :) 29 |

    30 |
    31 | 32 | 35 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | $('#osuLink').on('click', function() { 3 | setGameMode(0) 4 | }); 5 | 6 | $('#taikoLink').on('click', function() { 7 | setGameMode(1) 8 | }); 9 | 10 | $('#catchLink').on('click', function() { 11 | setGameMode(2) 12 | }); 13 | 14 | $('#maniaLink').on('click', function() { 15 | setGameMode(3) 16 | }); 17 | }); 18 | 19 | function setGameMode(mode) { 20 | var expirationDate = new Date(); 21 | expirationDate.setFullYear(expirationDate.getFullYear() + 1); 22 | 23 | var cookieValue = "mode=" + mode + "; expires=" + expirationDate.toUTCString() + ";path=/;"; 24 | document.cookie = cookieValue; 25 | location.reload(); 26 | } 27 | 28 | let debounceTimer; 29 | 30 | function showResult(str) { 31 | if (str.length == 0) { 32 | document.getElementById("topBarSearchResults").innerHTML = ""; 33 | document.getElementById("topBarSearchResults").style.display = "none"; 34 | return; 35 | } 36 | 37 | clearTimeout(debounceTimer); 38 | 39 | debounceTimer = setTimeout(function () { 40 | var xmlhttp = new XMLHttpRequest(); 41 | xmlhttp.onreadystatechange = function () { 42 | if (this.readyState == 4 && this.status == 200) { 43 | document.getElementById("topBarSearchResults").innerHTML = this.responseText; 44 | document.getElementById("topBarSearchResults").style.display = "block"; 45 | } 46 | }; 47 | xmlhttp.open("GET", "/beatmapSearch.php?q=" + str, true); 48 | xmlhttp.send(); 49 | }, 300); 50 | } 51 | 52 | function searchFocus() { 53 | document.getElementById("topBarSearchResults").style.display="block"; 54 | } 55 | 56 | function openTab(name) { 57 | let x = document.getElementsByClassName("tab"); 58 | for (let i = 0; i < x.length; i++) 59 | x[i].style.display = "none"; 60 | 61 | let buttons = document.getElementsByClassName("tabbed-container-nav")[0].getElementsByTagName("button"); 62 | for (let i = 0; i < buttons.length; i++) 63 | buttons[i].classList.remove("active"); 64 | 65 | document.getElementById(name).style.display = "block"; 66 | event.target.classList.add("active"); 67 | } -------------------------------------------------------------------------------- /sensitiveStrings-Example.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /settings/CreateNewApiApp.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM `apikeys` WHERE `UserID` = ?"); 18 | $stmt->bind_param("i", $userId); 19 | $stmt->execute(); 20 | $result = $stmt->get_result(); 21 | 22 | if ($result->num_rows < 5) { 23 | $stmt = $conn->prepare("INSERT INTO `apikeys` (`Name`, `ApiKey`, `UserID`) VALUES (?, ?, ?);"); 24 | $stmt->bind_param("ssi", $name, $apiKey, $userId); 25 | $stmt->execute(); 26 | } 27 | 28 | $stmt->close(); 29 | 30 | header("Location: index.php"); -------------------------------------------------------------------------------- /settings/RemoveApiApp.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM `apikeys` WHERE ApiID = ?;"); 6 | $stmt->bind_param("i", $apiId); 7 | $stmt->execute(); 8 | $result = $stmt->get_result(); 9 | 10 | if($result == null) 11 | die("This API doesn't exist."); 12 | 13 | $row = $result->fetch_assoc(); 14 | $apiOwner = $row["UserID"]; 15 | 16 | if($apiOwner != $userId) 17 | die("You do not own this API!"); 18 | 19 | $stmt = $conn->prepare("DELETE FROM `apikeys` WHERE ApiID = ? AND UserID = ?;"); 20 | $stmt->bind_param("ii", $apiId, $userId); 21 | $stmt->execute(); 22 | $stmt->close(); 23 | 24 | header("Location: index.php?success"); -------------------------------------------------------------------------------- /settings/save.php: -------------------------------------------------------------------------------- 1 | prepare("UPDATE `users` SET `DoTrueRandom`=?, `Custom50Rating`=?, `Custom45Rating`=?, `Custom40Rating`=?, `Custom35Rating`=?, `Custom30Rating`=?, `Custom25Rating`=?, `Custom20Rating`=?, `Custom15Rating`=?, `Custom10Rating`=?, `Custom05Rating`=?, `Custom00Rating`=?, `HideRatings`=?, `CustomDescription`=?, `OnlyFriendsOnFrontPage`=? WHERE `UserID`=?"); 18 | $stmt->bind_param("sssssssssssssssi", $random, $ratingNames[0], $ratingNames[1], $ratingNames[2], $ratingNames[3], $ratingNames[4], $ratingNames[5], $ratingNames[6], $ratingNames[7], $ratingNames[8], $ratingNames[9], $ratingNames[10], $hideRatings, $customDescription, $onlyFriendsOnFrontPage, $userId); 19 | $stmt->execute(); 20 | -------------------------------------------------------------------------------- /test.php: -------------------------------------------------------------------------------- 1 | prepare(" 11 | SELECT d.DescriptorID, d.Name 12 | FROM descriptor_votes 13 | JOIN descriptors d ON descriptor_votes.DescriptorID = d.DescriptorID 14 | WHERE BeatmapID = ? 15 | GROUP BY d.DescriptorID 16 | HAVING SUM(CASE WHEN Vote = 1 THEN 1 ELSE 0 END) > (SUM(CASE WHEN Vote = 0 THEN 1 ELSE 0 END) + 0) 17 | ORDER BY (SUM(CASE WHEN Vote = 1 THEN 1 ELSE 0 END) - SUM(CASE WHEN Vote = 0 THEN 1 ELSE 0 END)) DESC, d.DescriptorID 18 | LIMIT 5; 19 | "); 20 | $stmt->bind_param("i", $beatmapID); 21 | $stmt->execute(); 22 | $result = $stmt->get_result(); 23 | 24 | $descriptorIDs = []; 25 | while ($row = $result->fetch_assoc()) { 26 | $descriptorIDs[] = $row['DescriptorID']; 27 | } 28 | $stmt->close(); 29 | 30 | // Step 2: Find users who rated this BeatmapID highly (e.g., 4 or 5) 31 | $stmt = $conn->prepare(" 32 | SELECT DISTINCT UserID 33 | FROM ratings 34 | WHERE BeatmapID = ? AND Score >= 4 35 | "); 36 | $stmt->bind_param("i", $beatmapID); 37 | $stmt->execute(); 38 | $result = $stmt->get_result(); 39 | 40 | $userIDs = []; 41 | while ($row = $result->fetch_assoc()) { 42 | $userIDs[] = $row['UserID']; 43 | } 44 | $stmt->close(); 45 | 46 | if (empty($userIDs)) { 47 | echo "No recommendations available."; 48 | return; 49 | } 50 | 51 | // Step 3: Find BeatmapIDs that these users also rated highly and compute the recommendation score 52 | $userPlaceholders = implode(',', array_fill(0, count($userIDs), '?')); 53 | $descriptorPlaceholders = implode(',', array_fill(0, count($descriptorIDs), '?')); 54 | $types = str_repeat('i', count($userIDs) + count($descriptorIDs) + 1 + 1 + 1); 55 | 56 | $stmt = $conn->prepare(" 57 | SELECT r.BeatmapID, b.SetID, b.DifficultyName, AVG(r.Score) as AvgScore, COUNT(r.Score) as ScoreCount, 58 | COUNT(DISTINCT dv.DescriptorID) as MatchingDescriptors, 59 | b.Timestamp as BeatmapTimestamp, 60 | ABS(TIMESTAMPDIFF(YEAR, (SELECT Timestamp FROM beatmaps WHERE BeatmapID = ?), b.Timestamp)) AS YearDiff 61 | FROM ratings r 62 | LEFT JOIN beatmaps b ON b.BeatmapID = r.BeatmapID 63 | LEFT JOIN descriptor_votes dv ON dv.BeatmapID = r.BeatmapID AND dv.DescriptorID IN ($descriptorPlaceholders) 64 | WHERE r.UserID IN ($userPlaceholders) 65 | AND r.BeatmapID != ? 66 | GROUP BY r.BeatmapID 67 | HAVING AvgScore >= 4 AND ScoreCount > 15 AND ScoreCount < 80 68 | ORDER BY ( 69 | AVG(r.Score) * 1 + 70 | COUNT(DISTINCT dv.DescriptorID) * 1.5 + 71 | IF(ABS(TIMESTAMPDIFF(YEAR, (SELECT Timestamp FROM beatmaps WHERE BeatmapID = ?), b.Timestamp)) <= 2, 2, 0) 72 | ) DESC 73 | LIMIT 10; 74 | "); 75 | 76 | echo $conn->error; 77 | 78 | // Bind dynamic parameters 79 | $params = array_merge([$beatmapID], $descriptorIDs, $userIDs, [$beatmapID], [$beatmapID]); 80 | $stmt->bind_param($types, ...$params); 81 | $stmt->execute(); 82 | $result = $stmt->get_result(); 83 | 84 | // Step 4: Fetch and print the top 10 recommended BeatmapIDs with their scores 85 | $recommendations = []; 86 | while ($row = $result->fetch_assoc()) { 87 | $recommendations[] = [ 88 | 'SetID' => $row['SetID'], 89 | 'BeatmapID' => $row['BeatmapID'], 90 | 'DifficultyName' => $row['DifficultyName'], 91 | 'AvgScore' => $row['AvgScore'], 92 | 'MatchingDescriptors' => $row['MatchingDescriptors'], 93 | 'YearDiff' => $row['YearDiff'] 94 | ]; 95 | } 96 | $stmt->close(); 97 | 98 | if (empty($recommendations)) { 99 | echo "No recommendations available."; 100 | } else { 101 | echo "Recommendations for BeatmapID $beatmapID:
    "; 102 | foreach ($recommendations as $rec) { 103 | echo $rec['BeatmapID'] . " / {$rec['SetID']}" . " (" . $rec['DifficultyName'] . ") - " . 104 | "Average Score: " . round($rec['AvgScore'], 2) . ", " . 105 | "Matching Descriptors: " . $rec['MatchingDescriptors'] . ", " . 106 | "Year diff: {$rec['YearDiff']}
    "; 107 | } 108 | } 109 | } 110 | 111 | // Example usage 112 | $beatmapID = $_GET['id'] ?? 131891; // Replace with the actual BeatmapID you want recommendations for 113 | getRecommendations($beatmapID, $conn); 114 | ?> 115 | -------------------------------------------------------------------------------- /userConnect.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM `users` WHERE `AccessToken` = ?"); 10 | $stmt->bind_param("s", $token); 11 | $stmt->execute(); 12 | $result = $stmt->get_result(); 13 | 14 | if ($result->num_rows == 1) { 15 | $row = $result->fetch_assoc(); 16 | $loggedIn = true; 17 | $userId = $row['UserID']; 18 | $userName = $row['Username']; 19 | $user = $row; 20 | 21 | // Update the last accessed site column in one-minute limits. 22 | if((time() - strtotime($row['LastAccessedSite'])) > 60){ 23 | $ip = $_SERVER['HTTP_CLIENT_IP'] 24 | ? $_SERVER['HTTP_CLIENT_IP'] 25 | : ($_SERVER['HTTP_X_FORWARDED_FOR'] 26 | ? $_SERVER['HTTP_X_FORWARDED_FOR'] 27 | : $_SERVER['REMOTE_ADDR']); 28 | 29 | $stmt = $conn->prepare("UPDATE `users` SET `LastAccessedSite` = CURRENT_TIMESTAMP, `IpAddress` = ? WHERE `AccessToken` = ?"); 30 | $stmt->bind_param("ss", $ip, $token); 31 | $stmt->execute(); 32 | } 33 | } 34 | } 35 | ?> -------------------------------------------------------------------------------- /users/index.php: -------------------------------------------------------------------------------- 1 | 4 | 5 |

    adfgfadg

    6 | 12 | prepare("SELECT U.userid, U.username, COUNT(R.userid) AS ratings_count FROM users U LEFT JOIN ratings R ON U.userid = R.userid GROUP BY U.userid, U.username ORDER BY ratings_count DESC LIMIT 100;"); 18 | $stmt->execute(); 19 | $result = $stmt->get_result(); 20 | $count = 0; 21 | ?> 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | fetch_assoc()) { 34 | $count += 1; 35 | 36 | $stmt = $conn->prepare("SELECT COUNT(*) as count FROM descriptor_votes WHERE UserID = ?;"); 37 | $stmt->bind_param("i", $row["userid"]); 38 | $stmt->execute(); 39 | $descriptorCount = $stmt->get_result()->fetch_assoc()["count"]; 40 | 41 | $stmt = $conn->prepare("SELECT COUNT(*) as count FROM beatmap_edit_requests WHERE UserID = ? and Status='approved';"); 42 | $stmt->bind_param("i", $row["userid"]); 43 | $stmt->execute(); 44 | $editCount = $stmt->get_result()->fetch_assoc()["count"]; 45 | ?> 46 | 47 | 48 | 53 | 58 | 59 | 60 | 61 | 62 | 63 |
    UsernameRatings CountDescriptor Vote CountEdit Count
    # 49 | "> 50 | " style="height:24px;width:24px;" title=""/> 51 | 52 | 54 | "> 55 | 56 | 57 |
    64 | --------------------------------------------------------------------------------