├── .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 |
--------------------------------------------------------------------------------
/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 |
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 |
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 |
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 |
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 | Name
34 | Title
35 | Difficulty
36 | Date
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 "{$name} ";
57 | echo "{$title} ";
58 | if ($isEditingSet) {
59 | echo "Mapset (general edit) ";
60 | } else {
61 | echo "{$row["DifficultyName"]} ";
62 | }
63 | echo "{$row["Timestamp"]} ";
64 | echo " ";
65 | }
66 | ?>
67 |
68 |
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 |
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 |
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 |
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 |
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 |
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 |
45 | ' . $i . '';
52 | }
53 | ?>
54 |
55 |
56 | ' . DateTime::createFromFormat('!m', $i)->format('F') . '';
63 | }
64 | ?>
65 |
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 |
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 |
98 | Difficulty:
99 |
100 |
101 | Any
102 | prepare("SELECT DifficultyName, BeatmapID FROM beatmaps WHERE `SetID` = ? AND Blacklisted = 0;");
104 | $stmt->bind_param("i", $mapset_id);
105 | $stmt->execute();
106 | $result = $stmt->get_result();
107 |
108 | while($row = $result->fetch_assoc()){
109 | $selectedString = $beatmap_id == $row['BeatmapID'] ? "selected" : "";
110 | $difficultyName = htmlspecialchars(mb_strimwidth($row['DifficultyName'], 0, 40, "..."));
111 | echo "{$difficultyName} ";
112 | }
113 | ?>
114 |
115 |
116 |
117 |
118 | Order:
119 |
120 |
121 | >Date (newest)
122 | >Date (oldest)
123 | >Highest score
124 |
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 |
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 | Latest
44 | Ratings
45 | 0) { ?>
46 | Tags ()
47 |
48 | Stats
49 | 0) { ?>
50 | Lists ()
51 |
52 |
53 | 0) { ?>
54 | >Nominations ()
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 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/profile/tabs/tags.php:
--------------------------------------------------------------------------------
1 |
6 |
7 |
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 | Treat fellow OMDB users with respect.
11 | Avoid actions that disrespects the site's intended functionality (such as manipulating votes in a group, or using multiaccounts).
12 | Do not encourage other users who are engaging in rule-breaking behaviour.
13 |
14 |
Violation of these rules may lead to permanent account suspension.
15 |
16 |
Comments
17 |
18 | Please only use English for your comments to ensure everyone can understand and participate.
19 | Do not post insensitive content. This includes racism, sexism, homophobia and transphobia.
20 | Engage in discussions with respect and courtesy. Disagreements are fine, but avoid personal attacks and insults.
21 | Remember that tastes vary. Be open to different viewpoints and diverse preferences.
22 | Derailing ongoing conversations are not allowed. Do not be disruptive.
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 | Username
28 | Ratings Count
29 | Descriptor Vote Count
30 | Edit Count
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 |
49 | ">
50 | " style="height:24px;width:24px;" title=""/>
51 |
52 |
53 |
54 | ">
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------