├── .env.example ├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── .htaccess ├── .idea ├── php.xml └── vcs.xml ├── .whitesource ├── LICENSE ├── README.md ├── ads.txt ├── composer.json ├── composer.lock ├── cron ├── ReplayCompressor.php ├── autoAccountDelete.php ├── cron.php └── updateUsernames.php ├── css ├── checkboxSwitch.css ├── editProfile.css ├── errorModal.css ├── faq.css ├── footer.css ├── forgotPassword.css ├── index.css ├── loader.css ├── login.css ├── maintenance.css ├── navbar.css ├── patreon.css ├── plyr.css ├── progress.css ├── register.css ├── search.css ├── userProfile.css ├── userVerification.css └── view.css ├── editProfile.php ├── emailVerification.php ├── faq.php ├── forgotPassword.php ├── images ├── add.png ├── arrow_button_left.png ├── arrow_button_right.png ├── background.png ├── background2.png ├── codevirtuel.jpg ├── cross.png ├── cursor.png ├── defaultProfilePicture.png ├── editProfile.png ├── etape1.png ├── etape2.gif ├── etape2.png ├── etape3.png ├── icon.png ├── image credits.txt ├── index │ ├── Discord_logo.png │ ├── github_logo.png │ ├── modal1.png │ ├── modal2.png │ ├── modal3.png │ ├── modal4.png │ ├── modal5.png │ ├── modal6.png │ ├── osu forums.png │ ├── patreon_logo.png │ ├── paypal_me.png │ └── tipeee_logo.png ├── large │ └── index │ │ ├── Discord_logo.png │ │ └── etape1.png ├── loading.gif ├── logo.png ├── medium │ └── index │ │ ├── Discord_logo.png │ │ ├── codevirtuel.jpg │ │ ├── etape1.png │ │ ├── github_logo.png │ │ ├── osu_forums.png │ │ └── paypal_me.png ├── mods │ ├── Autopilot.png │ ├── Autoplay.png │ ├── Cinema.png │ ├── Coop.png │ ├── DoubleTime.png │ ├── Easy.png │ ├── FadeIn.png │ ├── Flashlight.png │ ├── HalfTime.png │ ├── HardRock.png │ ├── Hidden.png │ ├── Key1.png │ ├── Key2.png │ ├── Key3.png │ ├── Key4.png │ ├── Key5.png │ ├── Key6.png │ ├── Key7.png │ ├── Key8.png │ ├── Key9.png │ ├── Mirror.png │ ├── Nightcore.png │ ├── NoFail.png │ ├── None.png │ ├── Perfect.png │ ├── Random.png │ ├── Relax.png │ ├── ScoreV2.png │ ├── SpunOut.png │ ├── SuddenDeath.png │ └── Target.png ├── ok.png ├── osuCTB.png ├── osuMania.png ├── osuStdr.png ├── osuTaiko.png ├── osu_logo.png ├── preview.jpg ├── progress │ ├── green.png │ ├── orange.png │ └── red.png ├── reddit_icon.png ├── small │ └── index │ │ ├── Discord_logo.png │ │ ├── codevirtuel.jpg │ │ ├── etape1.png │ │ ├── github_logo.png │ │ ├── osu_forums.png │ │ └── paypal_me.png ├── tooltips │ └── findOsuId.PNG ├── twitter_icon.png ├── u_icon.png ├── view │ ├── delete_replay.png │ ├── download_beatmap.png │ ├── download_replay.png │ ├── download_skin.png │ ├── peertube_logo.png │ ├── rerecord_replay.png │ ├── video_source.png │ └── youtube_logo.png └── xlarge │ └── index │ └── Discord_logo.png ├── index.php ├── js ├── analytics.js ├── closeErrorModal.js ├── editProfile.js ├── index │ ├── askUsername.js │ ├── upload.js │ └── validateUsername.js ├── loader.js ├── patreon │ └── loadBlocks.js ├── plyr.js ├── profile │ ├── cursorSize.js │ ├── modal.js │ ├── replaySelect.js │ ├── uploadSkin.js │ └── volume.js ├── progress │ └── autoUpload.js ├── request.js └── view │ └── modal.js ├── legal ├── EN │ ├── Terms of use for replay processing - EN.pdf │ └── Terms of use for user accounts - EN.pdf ├── FR │ ├── Termes d'utilisation compte utilisateur FR.pdf │ └── Termes d'utilisation du traitement des replays - FR.pdf └── TU.php ├── lib ├── bootstrap │ ├── bootstrap.bundle.min.js │ ├── bootstrap.bundle.min.js.map │ ├── bootstrap.css │ ├── bootstrap.css.map │ ├── bootstrap.min.css │ └── bootstrap.min.css.map └── jquery │ └── jquery.min.js ├── login.php ├── loginForm.php ├── logout.php ├── maintenance.php ├── package-lock.json ├── package.json ├── patreon.php ├── php.ini ├── php ├── MysqlAgent.php ├── admins.php ├── autoAccountDelete.php ├── disableUploads.php ├── errors.php ├── fillReplayStats.php ├── ftp_agent.class.php ├── getUserId.php ├── getUsername.php ├── index.php ├── index │ ├── UploadLimiter.php │ ├── clearSession.php │ ├── newUsername.php │ ├── replayFileVerf.php │ └── upload.php ├── navbar.php ├── osuApiFunctions.php ├── patreon │ ├── 1_pledgers.txt │ ├── 5_pledgers.txt │ └── getPledgers.php ├── profile │ ├── blockManager.php │ ├── blocks │ │ ├── changeEmail.php │ │ ├── changePassword.php │ │ ├── cursorSizeChooser.php │ │ ├── dimChooser.php │ │ ├── gameSettingsChooser.php │ │ ├── removeAccount.php │ │ ├── replayDatabase.php │ │ ├── replayGraveyard.php │ │ ├── replayPending.php │ │ ├── skinChooser.php │ │ ├── skinRemover.php │ │ ├── skinUploader.php │ │ └── volumeChooser.php │ ├── changeEmail.php │ ├── changePassword.php │ ├── deleteProfile.php │ ├── form_cursorSize.php │ ├── form_gameSettings.php │ ├── form_skinChooser.php │ ├── form_volume.php │ ├── ini.class.php │ ├── iniParser.php │ ├── removeSkin.php │ ├── replaySettings.php │ ├── saveUserIni.php │ ├── uploadSkin.php │ └── verfDeleteProfile.php ├── progress │ ├── cancelReplay.php │ ├── checkUpdate.php │ └── functions.php ├── search │ ├── blockModel.php │ └── queryReplays.php ├── sendVerificationEmail.php ├── server │ ├── generateSecretToken.php │ ├── login.php │ └── userHasAnAccount.php ├── success.php ├── verificationFunctions.php ├── view │ ├── deleteReplay.php │ ├── functions.php │ ├── re_record_replay.php │ └── sendToGraveyard.php └── websiteFunctions.php ├── progress.php ├── register.php ├── search.php ├── sitemap.xml ├── startup.php ├── updateMods.php ├── userProfile.php ├── userVerification.php └── view.php /.env.example: -------------------------------------------------------------------------------- 1 | # General config 2 | DEBUG_VERSION = true #false for production website 3 | UPLOAD_LIMIT_PER_DAY = 5 #Number of replay upload allowed by day for one user 4 | 5 | # FTP (Storage server) 6 | FTP_HOST = "" 7 | FTP_USER = "" 8 | FTP_PASS = "" 9 | FTP_DIR = "" 10 | 11 | # MySQL 12 | MYSQL_HOST = "" 13 | MYSQL_DB = "" 14 | MYSQL_USER = "" 15 | MYSQL_PASS = "" 16 | 17 | # Osu! API 18 | OSU_KEY = "" 19 | 20 | # Patreon API 21 | PATREON_KEY = "" 22 | 23 | # ReCAPTCHA 24 | CAPTCHA_KEY = "" 25 | 26 | # Mail settings 27 | SMTP_HOST = "" 28 | SMTP_PORT = 29 | SMTP_USER = "" 30 | SMTP_PASS = "" 31 | 32 | # Upload key 33 | UPLOAD_REPLAY_KEY = "" #Any random string 34 | 35 | # Sentry.io - leave it empty if your are not using it 36 | # Only used in production mode 37 | SENTRY_URL = "" 38 | 39 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: codevirtuel 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | custom: # Replace with a single custom sponsorship URL 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Link replay/skin or useful file(s)** 38 | 39 | **Additional context** 40 | Add any other context about the problem here. 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.[mp4] 2 | secure/ 3 | test2.php 4 | client_secret.json 5 | client/ 6 | replayList/ 7 | requestList/ 8 | vendor 9 | *.osr 10 | *.osk 11 | *.ini 12 | README.md 13 | googlef02d221e2c7a486e.html 14 | .htaccess 15 | googlef02d221e2c7a486e.html 16 | .htaccess 17 | .scannerwork 18 | .idea 19 | vendor/ 20 | node_modules/ 21 | .env.test 22 | errors.log 23 | /.env 24 | -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | #Change default directory page 2 | DirectoryIndex index.php 3 | 4 | #Prevent viewing of .htaccess file 5 | 6 | order allow,deny 7 | deny from all 8 | 9 | 10 | #AddType application/x-httpd-php .htm .html 11 | Options -Indexes 12 | 13 | #Prevent directory listings 14 | 15 | Allow from all 16 | 17 | 18 | 19 | 20 | mod_gzip_on Yes 21 | mod_gzip_dechunk Yes 22 | mod_gzip_item_include file \.(html?|txt|css|js|php|pl)$ 23 | mod_gzip_item_include mime ^application/x-javascript.* 24 | mod_gzip_item_include mime ^text/.* 25 | mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.* 26 | mod_gzip_item_exclude mime ^image/.* 27 | mod_gzip_item_include handler ^cgi-script$ 28 | 29 | 30 | # Add Caching. 31 | 32 | 33 | Header set Cache-Control "max-age=2592000, public" 34 | 35 | 36 | Header set Cache-Control "max-age=2592000, private" 37 | 38 | 39 | Header set Cache-Control "max-age=7200, public" 40 | 41 | # Disable caching for scripts and other dynamic files 42 | 43 | Header unset Cache-Control 44 | 45 | 46 | 47 | #RewriteEngine On 48 | #RewriteBase / 49 | #RewriteCond %{REMOTE_ADDR} !^90\.12\.17\.114 50 | #RewriteCond %{REQUEST_URI} !^/maintenance\.php$ 51 | #RewriteCond %{REQUEST_URI} !^/client/ 52 | #RewriteCond %{REQUEST_FILENAME} !\.(gif|png|jpg|jpeg|jfif|bmp|css|js)$ [NC] 53 | #RewriteRule ^(.*)$ http://osureplayviewer.xyz/maintenance.php [R=307,L] 54 | -------------------------------------------------------------------------------- /.idea/php.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.whitesource: -------------------------------------------------------------------------------- 1 | { 2 | "checkRunSettings": { 3 | "vulnerableCheckRunConclusionLevel": "failure" 4 | }, 5 | "issueSettings": { 6 | "minSeverityLevel": "LOW" 7 | } 8 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Alexis Poupelin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # osu!replayViewer 2 | 3 | ⚠️ This project is no longer maintained ⚠️ 4 | 5 | Easy to use website. Just upload your .osr, wait for processing and share it to your friends 6 | 7 | [Click here to visit the website](https://osureplayviewer.xyz/) 8 | 9 | ## Getting Started 10 | 11 | * Go the homepage and upload your replay 12 | * Wait some time (depend of the number of requests) 13 | * Check if the processing of your replay is finished (on the search page) 14 | * Open the search page and type your osu! username or ID (you can try with my username) 15 | * Select your replay 16 | * Enjoy 17 | 18 | ## In the future 19 | * Like and view counter 20 | * Report issue for a replay function 21 | * Deploy osu!replayClient. A recording client. 22 | * Page to compare two replays (with graphs and stats) 23 | * Use mirror for beatmaps not available on the osu website 24 | 25 | ## Authors 26 | 27 | * **Ekode** - *Creator of osu!replayViewer* - [osu!profile](https://osu.ppy.sh/users/3481725) - [Github](https://github.com/codevirtuel) 28 | 29 | ## License 30 | 31 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details 32 | 33 | ## Acknowledgments 34 | 35 | * **Darkimmortal** - *Creator of osu!record and inspiration* - [osu!profile](https://osu.ppy.sh/u/10886) - [osu!record](https://osurecord.weeaboo.com) 36 | -------------------------------------------------------------------------------- /ads.txt: -------------------------------------------------------------------------------- 1 | vi.ai, 853789262363088, DIRECT # 41b5eef6 2 | spotxchange.com, 74964, RESELLER, 7842df1d2fe2db34 # 41b5eef6 3 | spotx.tv, 74964, RESELLER, 7842df1d2fe2db34 # 41b5eef6 4 | spotxchange.com, 104684, RESELLER, 7842df1d2fe2db34 # 41b5eef6 5 | spotx.tv, 104684, RESELLER, 7842df1d2fe2db34 # 41b5eef6 6 | spotxchange.com, 122515, RESELLER, 7842df1d2fe2db34 # 41b5eef6 7 | spotx.tv, 122515, RESELLER, 7842df1d2fe2db34 # 41b5eef6 8 | freewheel.tv, 440657, RESELLER # 41b5eef6 9 | freewheel.tv, 440673, RESELLER # 41b5eef6 10 | freewheel.tv, 364193, RESELLER # 41b5eef6 11 | freewheel.tv, 369249, RESELLER # 41b5eef6 12 | smartadserver.com, 2776, RESELLER 13 | pubmatic.com, 156830, RESELLER 14 | advertising.com, 24831, RESELLER 15 | rubiconproject.com, 15476, RESELLER, 0bfd66d529a55807 16 | google.com, pub-5617098146054077, RESELLER, f08c47fec0942fa0 17 | openx.com, 540362347, RESELLER, 6a698e2ec38604c6 -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "platform": { 4 | "php": "7.0" 5 | } 6 | }, 7 | "require-dev": { 8 | "doctrine/instantiator": "1.0.5", 9 | "myclabs/deep-copy": "1.7.0", 10 | "phpdocumentor/reflection-common": "1.0.1", 11 | "phpdocumentor/reflection-docblock": "4.3.0", 12 | "phpdocumentor/type-resolver": "0.4.0", 13 | "phpspec/prophecy": "1.8.0" 14 | }, 15 | "require": { 16 | "phpmailer/phpmailer": "^6.0", 17 | "patreon/patreon": "^0.3.1", 18 | "vlucas/phpdotenv": "^3.5", 19 | "palepurple/rate-limit": "^2.0", 20 | "tedivm/stash": "^0.15.2", 21 | "sentry/sentry": "^1.10", 22 | "phpseclib/phpseclib": "^2.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /cron/ReplayCompressor.php: -------------------------------------------------------------------------------- 1 | ftp_conn = new ftp_agent(); 16 | $this->ftp_conn->connect(); 17 | 18 | //Connect to Mysql 19 | $sql = new MysqlAgent(); 20 | $sql->connect(); 21 | $this->mysql_conn = $sql->getMysqlConn(); 22 | } 23 | 24 | /** 25 | * Generate an array of replays id older than $life_days 26 | * @return array 27 | */ 28 | private function getExpiredReplays(): array 29 | { 30 | $replay_array = array(); 31 | 32 | //Select every replay older than $life_days and not already compressed 33 | $stmt = $this->mysql_conn->prepare("SELECT * FROM replaylist WHERE date < DATE_SUB(now(), INTERVAL ? DAY) AND compressed IS FALSE"); 34 | $stmt->bind_param("i", self::$life_days); 35 | $stmt->execute(); 36 | 37 | //Get results 38 | $result = $stmt->get_result(); 39 | while ($row = $result->fetch_assoc()) { 40 | array_push($replay_array, $row['replayId']); 41 | } 42 | 43 | return $replay_array; 44 | } 45 | 46 | private function getCompressedReplays(): array 47 | { 48 | $replay_array = array(); 49 | 50 | //Select every replay older than $life_days and not already compressed 51 | $stmt = $this->mysql_conn->prepare("SELECT * FROM replaylist WHERE compressed IS TRUE"); 52 | $stmt->execute(); 53 | 54 | //Get results 55 | $result = $stmt->get_result(); 56 | while ($row = $result->fetch_assoc()) { 57 | array_push($replay_array, $row['replayId']); 58 | } 59 | 60 | return $replay_array; 61 | } 62 | 63 | private function setCompressedStatus(String $replayId, bool $compressed) 64 | { 65 | //Set this replay as "compressed" (or not) in the database 66 | $stmt = $this->mysql_conn->prepare("UPDATE replaylist SET compressed = ? WHERE replayId = ?"); 67 | $stmt->bind_param("is", $compressed, $replayId); 68 | $stmt->execute(); 69 | } 70 | 71 | /** 72 | * Compress a replay by deleting videos and keeping only the .osr and .osk 73 | * @param String $replayId 74 | */ 75 | public function compressReplay(String $replayId) 76 | { 77 | //Fetch and delete every .mp4 in the replay folder 78 | $files = $this->ftp_conn->listFiles($replayId); 79 | 80 | foreach ($files as $file) { 81 | if (preg_match('/\.mp4$/i', $file['name'])) { 82 | $this->ftp_conn->removeFile($replayId . '/' . $file['name']); 83 | sleep(0.02); 84 | } 85 | } 86 | 87 | //Set this replay as "compressed" in the database 88 | $this->setCompressedStatus($replayId, true); 89 | } 90 | 91 | /** 92 | * Compress an array of replays 93 | * @param array $replays 94 | */ 95 | public function compressReplays(array $replays) 96 | { 97 | foreach ($replays as $replay) { 98 | $this->compressReplay($replay); 99 | } 100 | } 101 | 102 | public function compressExpiredReplays() 103 | { 104 | $replays = $this->getExpiredReplays(); 105 | foreach ($replays as $replay) { 106 | $this->compressReplay($replay); 107 | } 108 | } 109 | 110 | private function hasVideo($replayId) 111 | { 112 | $files = $this->ftp_conn->listFiles($replayId); 113 | 114 | foreach ($files as $file) { 115 | if (preg_match('/\.mp4$/i', $file)) { 116 | return $replayId . '/' . $file; 117 | } 118 | } 119 | } 120 | 121 | public function removeVideos() 122 | { 123 | $compressedReplays = $this->getCompressedReplays(); 124 | foreach ($compressedReplays as $replay) { 125 | $video = $this->hasVideo($replay); 126 | if (!empty($video)) { 127 | var_dump($video); 128 | echo "Deleting videos from replayId : " . $replay . "
"; 129 | $this->ftp_conn->removeFile($video); 130 | sleep(0.02); 131 | } 132 | 133 | } 134 | } 135 | } -------------------------------------------------------------------------------- /cron/autoAccountDelete.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM accounts WHERE date < DATE_SUB(now(), INTERVAL '$timeLimit' DAY) AND verificationId<>\"\" AND verfIdEmail<>\"\" "); 8 | $query->execute(); 9 | $result = $query->get_result(); 10 | while ($row = $result->fetch_assoc()) { 11 | $userId = $row["userId"]; 12 | array_push($array,$userId); 13 | } 14 | $query->close(); 15 | return $array; 16 | } 17 | 18 | function deleteAccount($conn,$userId){ 19 | //detete account from database 20 | $query = $conn->prepare("DELETE FROM accounts WHERE userId=?"); 21 | $query->bind_param("i",$userId); 22 | $query->execute(); 23 | $query->close(); 24 | 25 | //TODO delete account folder form server 26 | } 27 | 28 | function cleanFolder($dir){ 29 | //delete all folder files 30 | $files = glob($dir."/*"); // get all file names 31 | foreach($files as $file){ // iterate files 32 | if(is_file($file)){ 33 | unlink($file); // delete file 34 | } 35 | } 36 | } 37 | 38 | function removeFolder($dir){ 39 | cleanFolder($dir); 40 | //delete folder 41 | rmdir($dir); 42 | } 43 | ?> 44 | -------------------------------------------------------------------------------- /cron/cron.php: -------------------------------------------------------------------------------- 1 | connect_error) { 17 | die("Connection failed: " . $conn->connect_error); 18 | } 19 | 20 | //FTP 21 | $conn_id = ftp_connect(getenv('FTP_HOST')); 22 | $login_result = ftp_login($conn_id, getenv('FTP_USER'), getenv('FTP_PASS')); 23 | 24 | 25 | // check connection 26 | if ((!$conn_id) || (!$login_result)) { 27 | die("FTP connection has failed !"); 28 | } 29 | 30 | if (ftp_chdir($conn_id, getenv('FTP_DIR'))) { 31 | echo "Current directory is now: " . ftp_pwd($conn_id) . "
"; 32 | } else { 33 | echo "Couldn't change directory
"; 34 | } 35 | 36 | // --- Functions 37 | function cleanRemoteFolder($dir, $conn_id) 38 | { 39 | //delete all folder files 40 | $files = ftp_nlist($conn_id, "./" . $dir); // get all file names 41 | foreach ($files as $file) { // iterate files 42 | if (is_file($file)) { 43 | ftp_delete($conn_id, $file); 44 | } 45 | } 46 | } 47 | 48 | function removeRemoteFolder($dir, $conn_id) 49 | { 50 | cleanRemoteFolder($dir, $conn_id); 51 | //delete folder 52 | ftp_rmdir($conn_id, $dir); 53 | } 54 | 55 | function cleanRequestFolder($conn) 56 | { 57 | $array = array(); 58 | 59 | $result = $conn->query("SELECT * FROM requestlist"); 60 | while ($row = $result->fetch_assoc()) { 61 | $replayId = $row['replayId']; 62 | array_push($array, $replayId); 63 | } 64 | 65 | $folders = scandir("../requestList/"); 66 | foreach ($folders as $folder) { 67 | if (!in_array($folder, $array) && $folder != "." && $folder != "..") { 68 | removeFolder("../requestList/" . $folder); 69 | } 70 | } 71 | } 72 | 73 | function cleanReplayFolder($conn, $conn_id) 74 | { 75 | $array = array(); 76 | 77 | $result = $conn->query("SELECT * FROM replaylist"); 78 | while ($row = $result->fetch_assoc()) { 79 | $replayId = $row['replayId']; 80 | array_push($array, $replayId); 81 | } 82 | 83 | $folders = ftp_nlist($conn_id, "."); 84 | foreach ($folders as $folder) { 85 | if (!in_array($folder, $array) && $folder != "." && $folder != "..") { 86 | removeRemoteFolder($folder, $conn_id); 87 | } 88 | } 89 | } 90 | 91 | echo "==== Deleting account with register time expired ====
"; 92 | 93 | $accountsToRemove = getRemovableAccounts($conn,$timeLimit); 94 | if(!empty($accountsToRemove)){ 95 | foreach($accountsToRemove as $userId){ 96 | deleteAccount($conn,$userId); 97 | echo 'Deleted account with id '.$userId.'
'; 98 | } 99 | }else{ 100 | echo 'No account to delete'; 101 | } 102 | 103 | echo "==== Deleting replays expired ====
"; 104 | 105 | $compressor = new ReplayCompressor(); 106 | $compressor->compressExpiredReplays(); 107 | $compressor->removeVideos(); 108 | 109 | echo "==== Clean database ====
"; 110 | 111 | echo "==== Clean filesystem ====
"; 112 | cleanRequestFolder($conn); 113 | //cleanReplayFolder($conn, $conn_id); 114 | 115 | 116 | -------------------------------------------------------------------------------- /cron/updateUsernames.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/cron/updateUsernames.php -------------------------------------------------------------------------------- /css/checkboxSwitch.css: -------------------------------------------------------------------------------- 1 | /* The switch - the box around the slider */ 2 | .switch_check { 3 | position: relative; 4 | display: inline-block; 5 | width: 60px; 6 | height: 34px; 7 | } 8 | 9 | /* Hide default HTML checkbox */ 10 | .switch_check input { 11 | opacity: 0; 12 | width: 0; 13 | height: 0; 14 | } 15 | 16 | /* The slider */ 17 | .slider_check { 18 | position: absolute; 19 | cursor: pointer; 20 | top: 0; 21 | left: 0; 22 | right: 0; 23 | bottom: 0; 24 | background-color: #ccc; 25 | -webkit-transition: .4s; 26 | transition: .4s; 27 | } 28 | 29 | .slider_check:before { 30 | position: absolute; 31 | content: ""; 32 | height: 26px; 33 | width: 26px; 34 | left: 4px; 35 | bottom: 4px; 36 | background-color: white; 37 | -webkit-transition: .4s; 38 | transition: .4s; 39 | } 40 | 41 | input:checked + .slider_check { 42 | background-color: #2196F3; 43 | } 44 | 45 | input:focus + .slider_check { 46 | box-shadow: 0 0 1px #2196F3; 47 | } 48 | 49 | input:checked + .slider_check:before { 50 | -webkit-transform: translateX(26px); 51 | -ms-transform: translateX(26px); 52 | transform: translateX(26px); 53 | } 54 | 55 | /* Rounded sliders */ 56 | .slider_check.round { 57 | border-radius: 34px; 58 | } 59 | 60 | .slider_check.round:before { 61 | border-radius: 50%; 62 | } -------------------------------------------------------------------------------- /css/errorModal.css: -------------------------------------------------------------------------------- 1 | .modal-error { 2 | display:inline-block; /* Hidden by default */ 3 | position: fixed; /* Stay in place */ 4 | z-index: 1000000; /* Sit on top */ 5 | left: 0; 6 | top: 0; 7 | width: 100vw; /* Full width */ 8 | height: 100vh; /* Full height */ 9 | overflow: auto; /* Enable scroll if needed */ 10 | background-color: rgb(0,0,0); /* Fallback color */ 11 | background-color: rgba(0,0,0,0.4); /* Black w/ opacity */ 12 | overflow-y: auto; 13 | } 14 | 15 | /* Modal Content/Box */ 16 | .modal-content-error { 17 | border-radius: 5vw; 18 | padding-top: 2vh; 19 | padding-bottom: 2vh; 20 | background-color: #fefefe; 21 | margin: 5% auto; /* 15% from the top and centered */ 22 | margin-top: 20vh; 23 | border: 1px solid #888; 24 | width: 80vw; /* Could be more or less, depending on screen size */ 25 | 26 | text-align: center; 27 | } 28 | 29 | /* The Close Button */ 30 | .close-error { 31 | margin-top: 2%; 32 | color: #aaa; 33 | font-size: 2em; 34 | font-weight: bold; 35 | } 36 | 37 | .close-error:hover, 38 | .close-error:focus { 39 | color: black; 40 | text-decoration: none; 41 | cursor: pointer; 42 | } 43 | 44 | .modal-content-error h2{ 45 | font-size: 3em; 46 | color: red; 47 | text-shadow: 3px 3px pink; 48 | margin-bottom: 1%; 49 | } 50 | 51 | .modal-content-error span{ 52 | font-size: 1.5em; 53 | } 54 | 55 | #errorModal{ 56 | margin-bottom: 1%; 57 | font-size: 1.5em; 58 | } 59 | -------------------------------------------------------------------------------- /css/faq.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | background-image: url("../images/background.png"); 8 | padding-top: 20vh; 9 | font-family: "Verdana"; 10 | } 11 | 12 | .align_center{ 13 | text-align: center; 14 | } 15 | 16 | #title{ 17 | text-align:center; 18 | color:#FF66AA; 19 | text-shadow: 3px 3px white; 20 | margin-bottom: 3%; 21 | } 22 | 23 | /*text*/ 24 | .question{ 25 | margin-left: 4%; 26 | margin-right: 4%; 27 | margin-bottom: 4%; 28 | } 29 | 30 | .question_title{ 31 | margin-bottom: 2%; 32 | color:#FF66AA; 33 | text-shadow: 1px 1px gray; 34 | font-size: 130%; 35 | } 36 | 37 | .question_text{ 38 | text-align: justify; 39 | font-size: 110%; 40 | } 41 | 42 | .mail{ 43 | text-align: center; 44 | background-color: lightgray; 45 | padding:2%; 46 | margin-left: 20%; 47 | margin-right: 20%; 48 | border-radius: 100px; 49 | } 50 | 51 | @media only screen and (max-width: 1080px) and (orientation: portrait){ 52 | .mail{ 53 | margin-left: 4%; 54 | margin-right: 4%; 55 | font-size: 100%; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /css/footer.css: -------------------------------------------------------------------------------- 1 | /* FOOTER */ 2 | body{ 3 | position: relative; 4 | padding-bottom: 30rem; 5 | min-height: 100%; 6 | } 7 | 8 | footer{ 9 | background-image: url("../images/background2.png"); 10 | border-top: solid #FF66AA 10px; 11 | padding-bottom: 5%; 12 | position: absolute; 13 | right: 0; 14 | bottom: 0; 15 | left: 0; 16 | width:100%; 17 | /*padding: 1rem;*/ 18 | } 19 | 20 | footer h3{ 21 | margin-top: 2%; 22 | color: lightgray; 23 | } 24 | 25 | footer img{ 26 | height: 15vh; 27 | } 28 | 29 | footer a{ 30 | text-decoration: none; 31 | } 32 | 33 | footer a:hover{ 34 | opacity: 0.6; 35 | } 36 | 37 | .footer_img{ 38 | margin-top: 2%; 39 | text-align: center; 40 | } 41 | 42 | #created{ 43 | color: lightgray; 44 | text-align: right; 45 | font-size: 90%; 46 | margin-right: 2%; 47 | } 48 | 49 | #created img{ 50 | vertical-align:middle; 51 | height: 10vh; 52 | border-radius: 100%; 53 | border: solid white 2px; 54 | } 55 | 56 | .spacer{ 57 | height: 80vh; 58 | /*background-color: red;*/ 59 | } 60 | 61 | /* Mobiles */ 62 | @media only screen and (max-width: 1080px) and (orientation: portrait){ 63 | footer img{ 64 | height: 10vh; 65 | } 66 | footer h3{ 67 | font-size: 3vw; 68 | } 69 | #created{ 70 | font-size: 2vw; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /css/forgotPassword.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | background-image: url("../images/background.png"); 8 | padding-top: 20vh; 9 | font-family: "Verdana"; 10 | } 11 | 12 | .align_center{ 13 | text-align: center; 14 | } 15 | 16 | #title{ 17 | text-align: center; 18 | color:#FF66AA; 19 | text-shadow: 3px 3px white; 20 | margin-bottom: 3%; 21 | } 22 | 23 | h1{ 24 | text-align: center; 25 | } 26 | 27 | h2{ 28 | font-size: 150%; 29 | } 30 | 31 | .block { 32 | display: block; 33 | margin:auto; 34 | margin-left: 10%; 35 | margin-right: 10%; 36 | /*background-color: rgba(150, 150, 150, .5);*/ 37 | border-radius:50px; 38 | text-align: center; 39 | } 40 | 41 | #block{ 42 | padding-top: 5%; 43 | padding-bottom: 5%; 44 | margin-bottom:2%; 45 | } 46 | 47 | .back{ 48 | height:70px; 49 | margin-right: 1%; 50 | position: sticky; 51 | right: 0; 52 | top: 0; 53 | } 54 | 55 | input[type='email'] { 56 | width: 80%; 57 | padding: 12px 20px; 58 | margin: 8px 0; 59 | margin-top: 5vh; 60 | display: inline-block; 61 | border: 1px solid #ccc; 62 | box-sizing: border-box; 63 | } 64 | 65 | input[type="submit"] { 66 | background-color: #4CAF50; 67 | color: white; 68 | padding: 14px 20px; 69 | margin: 8px 0; 70 | border: none; 71 | cursor: pointer; 72 | width: 80%; 73 | } 74 | 75 | /* Add a hover effect for buttons */ 76 | input[type="submit"]:hover { 77 | opacity: 0.8; 78 | } 79 | -------------------------------------------------------------------------------- /css/loader.css: -------------------------------------------------------------------------------- 1 | /* Loader */ 2 | .loaderCustom { 3 | position: fixed; 4 | left: 0px; 5 | top: 0px; 6 | width: 100%; 7 | height: 100%; 8 | z-index: 9999; 9 | background: url('../images/loading.gif') 50% 50% no-repeat rgb(249,249,249); 10 | opacity: .8; 11 | } 12 | -------------------------------------------------------------------------------- /css/login.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | background-image: url("../images/background.png"); 8 | /*padding-bottom:5%;*/ 9 | padding-top: 20vh; 10 | font-family: "Verdana"; 11 | } 12 | 13 | .align_center{ 14 | text-align: center; 15 | } 16 | 17 | #title{ 18 | text-align: center; 19 | color:#FF66AA; 20 | text-shadow: 3px 3px white; 21 | margin-bottom: 3%; 22 | } 23 | 24 | /* Bordered form */ 25 | form { 26 | /*border: 3px solid #f1f1f1;*/ 27 | width:50vw; 28 | margin:auto; 29 | } 30 | 31 | b{ 32 | font-family: "Verdana"; 33 | font-size: 100%; 34 | } 35 | 36 | /* Full-width inputs */ 37 | input[type=text], input[type=password] { 38 | width: 100%; 39 | padding: 12px 20px; 40 | margin: 8px 0; 41 | display: inline-block; 42 | border: 1px solid #ccc; 43 | box-sizing: border-box; 44 | } 45 | 46 | /* Set a style for all buttons */ 47 | button { 48 | background-color: #4CAF50; 49 | color: white; 50 | padding: 14px 20px; 51 | margin: 8px 0; 52 | border: none; 53 | cursor: pointer; 54 | width: 100%; 55 | } 56 | 57 | /* Add a hover effect for buttons */ 58 | button:hover { 59 | opacity: 0.8; 60 | } 61 | 62 | /* Extra style for the cancel button (red) */ 63 | .cancelbtn { 64 | width: auto; 65 | padding: 10px 18px; 66 | background-color: #f44336; 67 | } 68 | 69 | /* Center the avatar image inside this container */ 70 | .imgcontainer { 71 | text-align: center; 72 | margin: 24px 0 12px 0; 73 | } 74 | 75 | /* Avatar image */ 76 | img.avatar { 77 | width:20%; 78 | border-radius: 50%; 79 | } 80 | 81 | /* Add padding to containers */ 82 | .container { 83 | padding: 16px; 84 | } 85 | 86 | /* The "Forgot password" text */ 87 | span.psw { 88 | float: right; 89 | padding-top: 16px; 90 | } 91 | 92 | /* Change styles for span and cancel button on extra small screens */ 93 | @media screen and (max-width: 300px) { 94 | span.psw { 95 | display: block; 96 | float: none; 97 | } 98 | .cancelbtn { 99 | width: 100%; 100 | } 101 | } 102 | 103 | .errorText{ 104 | color:red; 105 | font-family: "Verdana"; 106 | } 107 | 108 | /* Tooltip container */ 109 | .tooltip { 110 | position: relative; 111 | display: inline-block; 112 | border-bottom: 1px dotted black; /* If you want dots under the hoverable text */ 113 | } 114 | 115 | /* Tooltip text */ 116 | .tooltip .tooltiptext { 117 | visibility: hidden; 118 | width: 250px; 119 | background-color: #555; 120 | color: #fff; 121 | text-align: center; 122 | padding: 5px 0; 123 | border-radius: 6px; 124 | 125 | /* Position the tooltip text */ 126 | position: absolute; 127 | z-index: 1; 128 | bottom: 125%; 129 | left: 50%; 130 | margin-left: -60px; 131 | 132 | /* Fade in tooltip */ 133 | opacity: 0; 134 | transition: opacity 0.3s; 135 | } 136 | 137 | /* Tooltip arrow */ 138 | .tooltip .tooltiptext::after { 139 | content: ""; 140 | position: absolute; 141 | top: 100%; 142 | left: 50%; 143 | margin-left: -5px; 144 | border-width: 5px; 145 | border-style: solid; 146 | border-color: #555 transparent transparent transparent; 147 | } 148 | 149 | /* Show the tooltip text when you mouse over the tooltip container */ 150 | .tooltip:hover .tooltiptext { 151 | visibility: visible; 152 | opacity: 1; 153 | } 154 | 155 | @media only screen and (orientation: portrait){ 156 | 157 | form { 158 | margin:auto; 159 | width:80vw; 160 | } 161 | 162 | b{ 163 | font-size: 4vw; 164 | } 165 | 166 | #title{ 167 | font-size: 5vw; 168 | } 169 | 170 | input[type=text], input[type=password] { 171 | /*font-size: 4vw;*/ 172 | font-size: 4vw; 173 | } 174 | 175 | button { 176 | font-size: 4vw; 177 | } 178 | 179 | .psw{ 180 | font-size: 3vw; 181 | } 182 | .g-recaptcha{ 183 | transform:scale(0.88); 184 | transform-origin:0 0; 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /css/maintenance.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-image: url("../images/background.png"); 3 | } 4 | 5 | p{ 6 | display:block; 7 | font-family:"Verdana"; 8 | width:50%; 9 | height:10%; 10 | margin:auto; 11 | padding:1% 1% 1% 1%; 12 | background-color: rgba(150, 150, 150, .5); 13 | text-align:center; 14 | font-size:150%; 15 | border-radius:50px; 16 | } 17 | 18 | p img{ 19 | margin-top:5%; 20 | border-radius:50px; 21 | border-color:black; 22 | border-style: solid; 23 | border-width: 5px; 24 | } -------------------------------------------------------------------------------- /css/navbar.css: -------------------------------------------------------------------------------- 1 | /*Top navigation bar*/ 2 | .top-nav{ 3 | z-index: 1000; 4 | font-family: "Verdana"; 5 | position:fixed; 6 | top:0; 7 | display:flex; 8 | overflow:visible; 9 | height:6rem; 10 | width:100%; 11 | justify-content: center; 12 | align-items:center; 13 | background-color: #FF66AA; 14 | border-bottom:solid white 10px; 15 | } 16 | 17 | .nav-link{ 18 | padding: 14px 16px; 19 | display:inline-block; 20 | width:15vw; 21 | text-align: center; 22 | color: white; 23 | text-decoration: none; 24 | font-size: 3vh; 25 | border-radius:100px; 26 | align-items:center; 27 | } 28 | 29 | .top-nav a:hover { 30 | background-color: #FFB2D4; 31 | } 32 | 33 | #logo:hover { 34 | opacity: 0.9; 35 | } 36 | 37 | #logo img{ 38 | width: 20vh; 39 | } 40 | 41 | #logo{ 42 | margin-top: 4%; 43 | border-radius:50%; 44 | } 45 | 46 | .floatleft { 47 | float:left; 48 | } 49 | .floatright { 50 | float:right; 51 | } 52 | 53 | .active{ 54 | background-color: #FFB2D4; 55 | } 56 | 57 | /* Mobiles */ 58 | @media only screen and (max-width: 1080px) and (orientation: portrait){ 59 | [class*="floatright"] { 60 | float:left; 61 | } 62 | [class*="top-nav"] { 63 | align-items: center; 64 | height:15vw; 65 | } 66 | [class*="nav-link"] { 67 | font-size: 0; 68 | padding-left:2vw; 69 | padding-right:2vw; 70 | padding-top: 1vh; 71 | padding-bottom: 1vh; 72 | width:10vw; 73 | } 74 | [class*="nav-link"] i{ 75 | font-size: 7vw; 76 | } 77 | #logo{ 78 | margin-top: 10%; 79 | margin-left: 2vw; 80 | margin-right: 2vw; 81 | } 82 | } 83 | 84 | @media only screen and (max-width: 1080px) and (orientation: landscape){ 85 | [class*="top-nav"] { 86 | height:15vh; 87 | } 88 | } 89 | 90 | @media only screen and (max-height:200px){ 91 | .top-nav{ 92 | display: none; 93 | } 94 | } 95 | 96 | @media only screen and (max-width:200px){ 97 | .top-nav{ 98 | display: none; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /css/patreon.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | background-image: url("../images/background.png"); 8 | /*padding-bottom:5%;*/ 9 | padding-top: 20vh; 10 | font-family: "Verdana"; 11 | } 12 | 13 | i { 14 | height: 3vh; 15 | color: white; 16 | text-align:center; 17 | } 18 | 19 | h2, h1 { 20 | font-weight: bold; 21 | } 22 | 23 | /* Presentation */ 24 | #title{ 25 | text-align: center; 26 | color:#FF66AA; 27 | text-shadow: 3px 3px white; 28 | margin-bottom: 3%; 29 | } 30 | 31 | #slogan{ 32 | text-align:center; 33 | font-size: 3vw; 34 | color: #CC5288; 35 | text-shadow: 3px 3px white; 36 | margin-bottom: 3%; 37 | } 38 | 39 | .align_center{ 40 | text-align:center; 41 | } 42 | 43 | /* Tier block */ 44 | #tier_block{ 45 | background-color: white; 46 | border: 2px solid rgb(231, 113, 166); 47 | padding-top: 1%; 48 | padding-bottom: 1%; 49 | margin-bottom: 1%; 50 | } 51 | 52 | #join_block_button{ 53 | text-align: right; 54 | } 55 | 56 | #join_block_button button{ 57 | width: 100%; 58 | font-size: 1.1vw; 59 | } 60 | 61 | @media only screen and (max-width: 1080px) and (orientation: portrait){ 62 | #join_block_button button{ 63 | display: none; 64 | } 65 | } -------------------------------------------------------------------------------- /css/register.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | background-image: url("../images/background.png"); 8 | /*padding-bottom:5%;*/ 9 | padding-top: 20vh; 10 | font-family: "Verdana"; 11 | } 12 | 13 | #title{ 14 | text-align:center; 15 | color:#FF66AA; 16 | text-shadow: 3px 3px white; 17 | margin-bottom: 3%; 18 | } 19 | 20 | form { 21 | margin-top: 3%; 22 | margin-left: 20%; 23 | margin-right: 20%; 24 | } 25 | 26 | input[type=number], input[type=password], input[type=email] { 27 | width: 100%; 28 | padding: 12px 20px; 29 | margin: 8px 0; 30 | display: inline-block; 31 | border: 1px solid #ccc; 32 | box-sizing: border-box; 33 | } 34 | 35 | button { 36 | background-color: #4CAF50; 37 | color: white; 38 | padding: 14px 20px; 39 | margin: 8px 0; 40 | border: none; 41 | cursor: pointer; 42 | width: 100%; 43 | } 44 | 45 | button:hover { 46 | opacity: 0.8; 47 | } 48 | 49 | #recaptcha{ 50 | width: auto; 51 | margin:auto; 52 | } 53 | 54 | input[type=checkbox]{ 55 | transform: scale(2); 56 | margin-top: 1%; 57 | margin-bottom: 3%; 58 | margin-left: 1%; 59 | } 60 | 61 | #textCheckBox{ 62 | padding-left: 2%; 63 | font-size: 1em; 64 | } 65 | 66 | label{ 67 | font-weight: bold; 68 | font-family: "verdana"; 69 | } 70 | 71 | span{ 72 | font-family: "verdana"; 73 | margin-bottom: 5%; 74 | } 75 | 76 | h3{ 77 | font-family: "verdana"; 78 | text-align: center; 79 | } 80 | 81 | p{ 82 | color : red; 83 | text-align: center; 84 | font-weight: bold; 85 | font-family: "verdana"; 86 | } 87 | 88 | /* Tooltip container */ 89 | .tooltip { 90 | position: relative; 91 | display: inline-block; 92 | border-bottom: 1px dotted black; /* If you want dots under the hoverable text */ 93 | } 94 | 95 | /* Tooltip text */ 96 | .tooltip .tooltiptext { 97 | visibility: hidden; 98 | width: 250px; 99 | background-color: #555; 100 | color: #fff; 101 | text-align: center; 102 | padding: 5px 0; 103 | border-radius: 6px; 104 | 105 | /* Position the tooltip text */ 106 | position: absolute; 107 | z-index: 1; 108 | bottom: 125%; 109 | left: 50%; 110 | margin-left: -60px; 111 | 112 | /* Fade in tooltip */ 113 | opacity: 0; 114 | transition: opacity 0.3s; 115 | } 116 | 117 | /* Tooltip arrow */ 118 | .tooltip .tooltiptext::after { 119 | content: ""; 120 | position: absolute; 121 | top: 100%; 122 | left: 50%; 123 | margin-left: -5px; 124 | border-width: 5px; 125 | border-style: solid; 126 | border-color: #555 transparent transparent transparent; 127 | } 128 | 129 | /* Show the tooltip text when you mouse over the tooltip container */ 130 | .tooltip:hover .tooltiptext { 131 | visibility: visible; 132 | opacity: 1; 133 | } 134 | 135 | /* Mobile */ 136 | @media only screen and (orientation: portrait){ 137 | h3{ 138 | font-size: 4vw; 139 | } 140 | 141 | form{ 142 | margin-top: 2%; 143 | margin-left: 10%; 144 | margin-right: 10%; 145 | } 146 | 147 | label{ 148 | font-size: 4vw; 149 | } 150 | 151 | #title{ 152 | font-size: 5vw; 153 | } 154 | 155 | input[type=number], input[type=password], input[type=email] { 156 | margin:auto; 157 | font-size: 4vw; 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /css/search.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | background-image: url("../images/background.png"); 8 | padding-top: 20vh; 9 | font-family: "Verdana"; 10 | height:100%; 11 | position: relative; 12 | } 13 | 14 | /* Others */ 15 | 16 | .align_center{ 17 | text-align: center; 18 | } 19 | 20 | /* Presentation */ 21 | #title{ 22 | text-align: center; 23 | color:#FF66AA; 24 | text-shadow: 3px 3px white; 25 | margin-bottom: 2%; 26 | } 27 | 28 | #form{ 29 | display:block; 30 | margin:auto; 31 | margin-left:27%; 32 | margin-right:27%; 33 | padding:1% 1% 1% 1%; 34 | text-align:center; 35 | font-family:"Verdana"; 36 | font-size:20px; 37 | border-radius:50px; 38 | } 39 | 40 | input[type="search"]{ 41 | vertical-align: middle; 42 | width:20vw; 43 | height:5vh; 44 | text-align:center; 45 | font-size: 110%; 46 | } 47 | 48 | input[type="submit"]{ 49 | height: 6vh; 50 | width: 6vw; 51 | } 52 | 53 | .content { 54 | display:block; 55 | width: 80vw; 56 | height:15vh; 57 | margin:auto; 58 | margin-top:1%; 59 | padding:1% 1% 1% 1%; 60 | background-color: rgba(150, 150, 150, .5); 61 | border-radius:50px; 62 | font-family:"Verdana"; 63 | text-decoration: none; 64 | color:black; 65 | } 66 | 67 | .content img { 68 | margin-right: 3%; 69 | float: left; 70 | height:15vh; 71 | border-radius:50px; 72 | } 73 | 74 | #alignRight{ 75 | float : right; 76 | } 77 | 78 | .content:hover{ 79 | background-color: rgba(150, 150, 150, .7); 80 | } 81 | 82 | .requestContent { 83 | display:block; 84 | width: 60%; 85 | height:15vh; 86 | margin:auto; 87 | margin-top:1%; 88 | padding:1% 1% 1% 1%; 89 | background-color: rgba(150, 150, 150, .5); 90 | border-radius:50px; 91 | font-family:"Verdana"; 92 | text-decoration: none; 93 | color:black; 94 | } 95 | 96 | .requestContent img { 97 | margin-right: 3%; 98 | float: left; 99 | height:15vh; 100 | border-radius:50px; 101 | } 102 | 103 | .requestContent:hover{ 104 | background-color: rgba(150, 150, 150, .7); 105 | } 106 | 107 | #anim img { 108 | -webkit-transition: all 1s ease; /* Safari and Chrome */ 109 | -moz-transition: all 1s ease; /* Firefox */ 110 | -o-transition: all 1s ease; /* IE 9 */ 111 | -ms-transition: all 1s ease; /* Opera */ 112 | transition: all 1s ease; 113 | max-width: 100%; 114 | } 115 | .content:hover #anim img { 116 | -webkit-transform:scale(1.25); /* Safari and Chrome */ 117 | -moz-transform:scale(1.25); /* Firefox */ 118 | -ms-transform:scale(1.25); /* IE 9 */ 119 | -o-transform:scale(1.25); /* Opera */ 120 | transform:scale(1.25); 121 | } 122 | 123 | .rotate90 { 124 | -webkit-transform: rotate(180deg); 125 | -moz-transform: rotate(180deg); 126 | -o-transform: rotate(180deg); 127 | -ms-transform: rotate(180deg); 128 | transform: rotate(180deg); 129 | } 130 | 131 | #anim { 132 | margin-right: 3%; 133 | overflow: hidden; 134 | float: left; 135 | height:15vh; 136 | border-radius:50px; 137 | } 138 | 139 | .img-valign { 140 | vertical-align: middle; 141 | margin-bottom: 0.75em; 142 | } 143 | 144 | .div-align { 145 | display: table; 146 | margin:0 auto; 147 | font-family:"Verdana"; 148 | font-size:30px; 149 | margin-top:2%; 150 | } 151 | 152 | #placeholder{ 153 | margin-bottom: 10%; 154 | } 155 | 156 | #beatmap_name{ 157 | font-weight: bold; 158 | font-size: 1.5vw; 159 | color:black; 160 | text-shadow: 1px 1px lightgray; 161 | margin-bottom: 1%; 162 | } 163 | 164 | #block_content{ 165 | font-size: 1vw; 166 | } 167 | 168 | #score{ 169 | float:right; 170 | } 171 | 172 | /* Mobiles */ 173 | @media only screen and (max-width: 1080px) and (orientation: portrait){ 174 | /* Search bar */ 175 | input[type="text"]{ 176 | width:30vw; 177 | padding-left: 20px; 178 | height:5vh; 179 | font-size: 3vw; 180 | } 181 | 182 | input[type="submit"]{ 183 | height: 5vh; 184 | width: 15vw; 185 | font-size: 2vw; 186 | } 187 | 188 | #form{ 189 | margin-left:0%; 190 | margin-right:0%; 191 | } 192 | 193 | /*Result box */ 194 | .content img { 195 | height:10vh; 196 | } 197 | 198 | .content { 199 | height:10vh; 200 | } 201 | 202 | #anim { 203 | height:10vh; 204 | } 205 | 206 | /*Request boxes*/ 207 | .requestContent { 208 | height:10vh; 209 | } 210 | 211 | .requestContent img { 212 | height:10vh; 213 | } 214 | 215 | #block_content{ 216 | font-size: 2vw; 217 | } 218 | 219 | #beatmap_name{ 220 | font-size: 2.5vw; 221 | } 222 | 223 | #profileDesc{ 224 | font-size: 2vw; 225 | } 226 | 227 | #pageNumbers{ 228 | font-size: 7vw; 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /css/userProfile.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | background-image: url("../images/background.png"); 8 | padding-top: 20vh; 9 | font-family: "Verdana"; 10 | } 11 | 12 | .block { 13 | display: block; 14 | margin:auto; 15 | margin-left: 10%; 16 | margin-right: 10%; 17 | background-color: rgba(150, 150, 150, .5); 18 | border-radius:50px; 19 | } 20 | 21 | .align_center{ 22 | text-align: center; 23 | } 24 | 25 | .back{ 26 | height:70px; 27 | margin-right: 1%; 28 | position: sticky; 29 | right: 0; 30 | top: 0; 31 | } 32 | 33 | #header{ 34 | padding: 2% 10% 2% 10%; 35 | overflow:auto; 36 | vertical-align: middle; 37 | } 38 | 39 | #userImage{ 40 | border-radius:200px; 41 | border-style: solid; 42 | border-color: white; 43 | height:25vh; 44 | float: left; 45 | } 46 | 47 | #osuImage{ 48 | border-radius:200px; 49 | } 50 | 51 | #osuImage img{ 52 | height : 13vh; 53 | padding-left:8%; 54 | padding-top: 2%; 55 | } 56 | 57 | #osuImage:hover{ 58 | opacity: 0.5; 59 | } 60 | 61 | #profileImage img{ 62 | height : 13vh; 63 | } 64 | 65 | #profileImage:hover{ 66 | opacity: 0.5; 67 | } 68 | 69 | #headerContent { 70 | display: inline-block; 71 | padding-left:8%; 72 | padding-right: 15%; 73 | font-family: "Verdana"; 74 | font-size: 3.5vh; 75 | color:black; 76 | } 77 | 78 | #headerContent h1 { 79 | color: rgb(255, 102, 170); 80 | text-shadow: 2px 2px 0px rgba(150, 150, 150, 1); 81 | } 82 | 83 | #headerContent h3 { 84 | color: white; 85 | text-shadow: 2px 2px 0px rgba(150, 150, 150, 1); 86 | } 87 | 88 | #replayList h2{ 89 | text-align: center; 90 | font-family: "Verdana"; 91 | font-size: 2vw; 92 | padding-bottom: 2%; 93 | } 94 | 95 | #replayList { 96 | margin-top: 2%; 97 | padding: 1% 2% 1% 2%; 98 | text-align: center; 99 | } 100 | 101 | .replayImg { 102 | border: 5px solid white; 103 | height:180px; 104 | width:240px; 105 | } 106 | 107 | .replayImg:hover { 108 | opacity: 0.5; 109 | } 110 | 111 | #replayList a { 112 | border: 5px solid transparent; 113 | } 114 | 115 | .showMore { 116 | margin-top: 2%; 117 | } 118 | 119 | /* Mobiles */ 120 | @media only screen and (max-width: 1080px) and (orientation: portrait){ 121 | /*First block*/ 122 | #userImage{ 123 | height:30vw; 124 | float:none; 125 | } 126 | #header{ 127 | padding: 2% 5% 2% 5%; 128 | text-align: center; 129 | } 130 | #headerContent{ 131 | font-size: 4.5vw; 132 | } 133 | #osuImage img{ 134 | height : 15vw; 135 | padding-left:0%; 136 | } 137 | #profileImage img{ 138 | height : 15vw; 139 | } 140 | 141 | /*Replay library*/ 142 | #replayList h2{ 143 | font-size: 5vw; 144 | padding-bottom: 2%; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /css/userVerification.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | background-image: url("../images/background.png"); 8 | /*padding-bottom:5%;*/ 9 | padding-top: 20vh; 10 | font-family: "Verdana"; 11 | text-align: center; 12 | } 13 | 14 | .block{ 15 | margin-left: 5%; 16 | margin-right: 5%; 17 | margin-bottom: 2%; 18 | padding-top: 3%; 19 | padding-bottom: 3%; 20 | background-color: rgba(150, 150, 150, .5); 21 | background-color: rgba(150, 150, 150, .5); 22 | border-radius:50px; 23 | } 24 | 25 | h2{ 26 | text-decoration: underline; 27 | } 28 | 29 | .block img{ 30 | margin-top: 1%; 31 | height:10%; 32 | } 33 | 34 | #timer{ 35 | color:red; 36 | } 37 | -------------------------------------------------------------------------------- /emailVerification.php: -------------------------------------------------------------------------------- 1 | connect_error) { 19 | die("Connection failed: " . $conn->connect_error); 20 | header("Location:index.php?error=3"); 21 | exit; 22 | } 23 | 24 | if(isset($_GET['id'])){ 25 | $verfId = $_GET['id']; 26 | }else{ 27 | close($conn); 28 | } 29 | 30 | // ******************** Functions ********************************** 31 | function close($conn){ 32 | header("Location:index.php"); 33 | } 34 | // ******************** core ********************************** 35 | $queryInfos = $conn->prepare("SELECT * FROM accounts WHERE verfIdEmail=?"); 36 | $queryInfos->bind_param("s",$verfId); 37 | $queryInfos->execute(); 38 | $result = $queryInfos->get_result(); 39 | $queryInfos->close(); 40 | 41 | if($result->num_rows > 0){ 42 | while($row = $result->fetch_assoc()){ 43 | $usernameOsu = $row['username']; 44 | $userId = $row['userId']; 45 | } 46 | }else{ 47 | close($conn); 48 | } 49 | 50 | $queryInfos = $conn->prepare("UPDATE accounts SET verfIdEmail='' WHERE userId=?"); 51 | $queryInfos->bind_param("s",$userId); 52 | $queryInfos->execute(); 53 | $queryInfos->close(); 54 | 55 | echo 'Thanks '.$usernameOsu." ! Your email has been validated"; 56 | 57 | header("Location:userVerification.php?id=$userId"); 58 | ?> 59 | -------------------------------------------------------------------------------- /images/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/add.png -------------------------------------------------------------------------------- /images/arrow_button_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/arrow_button_left.png -------------------------------------------------------------------------------- /images/arrow_button_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/arrow_button_right.png -------------------------------------------------------------------------------- /images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/background.png -------------------------------------------------------------------------------- /images/background2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/background2.png -------------------------------------------------------------------------------- /images/codevirtuel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/codevirtuel.jpg -------------------------------------------------------------------------------- /images/cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/cross.png -------------------------------------------------------------------------------- /images/cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/cursor.png -------------------------------------------------------------------------------- /images/defaultProfilePicture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/defaultProfilePicture.png -------------------------------------------------------------------------------- /images/editProfile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/editProfile.png -------------------------------------------------------------------------------- /images/etape1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/etape1.png -------------------------------------------------------------------------------- /images/etape2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/etape2.gif -------------------------------------------------------------------------------- /images/etape2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/etape2.png -------------------------------------------------------------------------------- /images/etape3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/etape3.png -------------------------------------------------------------------------------- /images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/icon.png -------------------------------------------------------------------------------- /images/image credits.txt: -------------------------------------------------------------------------------- 1 | add.png - Smashicons on flaticon.com -------------------------------------------------------------------------------- /images/index/Discord_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/index/Discord_logo.png -------------------------------------------------------------------------------- /images/index/github_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/index/github_logo.png -------------------------------------------------------------------------------- /images/index/modal1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/index/modal1.png -------------------------------------------------------------------------------- /images/index/modal2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/index/modal2.png -------------------------------------------------------------------------------- /images/index/modal3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/index/modal3.png -------------------------------------------------------------------------------- /images/index/modal4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/index/modal4.png -------------------------------------------------------------------------------- /images/index/modal5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/index/modal5.png -------------------------------------------------------------------------------- /images/index/modal6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/index/modal6.png -------------------------------------------------------------------------------- /images/index/osu forums.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/index/osu forums.png -------------------------------------------------------------------------------- /images/index/patreon_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/index/patreon_logo.png -------------------------------------------------------------------------------- /images/index/paypal_me.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/index/paypal_me.png -------------------------------------------------------------------------------- /images/index/tipeee_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/index/tipeee_logo.png -------------------------------------------------------------------------------- /images/large/index/Discord_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/large/index/Discord_logo.png -------------------------------------------------------------------------------- /images/large/index/etape1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/large/index/etape1.png -------------------------------------------------------------------------------- /images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/loading.gif -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/logo.png -------------------------------------------------------------------------------- /images/medium/index/Discord_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/medium/index/Discord_logo.png -------------------------------------------------------------------------------- /images/medium/index/codevirtuel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/medium/index/codevirtuel.jpg -------------------------------------------------------------------------------- /images/medium/index/etape1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/medium/index/etape1.png -------------------------------------------------------------------------------- /images/medium/index/github_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/medium/index/github_logo.png -------------------------------------------------------------------------------- /images/medium/index/osu_forums.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/medium/index/osu_forums.png -------------------------------------------------------------------------------- /images/medium/index/paypal_me.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/medium/index/paypal_me.png -------------------------------------------------------------------------------- /images/mods/Autopilot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Autopilot.png -------------------------------------------------------------------------------- /images/mods/Autoplay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Autoplay.png -------------------------------------------------------------------------------- /images/mods/Cinema.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Cinema.png -------------------------------------------------------------------------------- /images/mods/Coop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Coop.png -------------------------------------------------------------------------------- /images/mods/DoubleTime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/DoubleTime.png -------------------------------------------------------------------------------- /images/mods/Easy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Easy.png -------------------------------------------------------------------------------- /images/mods/FadeIn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/FadeIn.png -------------------------------------------------------------------------------- /images/mods/Flashlight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Flashlight.png -------------------------------------------------------------------------------- /images/mods/HalfTime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/HalfTime.png -------------------------------------------------------------------------------- /images/mods/HardRock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/HardRock.png -------------------------------------------------------------------------------- /images/mods/Hidden.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Hidden.png -------------------------------------------------------------------------------- /images/mods/Key1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Key1.png -------------------------------------------------------------------------------- /images/mods/Key2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Key2.png -------------------------------------------------------------------------------- /images/mods/Key3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Key3.png -------------------------------------------------------------------------------- /images/mods/Key4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Key4.png -------------------------------------------------------------------------------- /images/mods/Key5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Key5.png -------------------------------------------------------------------------------- /images/mods/Key6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Key6.png -------------------------------------------------------------------------------- /images/mods/Key7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Key7.png -------------------------------------------------------------------------------- /images/mods/Key8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Key8.png -------------------------------------------------------------------------------- /images/mods/Key9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Key9.png -------------------------------------------------------------------------------- /images/mods/Mirror.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Mirror.png -------------------------------------------------------------------------------- /images/mods/Nightcore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Nightcore.png -------------------------------------------------------------------------------- /images/mods/NoFail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/NoFail.png -------------------------------------------------------------------------------- /images/mods/None.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/None.png -------------------------------------------------------------------------------- /images/mods/Perfect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Perfect.png -------------------------------------------------------------------------------- /images/mods/Random.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Random.png -------------------------------------------------------------------------------- /images/mods/Relax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Relax.png -------------------------------------------------------------------------------- /images/mods/ScoreV2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/ScoreV2.png -------------------------------------------------------------------------------- /images/mods/SpunOut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/SpunOut.png -------------------------------------------------------------------------------- /images/mods/SuddenDeath.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/SuddenDeath.png -------------------------------------------------------------------------------- /images/mods/Target.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/mods/Target.png -------------------------------------------------------------------------------- /images/ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/ok.png -------------------------------------------------------------------------------- /images/osuCTB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/osuCTB.png -------------------------------------------------------------------------------- /images/osuMania.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/osuMania.png -------------------------------------------------------------------------------- /images/osuStdr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/osuStdr.png -------------------------------------------------------------------------------- /images/osuTaiko.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/osuTaiko.png -------------------------------------------------------------------------------- /images/osu_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/osu_logo.png -------------------------------------------------------------------------------- /images/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/preview.jpg -------------------------------------------------------------------------------- /images/progress/green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/progress/green.png -------------------------------------------------------------------------------- /images/progress/orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/progress/orange.png -------------------------------------------------------------------------------- /images/progress/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/progress/red.png -------------------------------------------------------------------------------- /images/reddit_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/reddit_icon.png -------------------------------------------------------------------------------- /images/small/index/Discord_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/small/index/Discord_logo.png -------------------------------------------------------------------------------- /images/small/index/codevirtuel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/small/index/codevirtuel.jpg -------------------------------------------------------------------------------- /images/small/index/etape1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/small/index/etape1.png -------------------------------------------------------------------------------- /images/small/index/github_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/small/index/github_logo.png -------------------------------------------------------------------------------- /images/small/index/osu_forums.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/small/index/osu_forums.png -------------------------------------------------------------------------------- /images/small/index/paypal_me.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/small/index/paypal_me.png -------------------------------------------------------------------------------- /images/tooltips/findOsuId.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/tooltips/findOsuId.PNG -------------------------------------------------------------------------------- /images/twitter_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/twitter_icon.png -------------------------------------------------------------------------------- /images/u_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/u_icon.png -------------------------------------------------------------------------------- /images/view/delete_replay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/view/delete_replay.png -------------------------------------------------------------------------------- /images/view/download_beatmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/view/download_beatmap.png -------------------------------------------------------------------------------- /images/view/download_replay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/view/download_replay.png -------------------------------------------------------------------------------- /images/view/download_skin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/view/download_skin.png -------------------------------------------------------------------------------- /images/view/peertube_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/view/peertube_logo.png -------------------------------------------------------------------------------- /images/view/rerecord_replay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/view/rerecord_replay.png -------------------------------------------------------------------------------- /images/view/video_source.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/view/video_source.png -------------------------------------------------------------------------------- /images/view/youtube_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/view/youtube_logo.png -------------------------------------------------------------------------------- /images/xlarge/index/Discord_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/images/xlarge/index/Discord_logo.png -------------------------------------------------------------------------------- /js/analytics.js: -------------------------------------------------------------------------------- 1 | 2 | (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 3 | new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 4 | j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 5 | 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 6 | })(window,document,'script','dataLayer','GTM-KT37FG8'); 7 | 8 | -------------------------------------------------------------------------------- /js/closeErrorModal.js: -------------------------------------------------------------------------------- 1 | function closeErrorModal(){ 2 | var modal = document.getElementById("myErrorModal"); 3 | modal.style.display = "none"; 4 | } 5 | -------------------------------------------------------------------------------- /js/editProfile.js: -------------------------------------------------------------------------------- 1 | function showDim(){ 2 | document.getElementById("dimValue").innerHTML = document.getElementById("dimRange").value+"%"; 3 | 4 | var image = document.getElementById("dimPreview"); 5 | var amount = map(document.getElementById("dimRange").value,0,100,1,0); 6 | image.setAttribute('style', 'filter:brightness(' + amount + '); -webkit-filter:brightness(' + amount + '); -moz-filter:brightness(' + amount + ')'); 7 | } 8 | 9 | function map(s,a1,a2,b1,b2) 10 | { 11 | return b1 + (s-a1)*(b2-b1)/(a2-a1); 12 | } 13 | 14 | function updateCustomSkin(){ 15 | var enable = document.getElementById("checkBox"); 16 | if(enable.checked == true){ 17 | document.getElementById("skinsSelector").disabled = false; 18 | }else{ 19 | document.getElementById("skinsSelector").disabled = true; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /js/index/askUsername.js: -------------------------------------------------------------------------------- 1 | var isIdOk = false; 2 | 3 | function showUsername(str) { 4 | if (str.length == 0) { 5 | document.getElementById("txtHint").innerHTML = ""; 6 | isIdOk = false; 7 | update(); 8 | return; 9 | } else { 10 | var xmlhttp = new XMLHttpRequest(); 11 | xmlhttp.onreadystatechange = function() { 12 | if (this.readyState == 4 && this.status == 200) { 13 | document.getElementById("txtHint").innerHTML = this.responseText; 14 | if(this.responseText == "this user doesn't exists" || this.responseText == ''){ 15 | isIdOk = false; 16 | update(); 17 | return isIdOk; 18 | }else{ 19 | isIdOk = true; 20 | update(); 21 | return isIdOk; 22 | } 23 | } 24 | }; 25 | xmlhttp.open("GET", "php/getUsername.php?q=" + str, true); 26 | xmlhttp.send(); 27 | } 28 | } 29 | 30 | function validate(){ 31 | var retour = showUsername(document.getElementById("newUsername").value); 32 | console.log('test :'+document.getElementById("newUsername").value); 33 | console.log('test :'+retour); 34 | return retour; 35 | } 36 | 37 | function update(){ 38 | //Check if the form is filled 39 | 40 | if(isIdOk){ 41 | show("continue_btn"); 42 | } else { hide("continue_btn"); } 43 | } 44 | 45 | //-- Hide and seek 46 | function hide(id){ 47 | node = document.getElementById(id); 48 | if(node){ 49 | node.style.visibility = "hidden"; 50 | } 51 | } 52 | 53 | function show(id){ 54 | node = document.getElementById(id); 55 | if(node){ 56 | node.style.visibility = "visible"; 57 | } 58 | } 59 | 60 | function start(){ 61 | hide("continue_btn"); 62 | document.getElementById("txtHint").value = ''; 63 | document.getElementById("newUsername").value = ''; 64 | } 65 | -------------------------------------------------------------------------------- /js/index/upload.js: -------------------------------------------------------------------------------- 1 | //modal 2 | var modal; 3 | var clear = 'true'; 4 | 5 | function openModal(){ 6 | modal = document.getElementById("myModal"); 7 | modal.style.display = "block"; 8 | } 9 | 10 | function closeModal(){ 11 | modal = document.getElementById("myModal"); 12 | modal.style.display = "none"; 13 | } 14 | 15 | function openModalUsername(){ 16 | modal = document.getElementById("askUsername_modal"); 17 | modal.style.display = "block"; 18 | } 19 | 20 | function closeModalUsername(){ 21 | modal = document.getElementById("askUsername_modal"); 22 | modal.style.display = "none"; 23 | } 24 | 25 | function submitForm(){ 26 | document.getElementById("upload_box").submit(); 27 | } 28 | 29 | function setItemTrue(item){ 30 | document.getElementById(item).style["border-color"] = "lightgreen"; 31 | } 32 | 33 | function setItemFalse(item){ 34 | document.getElementById(item).style["border-color"] = "red"; 35 | } 36 | 37 | function notValidate(){ 38 | return false; 39 | } 40 | 41 | function disableProcessing(){ 42 | document.getElementById("start_processing").disabled = true; 43 | document.getElementById("checkBox").disabled = true; 44 | } 45 | 46 | function clearSession(){ 47 | $.ajax({ 48 | url: './php/index/clearSession.php', 49 | dataType: 'json', 50 | async: true, 51 | success: function(data){ 52 | console.log('success'); 53 | //data returned from php 54 | } 55 | }); 56 | } 57 | 58 | function disableClear(){ 59 | //clear = 'false'; 60 | } 61 | 62 | window.onunload = window.onbeforeunload = (function(){ 63 | console.log(clear); 64 | if(clear === 'true'){ 65 | clearSession(); 66 | } 67 | }) 68 | -------------------------------------------------------------------------------- /js/index/validateUsername.js: -------------------------------------------------------------------------------- 1 | var result; 2 | var id; 3 | 4 | function userExists(str){ 5 | if (str.length == 0) { 6 | return false; 7 | } else { 8 | var xmlhttp = new XMLHttpRequest(); 9 | xmlhttp.onreadystatechange = function() { 10 | if (this.readyState == 4 && this.status == 200) { 11 | if(this.responseText == "this user doesn't exists" || this.responseText == ''){ 12 | result = false; 13 | }else{ 14 | result = true; 15 | } 16 | } 17 | }; 18 | xmlhttp.open("GET", "php/getUsername.php?q=" + str, false); 19 | xmlhttp.send(); 20 | } 21 | } 22 | 23 | function getUserId(str){ 24 | if (str.length == 0) { 25 | id = 1; 26 | } else { 27 | var xmlhttp = new XMLHttpRequest(); 28 | xmlhttp.onreadystatechange = function() { 29 | if (this.readyState == 4 && this.status == 200) { 30 | if(this.responseText == "this user doesn't exists" || this.responseText == ''){ 31 | id = 1; 32 | }else{ 33 | id = this.responseText; 34 | } 35 | } 36 | }; 37 | xmlhttp.open("GET", "php/getUserId.php?q=" + str, false); 38 | xmlhttp.send(); 39 | } 40 | } 41 | 42 | function validateName(){ 43 | var str = document.getElementById("newUsername").value; 44 | userExists(str); 45 | console.log("user exists : "+result); 46 | return result; 47 | } 48 | 49 | function updatePicture(){ 50 | var str = document.getElementById("newUsername").value; 51 | var url = "https://a.ppy.sh/"; 52 | 53 | if (str.length == 0) { 54 | document.getElementById("userImage").src=url+"1"; 55 | } else { 56 | var xmlhttp = new XMLHttpRequest(); 57 | xmlhttp.onreadystatechange = function() { 58 | if (this.readyState == 4 && this.status == 200) { 59 | document.getElementById("userImage").src=url+this.responseText; 60 | } 61 | }; 62 | xmlhttp.open("GET", "php/getUserId.php?q=" + str, true); 63 | xmlhttp.send(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /js/loader.js: -------------------------------------------------------------------------------- 1 | //Copy paste this 2 | // 3 | // 4 | // 5 | //after 6 | //
7 | 8 | $(window).on("load", function() { 9 | // weave your magic here. 10 | $(".loaderCustom").fadeOut("slow");; 11 | }); 12 | 13 | $(window).on("beforeunload", function() { 14 | $('.loaderCustom').fadeIn(); 15 | }); 16 | -------------------------------------------------------------------------------- /js/patreon/loadBlocks.js: -------------------------------------------------------------------------------- 1 | //Ajax function to get json 2 | $(document).ready(function(){ 3 | $.getJSON( "php/patreon/getPledgers.php", function( data ) { 4 | data.forEach(function(element) { 5 | insertBlock(element); 6 | }); 7 | }); 8 | }); 9 | 10 | function insertBlock(array){ 11 | 12 | var tier_name = array.title; 13 | var pledgers_nb = array.patron_count; 14 | var tier_price = array.amount_cents/100; 15 | var join_url = 'https://www.patreon.com'+array.url; 16 | var pledgers_array = array.pledgers; 17 | 18 | var url = new URL(join_url); 19 | var join_id = url.searchParams.get("rid"); 20 | 21 | //Construct pledgers list 22 | var pledgers = ""; 23 | pledgers_array.forEach(function(element) { 24 | if(element !== ""){ 25 | pledgers += element+','; 26 | } 27 | }); 28 | 29 | 30 | var result = "
\n" + 31 | "
\n" + 32 | "
\n" + 33 | "

"+tier_name+"\n" + 34 | " - "+pledgers_nb+" pledgers\n" + 35 | "

\n" + 36 | "
\n" + 37 | "
\n" + 38 | "
\n" + 39 | " \n" + 40 | " \n" + 41 | "
\n" + 42 | "
\n" + 43 | "
\n" + 44 | "
\n" + 45 | "

\n" + 46 | "
"; 47 | 48 | var next = ""; 49 | if(pledgers !== ""){ 50 | next = 51 | "

Thank you ❤️,

\n" + 52 | "

\n" + 53 | " "+pledgers+"\n" + 54 | "

\n" + 55 | "
\n" + 56 | " View all the benefits on the patreon page\n" + 57 | "
\n" + 58 | "
\n" + 59 | "
"; 60 | }else{ 61 | next = 62 | "

\n" + 63 | " Be the first one to pledge this tier !\n" + 64 | " \n" + 65 | "

\n" + 66 | " View all the benefits on the patreon page\n" + 67 | "
\n" + 68 | " \n" + 69 | " "; 70 | } 71 | 72 | result += next; 73 | 74 | //Insert created block into page 75 | var divBlock = document.getElementById("tier_container"); 76 | divBlock.innerHTML = divBlock.innerHTML + result; 77 | } -------------------------------------------------------------------------------- /js/plyr.js: -------------------------------------------------------------------------------- 1 | document.addEventListener('DOMContentLoaded', () => { 2 | // This is the bare minimum JavaScript. You can opt to pass no arguments to setup. 3 | const player = new Plyr('#player'); 4 | 5 | player.ads = { 6 | enable:true, 7 | publisherId:'122432164390505' 8 | }; 9 | 10 | //console.log(player); 11 | }); 12 | -------------------------------------------------------------------------------- /js/profile/cursorSize.js: -------------------------------------------------------------------------------- 1 | function showCursorSize(){ 2 | document.getElementById("cursorSizeValue").innerHTML = document.getElementById("cursorSizeRange").value+"x"; 3 | 4 | //var image = document.getElementById("dimPreview"); 5 | //var amount = map(document.getElementById("dimRange").value,0,100,1,0); 6 | //image.setAttribute('style', 'filter:brightness(' + amount + '); -webkit-filter:brightness(' + amount + '); -moz-filter:brightness(' + amount + ')'); 7 | } -------------------------------------------------------------------------------- /js/profile/modal.js: -------------------------------------------------------------------------------- 1 | function openModalDelete(){ 2 | var modal = document.getElementById("delete_modal"); 3 | modal.style.display = "block"; 4 | } 5 | 6 | function closeModalDelete(){ 7 | var modal = document.getElementById("delete_modal"); 8 | modal.style.display = "none"; 9 | } 10 | 11 | /* Modal replay delete */ 12 | 13 | function openModalDeleteReplay(replayId, redirect) { 14 | var modal = document.getElementById("delete_replay_modal"); 15 | modal.style.display = "block"; 16 | document.getElementById("value_delete_replayId").value = replayId; 17 | document.getElementById("value_delete_redirect").value = redirect; 18 | } 19 | 20 | function closeModalDeleteReplay() { 21 | var modal = document.getElementById("delete_replay_modal"); 22 | modal.style.display = "none"; 23 | } 24 | 25 | function openMultipleModalDeleteReplay(redirect) { 26 | var modal = document.getElementById("delete_multiple_replay_modal"); 27 | modal.style.display = "block"; 28 | document.getElementById("value_delete_multiple_replayId").value = JSON.stringify(selectedReplays); 29 | document.getElementById("value_delete_multiple_redirect").value = redirect; 30 | } 31 | 32 | function closeMultipleModalDeleteReplay() { 33 | var modal = document.getElementById("delete_multiple_replay_modal"); 34 | modal.style.display = "none"; 35 | } 36 | 37 | /* Modal replay graveyard */ 38 | 39 | function openModalGraveyardReplay(replayId, redirect) { 40 | var modal = document.getElementById("graveyard_replay_modal"); 41 | modal.style.display = "block"; 42 | document.getElementById("value_graveyard_replayId").value = replayId; 43 | document.getElementById("value_graveyard_redirect").value = redirect; 44 | } 45 | 46 | function closeModalGraveyardReplay() { 47 | var modal = document.getElementById("graveyard_replay_modal"); 48 | modal.style.display = "none"; 49 | } 50 | 51 | function openMultipleModalGraveyardReplay(redirect) { 52 | var modal = document.getElementById("graveyard_multiple_replay_modal"); 53 | modal.style.display = "block"; 54 | document.getElementById("value_graveyard_multiple_replayId").value = JSON.stringify(selectedReplays); 55 | document.getElementById("value_graveyard_multiple_redirect").value = redirect; 56 | } 57 | 58 | function closeMultipleModalGraveyardReplay() { 59 | var modal = document.getElementById("graveyard_multiple_replay_modal"); 60 | modal.style.display = "none"; 61 | } 62 | 63 | /* Modal replay pending cancel */ 64 | 65 | function openModalPendingReplay(replayId, redirect, md5) { 66 | var modal = document.getElementById("pending_replay_modal"); 67 | modal.style.display = "block"; 68 | document.getElementById("value_pending_replayId").value = replayId; 69 | document.getElementById("value_pending_redirect").value = redirect; 70 | document.getElementById("value_pending_md5").value = md5; 71 | } 72 | 73 | function closeModalPendingReplay() { 74 | var modal = document.getElementById("pending_replay_modal"); 75 | modal.style.display = "none"; 76 | } 77 | 78 | function openMultipleModalPendingReplay(redirect) { 79 | var modal = document.getElementById("pending_multiple_replay_modal"); 80 | modal.style.display = "block"; 81 | document.getElementById("value_pending_multiple_replayId").value = JSON.stringify(selectedReplays); 82 | document.getElementById("value_pending_multiple_redirect").value = redirect; 83 | document.getElementById("value_pending_multiple_md5").value = JSON.stringify(selectedReplaysMd5); 84 | } 85 | 86 | function closeMultipleModalPendingReplay() { 87 | var modal = document.getElementById("pending_multiple_replay_modal"); 88 | modal.style.display = "none"; 89 | } 90 | 91 | /* Modal replay re-record */ 92 | 93 | function openModalRerecordReplay(replayId, redirect) { 94 | var modal = document.getElementById("rerecord_replay_modal"); 95 | modal.style.display = "block"; 96 | document.getElementById("value_rerecord_replayId").value = replayId; 97 | document.getElementById("value_rerecord_redirect").value = redirect; 98 | } 99 | 100 | function closeModalRerecordReplay() { 101 | var modal = document.getElementById("rerecord_replay_modal"); 102 | modal.style.display = "none"; 103 | } -------------------------------------------------------------------------------- /js/profile/replaySelect.js: -------------------------------------------------------------------------------- 1 | let selectedReplays = []; 2 | let selectedReplaysMd5 = []; 3 | 4 | function onCheckboxUpdated(checkbox, replayId, replayMd5 = null) { 5 | if (checkbox.checked) { 6 | onCheckReplay(replayId, replayMd5) 7 | } else { 8 | onUncheckReplay(replayId, replayMd5) 9 | } 10 | } 11 | 12 | function onCheckReplay(replayId, replayMd5 = null) { 13 | console.log("Added replay " + replayId + " to list " + replayMd5); 14 | selectedReplays.push(replayId); 15 | selectedReplaysMd5.push(replayMd5); 16 | updateMultiButtons(); 17 | } 18 | 19 | function onUncheckReplay(replayId, replayMd5 = null) { 20 | console.log("Removed replay " + replayId + " to list"); 21 | //Remove replay from list 22 | for (let i = selectedReplays.length - 1; i >= 0; i--) { 23 | if (selectedReplays[i] === replayId) { 24 | selectedReplays.splice(i, 1); 25 | selectedReplaysMd5.splice(i, 1); 26 | } 27 | } 28 | 29 | updateMultiButtons(); 30 | } 31 | 32 | function updateMultiButtons() { 33 | let bts = document.querySelectorAll("#multi_card_buttons span"); 34 | if (selectedReplays.length >= 1) { 35 | bts.forEach(function (bt) { 36 | bt.removeAttribute('disabled'); 37 | }) 38 | } else { 39 | bts.forEach(function (bt) { 40 | bt.setAttribute('disabled', true); 41 | }) 42 | } 43 | } -------------------------------------------------------------------------------- /js/profile/uploadSkin.js: -------------------------------------------------------------------------------- 1 | function checkFileSize(file) { 2 | var max = 52428800; // 50Mo 3 | 4 | if (file.size > max) { 5 | var pathname = window.location.pathname; 6 | removeHeaders = false; 7 | window.location.replace(pathname+"?block=skin&error=11"); 8 | document.getElementById("fileToUpload").value = null; // Clear the field. 9 | }else{ 10 | return true; 11 | } 12 | } 13 | 14 | function checkFileCharacters(file){ 15 | var patt = /['^£$%&*()}{@#~?><>,|=_+¬-]/; 16 | if(patt.test(file)){ 17 | var pathname = window.location.pathname; 18 | removeHeaders = false; 19 | window.location.replace(pathname+"?block=skin&error=10"); 20 | document.getElementById("fileToUpload").value = null; // Clear the field. 21 | }else{ 22 | return true; 23 | } 24 | 25 | } 26 | 27 | function onClick(form){ 28 | let file = document.getElementById("fileToUpload").files[0]; 29 | console.log(file); 30 | if(checkFileSize(file) && checkFileCharacters(file)){ 31 | form.parentNode.submit(); 32 | } 33 | } 34 | 35 | window.onchange = function() { 36 | //onClick(); 37 | }; 38 | -------------------------------------------------------------------------------- /js/profile/volume.js: -------------------------------------------------------------------------------- 1 | function updateVolume(){ 2 | document.getElementById("musicVolumeValue").innerHTML = document.getElementById("musicVolumeRange").value+"%"; 3 | document.getElementById("effectsVolumeValue").innerHTML = document.getElementById("effectsVolumeRange").value+"%"; 4 | } -------------------------------------------------------------------------------- /js/progress/autoUpload.js: -------------------------------------------------------------------------------- 1 | function submitForm(){ 2 | document.getElementById("upload_box").submit(); 3 | } 4 | -------------------------------------------------------------------------------- /js/request.js: -------------------------------------------------------------------------------- 1 | //----------------------------- variables ---------------------------------- 2 | var isIdOk = false; 3 | 4 | //----------------------------- functions ---------------------------------- 5 | 6 | //-- Username / osu id 7 | function showUsername(str) { 8 | if (str.length == 0) { 9 | document.getElementById("txtHint").innerHTML = ""; 10 | isIdOk = false; 11 | update(); 12 | return; 13 | } else { 14 | var xmlhttp = new XMLHttpRequest(); 15 | xmlhttp.onreadystatechange = function() { 16 | if (this.readyState == 4 && this.status == 200) { 17 | document.getElementById("txtHint").innerHTML = this.responseText; 18 | if(this.responseText == "this user doesn't exists" || this.responseText == ''){ 19 | isIdOk = false; 20 | update(); 21 | }else{ 22 | isIdOk = true; 23 | update(); 24 | } 25 | } 26 | }; 27 | xmlhttp.open("GET", "php/getUsername.php?q=" + str, true); 28 | xmlhttp.send(); 29 | } 30 | } 31 | 32 | //-- Password 33 | function checkPassword() { 34 | var firstPass = document.getElementById("pass").value; 35 | var confirmPass = document.getElementById("confPass").value; 36 | if(firstPass == confirmPass && firstPass != '' && confirmPass != ''){ 37 | return true; 38 | }else{ 39 | return false; 40 | } 41 | } 42 | 43 | function showCheckPass(){ 44 | var firstPass = document.getElementById("pass").value; 45 | var confirmPass = document.getElementById("confPass").value; 46 | if(firstPass == confirmPass && firstPass != '' && confirmPass != ''){ 47 | document.getElementById("checkPass").innerHTML = ""; 48 | }else{ 49 | document.getElementById("checkPass").innerHTML = "The password doesn't match"; 50 | } 51 | } 52 | 53 | //-- Hide and seek 54 | function hide(id){ 55 | node = document.getElementById(id); 56 | if(node){ 57 | node.style.visibility = "hidden"; 58 | } 59 | } 60 | 61 | function show(id){ 62 | node = document.getElementById(id); 63 | if(node){ 64 | node.style.visibility = "visible"; 65 | } 66 | } 67 | 68 | //-- Email 69 | function checkEmail() { 70 | var firstEmail = document.getElementById("email").value; 71 | var confirmEmail = document.getElementById("confEmail").value; 72 | if(firstEmail == confirmEmail && firstEmail != '' && confirmEmail != ''){ 73 | return true; 74 | }else{ 75 | return false; 76 | } 77 | } 78 | 79 | function validateEmail() { 80 | var email = document.getElementById("email").value; 81 | var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 82 | return re.test(String(email).toLowerCase()); 83 | } 84 | 85 | function showEmailValidity(){ 86 | if(validateEmail()){ 87 | document.getElementById("emailHint").innerHTML = ""; 88 | }else{ 89 | document.getElementById("emailHint").innerHTML = "This e-mail is not valid"; 90 | } 91 | } 92 | 93 | function showCheckEmail(){ 94 | var firstEmail = document.getElementById("email").value; 95 | var confirmEmail = document.getElementById("confEmail").value; 96 | if(firstEmail == confirmEmail && firstEmail != '' && confirmEmail != ''){ 97 | document.getElementById("checkEmail").innerHTML = ""; 98 | }else{ 99 | document.getElementById("checkEmail").innerHTML = "The email doesn't match"; 100 | } 101 | } 102 | 103 | function checkBox(){ 104 | var checkbox = document.getElementById("checkBox"); 105 | if(checkbox.checked){ 106 | return true; 107 | }else{ 108 | return false; 109 | } 110 | } 111 | 112 | //----------------------------- At start ---------------------------------- 113 | function start(){ 114 | hide("submitButton"); 115 | document.getElementById("email").value = ''; 116 | document.getElementById("userId").value = ''; 117 | document.getElementById("checkBox").checked = false; 118 | } 119 | 120 | //----------------------------- At every update --------------------------- 121 | function update(){ 122 | //Check if the form is filled 123 | if(checkPassword() && validateEmail() && checkEmail() && checkBox() && isIdOk){ 124 | show("submitButton"); 125 | } else { hide("submitButton"); } 126 | } 127 | 128 | //----------------------------- When the form is submitted ---------------- 129 | function submitted(){ 130 | 131 | } 132 | -------------------------------------------------------------------------------- /js/view/modal.js: -------------------------------------------------------------------------------- 1 | var modal; 2 | 3 | function openModalDelete(){ 4 | modal = document.getElementById("delete_modal"); 5 | modal.style.display = "block"; 6 | } 7 | 8 | function openModalRerecord(){ 9 | modal = document.getElementById("rerecord_modal"); 10 | modal.style.display = "block"; 11 | } 12 | 13 | function closeModalDelete(){ 14 | modal = document.getElementById("delete_modal"); 15 | modal.style.display = "none"; 16 | } 17 | 18 | function closeModalRerecord(){ 19 | modal = document.getElementById("rerecord_modal"); 20 | modal.style.display = "none"; 21 | } 22 | -------------------------------------------------------------------------------- /legal/EN/Terms of use for replay processing - EN.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/legal/EN/Terms of use for replay processing - EN.pdf -------------------------------------------------------------------------------- /legal/EN/Terms of use for user accounts - EN.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/legal/EN/Terms of use for user accounts - EN.pdf -------------------------------------------------------------------------------- /legal/FR/Termes d'utilisation compte utilisateur FR.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/legal/FR/Termes d'utilisation compte utilisateur FR.pdf -------------------------------------------------------------------------------- /legal/FR/Termes d'utilisation du traitement des replays - FR.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/legal/FR/Termes d'utilisation du traitement des replays - FR.pdf -------------------------------------------------------------------------------- /legal/TU.php: -------------------------------------------------------------------------------- 1 | 'EN/Terms of use for replay processing - EN.pdf', 5 | "fr" => 'FR/Termes d\'utilisation du traitement des replays - FR.pdf' 6 | ); 7 | 8 | $filesUser = array( 9 | "en" => 'EN/Terms of use for user accounts - EN.pdf', 10 | "fr" => 'FR/Termes d\'utilisation compte utilisateur FR.pdf' 11 | ); 12 | 13 | $TU = array( 14 | 'replay' => $filesReplay, 15 | 'user' => $filesUser 16 | ); 17 | 18 | //Get what is the Terms of Use requested 19 | if(isset($_GET['TU'])){ 20 | if(!in_array($_GET['TU'], array_keys($TU))){ 21 | $array = $filesReplay; 22 | }else{ 23 | $array = $TU[$_GET['TU']]; 24 | } 25 | }else{ 26 | $array = $filesReplay; 27 | } 28 | 29 | //Get the language (if the get value is not set) 30 | if(isset($_GET['lang'])){ 31 | //With the get variable 32 | $lang = $_GET['lang']; 33 | }else{ 34 | //With the browser language 35 | $lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2); 36 | } 37 | 38 | if(!in_array($lang, array_keys($array))){ 39 | $lang = "en"; 40 | } 41 | 42 | //Set the header 43 | header('Content-type: application/pdf'); 44 | readfile($array[$lang]); 45 | 46 | ?> 47 | -------------------------------------------------------------------------------- /login.php: -------------------------------------------------------------------------------- 1 | "", 10 | 1 => "Your account need verification", 11 | 2 => "The osu!id, the username or the password is invalid, ", 12 | 3 => "The reCaptcha is invalid, please try again", 13 | 4 => "Verification completed, you can now login", 14 | 5 => "Please enter a number into the osu!ID field" 15 | ); 16 | 17 | 18 | ?> 19 | 20 | 21 | 22 | osu!replayViewer - Login 23 | 24 | 25 | 26 | 27 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 |
50 | 51 | 52 | 53 |

Login

54 |
55 | 56 |
57 | 58 |
Find my osu!ID 59 | 60 |
61 | 62 | 63 | 64 | 65 |
66 | 67 | '; 73 | echo ''.$errors[$error_id]; 74 | switch($error_id){ 75 | case 1 : 76 | $link = $baseLink."userVerification.php?id=".$_GET['userId']; 77 | echo ' click here! '; 78 | break; 79 | case 2 : 80 | $link = $baseLink."register.php"; 81 | echo ' create an account here! '; 82 | break; 83 | default : 84 | break; 85 | } 86 | } 87 | ?> 88 | 89 | 92 |
93 | 94 |
95 | 96 | Forgot password? 97 |
98 |
99 | 100 |
101 |
102 |
103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /loginForm.php: -------------------------------------------------------------------------------- 1 | connect_error) { 17 | die("Connection failed: " . $conn->connect_error); 18 | header("Location:index.php?error=3"); 19 | exit; 20 | } 21 | 22 | // ******************** Functions ********************************** 23 | function close($conn){ 24 | $conn->close(); 25 | exit; 26 | } 27 | 28 | function verifyCaptcha($cResponse) 29 | { 30 | //POST request 31 | $key = getenv('CAPTCHA_KEY'); 32 | $url = "https://www.google.com/recaptcha/api/siteverify?secret=$key&response=$cResponse"; 33 | $ch = curl_init(); 34 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 35 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 36 | curl_setopt($ch, CURLOPT_URL,$url); 37 | $result=curl_exec($ch); 38 | curl_close($ch); 39 | 40 | $json = json_decode($result, true); 41 | return $json['success']; 42 | } 43 | // ******************** Core ********************************** 44 | $userJSON = getUserJSON($userId,$osuApiKey); 45 | $userId = $userJSON[0]['user_id']; 46 | 47 | $query = $conn->prepare("SELECT * FROM accounts WHERE userId=?"); 48 | $query->bind_param("i",$userId); 49 | $query->execute(); 50 | $result = $query->get_result(); 51 | $query->close(); 52 | 53 | if(strcmp(intval($userId),$userId) != 0){ 54 | header("Location:login.php?error=5"); 55 | close($conn); 56 | } 57 | 58 | //check reCaptcha (avoid bot) 59 | if (!verifyCaptcha($_POST['g-recaptcha-response'])) { 60 | header("Location:login.php?error=3"); 61 | close($conn); 62 | } 63 | 64 | if($result->num_rows < 1){ //Check if the account exist 65 | header("Location:login.php?error=2"); 66 | close($conn); 67 | } 68 | 69 | //Check if the account need verification 70 | while($row = $result->fetch_assoc()){ 71 | $verfUserId = $row['verificationId']; 72 | $verfIdEmail = $row['verfIdEmail']; 73 | $passwordHash = $row['password']; 74 | $userUsername = $row['username']; 75 | } 76 | 77 | //Check password 78 | if(!password_verify($userPassword,$passwordHash)){ 79 | header("Location:login.php?error=2"); 80 | close($conn); 81 | } 82 | 83 | if((empty($verfUserId) && empty($verfIdEmail)) == false){ 84 | header("Location:login.php?error=1&userId=".$userId); 85 | close($conn); 86 | } 87 | 88 | //Everything is valid create a new session 89 | session_start(); 90 | $_SESSION["userId"] = $userId; 91 | $_SESSION["username"] = $userUsername; 92 | header("Location:index.php"); 93 | ?> 94 | -------------------------------------------------------------------------------- /logout.php: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /maintenance.php: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Maintenance 12 | 13 | 14 | 15 | 21 | 22 | 23 | 24 |

25 | maintenance in progress, please come back later. 26 | 27 |

28 | 29 | 30 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "osu-replayviewer-web", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@fortawesome/fontawesome-free": { 8 | "version": "5.10.2", 9 | "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.10.2.tgz", 10 | "integrity": "sha512-9pw+Nsnunl9unstGEHQ+u41wBEQue6XPBsILXtJF/4fNN1L3avJcMF/gGF86rIjeTAgfLjTY9ndm68/X4f4idQ==", 11 | "dev": true 12 | }, 13 | "bulma": { 14 | "version": "0.7.5", 15 | "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.7.5.tgz", 16 | "integrity": "sha512-cX98TIn0I6sKba/DhW0FBjtaDpxTelU166pf7ICXpCCuplHWyu6C9LYZmL5PEsnePIeJaiorsTEzzNk3Tsm1hw==" 17 | }, 18 | "bulma-tooltip": { 19 | "version": "2.0.2", 20 | "resolved": "https://registry.npmjs.org/bulma-tooltip/-/bulma-tooltip-2.0.2.tgz", 21 | "integrity": "sha512-xsqWeWV7tsUn3uH04SqJeP7/CyC1RaDVIyVzr4/sIO3friIIOi7L6jc5g7qUwDxuBQl72yH/yRPuefpXoQ4hWg==" 22 | }, 23 | "cool-checkboxes-for-bulma.io": { 24 | "version": "1.1.0", 25 | "resolved": "https://registry.npmjs.org/cool-checkboxes-for-bulma.io/-/cool-checkboxes-for-bulma.io-1.1.0.tgz", 26 | "integrity": "sha512-RDEXOeS9COGTbQjlwRQzPRwOA8ycP4azc/GDVF5qYSOs4tYk6dc9SWNOj7Bb/NvhVUsb+H95pNtGgOBwCENBQg==" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "osu-replayviewer-web", 3 | "version": "1.0.0", 4 | "description": "Easy to use website. Just upload your .osr, wait for processing and share it to your friends", 5 | "main": "index.js", 6 | "directories": { 7 | "lib": "lib" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/DevEkode/osu-replayViewer-web.git" 15 | }, 16 | "author": "", 17 | "license": "ISC", 18 | "bugs": { 19 | "url": "https://github.com/DevEkode/osu-replayViewer-web/issues" 20 | }, 21 | "homepage": "https://github.com/DevEkode/osu-replayViewer-web#readme", 22 | "dependencies": { 23 | "bulma": "^0.7.5", 24 | "bulma-tooltip": "^2.0.2", 25 | "cool-checkboxes-for-bulma.io": "^1.1.0" 26 | }, 27 | "devDependencies": { 28 | "@fortawesome/fontawesome-free": "^5.10.2" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /patreon.php: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 35 | 36 | osu!replayViewer - Patreon supporters page 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 |

Patreon supporters

65 | 66 |

Help me build this project !

67 | 68 |
69 | Become a Patron! 70 |
71 |
72 |
73 | 74 |
75 | 76 |
77 | 78 | -------------------------------------------------------------------------------- /php.ini: -------------------------------------------------------------------------------- 1 | upload_max_filesize = 200M 2 | 3 | post_max_size = 200M 4 | 5 | display_errors = 0 6 | error_reporting = E_ALL & ~E_NOTICE 7 | zlib.output_compression = true 8 | -------------------------------------------------------------------------------- /php/MysqlAgent.php: -------------------------------------------------------------------------------- 1 | mysql_conn = new mysqli(getenv('MYSQL_HOST'), getenv('MYSQL_USER'), getenv('MYSQL_PASS'), getenv('MYSQL_DB')); 17 | //Check error 18 | if ($this->mysql_conn->connect_error) { 19 | die("Connection failed: " . $this->mysql_conn->connect_error); 20 | } 21 | return $this->mysql_conn; 22 | } 23 | 24 | public function close() 25 | { 26 | $this->mysql_conn->close(); 27 | } 28 | 29 | /** 30 | * @return mysqli 31 | */ 32 | public function getMysqlConn(): mysqli 33 | { 34 | return $this->mysql_conn; 35 | } 36 | 37 | /** 38 | * @param mysqli $mysql_conn 39 | */ 40 | public function setMysqlConn(mysqli $mysql_conn): void 41 | { 42 | $this->mysql_conn = $mysql_conn; 43 | } 44 | 45 | 46 | } -------------------------------------------------------------------------------- /php/admins.php: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /php/autoAccountDelete.php: -------------------------------------------------------------------------------- 1 | connect_error) { 15 | die("Connection failed: " . $conn->connect_error); 16 | exit; 17 | } 18 | 19 | function getRemovableAccounts($conn, $timeLimit) 20 | { 21 | $array = array(); 22 | 23 | $query = $conn->prepare("SELECT * FROM accounts WHERE date < DATE_SUB(now(), INTERVAL '$timeLimit' DAY) AND verificationId<>\"\" AND verfIdEmail<>\"\" "); 24 | $query->execute(); 25 | $result = $query->get_result(); 26 | while ($row = $result->fetch_assoc()) { 27 | $userId = $row["userId"]; 28 | $canBeDeleted = $row["canBeDeleted"]; 29 | if ($canBeDeleted) { 30 | array_push($array, $userId); 31 | } 32 | } 33 | $query->close(); 34 | return $array; 35 | } 36 | 37 | function deleteAccount($conn, $userId) 38 | { 39 | //detete account from database 40 | $query = $conn->prepare("DELETE FROM accounts WHERE userId=?"); 41 | $query->bind_param("i", $userId); 42 | $query->execute(); 43 | $query->close(); 44 | 45 | //TODO delete account folder form server 46 | } 47 | 48 | function cleanFolder($dir) 49 | { 50 | //delete all folder files 51 | $files = glob($dir . "/*"); // get all file names 52 | foreach ($files as $file) { // iterate files 53 | if (is_file($file)) { 54 | unlink($file); // delete file 55 | } 56 | } 57 | } 58 | 59 | function removeFolder($dir) 60 | { 61 | cleanFolder($dir); 62 | //delete folder 63 | rmdir($dir); 64 | } 65 | 66 | $accountsToRemove = getRemovableAccounts($conn, $timeLimit); 67 | if (!empty($accountsToRemove)) { 68 | foreach ($accountsToRemove as $userId) { 69 | deleteAccount($conn, $userId); 70 | echo 'Deleted account with id ' . $userId . '
'; 71 | } 72 | } else { 73 | echo 'No account to delete'; 74 | } 75 | ?> 76 | -------------------------------------------------------------------------------- /php/disableUploads.php: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /php/errors.php: -------------------------------------------------------------------------------- 1 | 'Mysql connection error', 6 | 2 => 'Cannot get replay data', 7 | 3 => 'Cannot get beatmap data', 8 | 4 => 'Cannot get player data', 9 | 5 => 'INSERT INTO mysql database failed', 10 | 6 => 'Cannot create replay directory', 11 | 7 => 'Cannot move replay to final destination', 12 | 8 => 'You have to accept terms of uses', 13 | 9 => 'Uploads are disabled', 14 | 10 => 'Upload rate exceeded' 15 | ); 16 | 17 | $editProfileErrors = array( 18 | 1 => 'Session error', 19 | 2 => 'This user doesn\'t exists', 20 | 3 => "Actual password doesn't match", 21 | 4 => "Database error", 22 | 5 => "New password doesn't match with the verification", 23 | 6 => "Database error", 24 | 7 => "This skin has already been uploaded", 25 | 8 => "Only .osk files are allowed", 26 | 9 => "Sorry, your skin couldn't be uploaded", 27 | 10 => "Your skin file name cannot contain special characters", 28 | 11 => "Your skin file size is more than 50Mb", 29 | 12 => "This skin doesn't exist", 30 | 13 => "Remove error", 31 | 14 => 'The server has received a null $_FILES' 32 | ); 33 | 34 | $progressErrors = array( 35 | 1 => 'This file doesn\'t matches with the original' 36 | ); 37 | 38 | // ---- Index ---- 39 | //Link array with corresponding page 40 | $indexOfPages = array( 41 | '/index.php' => $uploadErrors, 42 | '/editProfile.php' => $editProfileErrors, 43 | '/progress.php' => $progressErrors 44 | ); 45 | 46 | function showErrorModal($error,$errorMsg = null){ 47 | date_default_timezone_set("Europe/Paris"); 48 | $date = date('d/m/Y - H:i'); 49 | $page = $_SERVER['PHP_SELF']; 50 | echo << 52 | 53 | 68 | EOF; 69 | } 70 | 71 | //Take the error var in GET and show the error modal 72 | function showError(){ 73 | global $indexOfPages; 74 | $array = $indexOfPages[$_SERVER['PHP_SELF']]; 75 | if(isset($_GET['error']) && !empty($array) && in_array($_GET['error'],array_keys($array))){ 76 | if(isset($_GET['errorMsg'])){ 77 | showErrorModal($array[$_GET['error']],$_GET['errorMsg']); 78 | }else{ 79 | showErrorModal($array[$_GET['error']]); 80 | } 81 | } 82 | } 83 | ?> 84 | -------------------------------------------------------------------------------- /php/fillReplayStats.php: -------------------------------------------------------------------------------- 1 | connect_error) { 9 | die("Connection failed: " . $conn->connect_error); 10 | header("Location:index.php?error=3"); 11 | exit; 12 | } 13 | 14 | //Get replays 15 | $query = $conn->prepare("SELECT * FROM replaylist"); 16 | $query->execute(); 17 | $result = $query->get_result(); 18 | if($result->num_rows > 0){ 19 | while($row = $result->fetch_assoc()){ 20 | 21 | //Gatter info 22 | $playMod = $row['playMod']; 23 | $binaryMods = $row['binaryMods']; 24 | 25 | 26 | } 27 | } 28 | $query->close(); 29 | 30 | ?> 31 | -------------------------------------------------------------------------------- /php/ftp_agent.class.php: -------------------------------------------------------------------------------- 1 | root_dir = getenv('FTP_DIR'); 17 | $this->conn = new \phpseclib\Net\SFTP(getenv('FTP_HOST')); 18 | 19 | $login_result = $this->conn->login(getenv('FTP_USER'), getenv('FTP_PASS')); 20 | $this->conn->chdir($this->root_dir); 21 | // Vérification de la connexion 22 | if ((!$this->conn) || (!$login_result)) { 23 | return false; 24 | } else { 25 | $this->conn->chdir($this->root_dir); 26 | return true; 27 | } 28 | } 29 | 30 | public function disconnect(){ 31 | $this->conn->close(); 32 | } 33 | 34 | //Folders 35 | public function mkdir($dir){ 36 | $result = $this->conn->mkdir($this->conn, $dir); 37 | $this->conn->chmod(0777, $dir); 38 | if($result) {return true;} 39 | else {return false;} 40 | } 41 | 42 | public function dirExists($dir){ 43 | $dir = $dir.'/'; 44 | if ($this->conn->chdir($dir)) { 45 | return true; 46 | }else{ 47 | return false; 48 | } 49 | } 50 | 51 | public function removeFolder($dir){ 52 | $dir = $dir.'/'; 53 | var_dump($this->root_dir.$dir); 54 | $this->cleanFolder($dir); 55 | $result = $this->conn->rmdir($dir); 56 | 57 | if($result) {return true;} 58 | else {return false;} 59 | } 60 | 61 | public function cleanFolder($dir){ //remove all files from a folder 62 | $fichiers = $this->conn->nlist($dir); 63 | var_dump($fichiers); 64 | 65 | foreach($fichiers as &$fichier){ 66 | $this->removeFile($dir.$fichier); 67 | } 68 | } 69 | 70 | //files 71 | public function fileExists($fileName,$dir){ 72 | $contents_on_server = $this->conn->nlist($dir); 73 | if(in_array($fileName,$contents_on_server)){ 74 | return true; 75 | }else{ 76 | return false; 77 | } 78 | } 79 | 80 | public function removeFile($dir){ 81 | $result = $this->conn->delete($dir); 82 | if($result) {return true;} 83 | else {return false;} 84 | } 85 | 86 | public function sendFile($fileDir,$newDir){ 87 | $upload = $this->conn->put($fileDir, $newDir); 88 | 89 | // Vérification du status du chargement 90 | if (!$upload) { 91 | return false; 92 | } else { 93 | return true; 94 | } 95 | } 96 | 97 | public function downloadFile($fileDir,$newDir){ 98 | $result = $this->conn->get($fileDir, $newDir); 99 | if($result) {return true;} 100 | else {return false;} 101 | } 102 | 103 | public function listFiles($fileDir) 104 | { 105 | return $this->conn->nlist($fileDir); 106 | } 107 | 108 | } 109 | 110 | 111 | 112 | ?> 113 | -------------------------------------------------------------------------------- /php/getUserId.php: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /php/getUsername.php: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /php/index.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/php/index.php -------------------------------------------------------------------------------- /php/index/UploadLimiter.php: -------------------------------------------------------------------------------- 1 | adapter = new StashAdapter($stash); 18 | $this->rateLimiter = new RateLimit("uploadLimiters", getenv("UPLOAD_LIMIT_PER_DAY"), 86400, $this->adapter); 19 | } 20 | 21 | public function canUserUpload(): bool 22 | { 23 | //Check with ip 24 | $ip = $_SERVER['REMOTE_ADDR']; 25 | if ($this->rateLimiter->check($ip)) { 26 | return true; 27 | } 28 | return false; 29 | } 30 | 31 | public function getUploadsRemaining(): int 32 | { 33 | $ip = $_SERVER['REMOTE_ADDR']; 34 | return $this->rateLimiter->getAllowance($ip); 35 | } 36 | 37 | public function getTimeRemaining() 38 | { 39 | $ip = $_SERVER['REMOTE_ADDR']; 40 | return $this->rateLimiter->getTimeLeft($ip); 41 | } 42 | 43 | public static function getINSTANCE(): UploadLimiter 44 | { 45 | if (is_null(self::$INSTANCE)) { 46 | self::$INSTANCE = new UploadLimiter(); 47 | } 48 | return self::$INSTANCE; 49 | } 50 | } -------------------------------------------------------------------------------- /php/index/clearSession.php: -------------------------------------------------------------------------------- 1 | 38 | -------------------------------------------------------------------------------- /php/index/newUsername.php: -------------------------------------------------------------------------------- 1 | $playername, 'replay_playerId' => $replay_playerId, 'playerOsuAccount' => true); 18 | $session = array_replace($session,$remplacement); 19 | 20 | $_SESSION = array_merge($_SESSION,$session); 21 | 22 | header('Location:../../index.php'); 23 | ?> 24 | -------------------------------------------------------------------------------- /php/index/upload.php: -------------------------------------------------------------------------------- 1 | connect_error) { 13 | die("Connection failed: " . $conn->connect_error); 14 | header("Location:../../index.php?error=1"); 15 | exit; 16 | } 17 | 18 | //---- get all the Informations ---- 19 | //Cancel if the TU is not accepted 20 | if(!isset($_POST['checkboxTU']) && $_POST['checkboxTU'] != "true"){ 21 | header("Location:../../index.php?error=8"); 22 | exit; 23 | } 24 | 25 | //Check rate limit 26 | $limiter = UploadLimiter::getINSTANCE(); 27 | if (!$limiter->canUserUpload()) { 28 | header("Location:../../index.php?error=10"); 29 | exit; 30 | } 31 | 32 | //get replay file Informations 33 | $replayJSON = getReplayContent("../../uploads/".$_POST['filename']); 34 | 35 | //Create replayId 36 | date_default_timezone_set('Europe/Paris'); 37 | $replayId = uniqid(); 38 | 39 | //persistance 40 | //if(isset($_POST['checkbox']) && $_POST["checkbox"] != NULL){ 41 | // $persistance = 1; 42 | //}else{ 43 | // $persistance = 0; 44 | //} 45 | $persistance = 0; 46 | 47 | //beatmap Informations 48 | $beatmapJSON = getBeatmapJSONwMD5($replayJSON['md5'],$osuApiKey); 49 | 50 | $beatmapId = $beatmapJSON[0]['beatmap_id']; 51 | $beatmapSetId = $beatmapJSON[0]['beatmapset_id']; 52 | $beatmapName = base64_encode(generateBtFileNamewJSON($beatmapJSON)); 53 | 54 | //replay Informations 55 | $replayName = base64_encode($_POST['filename']); 56 | $replayDuration = $_POST['duration']; 57 | $fileMD5 = md5_file("../../uploads/".$_POST['filename']); 58 | $replayMod = $replayJSON['gamemode']; 59 | $binaryMods = $replayJSON['Mods']; 60 | 61 | //player Informations 62 | $playerJSON = getUserJSON($replayJSON['user'],$osuApiKey); 63 | $playerId = $_POST['userId']; 64 | 65 | //---- Send the Informations into the database ---- 66 | $sql = "INSERT INTO requestlist (replayId,beatmapId,beatmapSetId,OFN,BFN,duration,playerId,md5,playMod,binaryMods,persistance) VALUES (?,?,?,?,?,?,?,?,?,?,?)"; 67 | 68 | $stmt = $conn->prepare($sql); 69 | $stmt->bind_param("siissiisiii", 70 | $replayId, 71 | $beatmapId, 72 | $beatmapSetId, 73 | $replayName, 74 | $beatmapName, 75 | $replayDuration, 76 | $playerId, 77 | $fileMD5, 78 | $replayMod, 79 | $binaryMods, 80 | $persistance); 81 | 82 | if ($stmt->execute()) { 83 | //row created 84 | } else { 85 | echo "Error: " . $sql . "
" . $conn->error; 86 | $conn->close(); 87 | header("Location:../../index.php?error=5"); 88 | exit; 89 | } 90 | 91 | $btContent = getBeatmapJSONwMods($replayJSON['md5'], $replayJSON['Mods'], $osuApiKey); 92 | $replayAcc = getReplayAccuracy($replayJSON); 93 | $pp = 0; 94 | 95 | $stmt = $conn->prepare("INSERT INTO replaystats (replayId, gamemode, modsBinary, stars, pp, acc, ar, BPM, x300, x100, x50, gekis, katus, miss, t_score, max_combo, perfect) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); 96 | $stmt->bind_param('siidddddiiiiiiiii', 97 | $replayId, 98 | $replayJSON['gamemode'], 99 | $replayJSON['Mods'], 100 | $btContent[0]['difficultyrating'], 101 | $pp, 102 | $replayAcc, 103 | $btContent[0]['diff_approach'], 104 | $btContent[0]['bpm'], 105 | $replayJSON['x300'], 106 | $replayJSON['x100'], 107 | $replayJSON['x50'], 108 | $replayJSON['Gekis'], 109 | $replayJSON['Katus'], 110 | $replayJSON['Miss'], 111 | $replayJSON['Score'], 112 | $replayJSON['MaxCombo'], 113 | $replayJSON['perfectCombo']); 114 | 115 | if ($stmt->execute()) { 116 | //row created 117 | } else { 118 | echo "Error: " . $sql . "
" . $conn->error; 119 | header("Location:../../index.php?error=3&sqlErr=" . $conn->error); 120 | closeUpload($conn); 121 | } 122 | 123 | //Deplacement du fichier en liste d'attente 124 | if(!mkdir('../../requestList/'.$replayId, 0777, true)){ 125 | header("Location:../../index.php?error=6"); 126 | } 127 | if(!rename('../../uploads/'.$_POST['filename'],'../../requestList/'.$replayId.'/'.$_POST['filename'])){ 128 | header("Location:../../index.php?error=7"); 129 | } 130 | 131 | $conn->close(); 132 | include 'clearSession.php'; 133 | header("Location:../../progress.php?id=".$replayId); 134 | exit; 135 | 136 | 137 | 138 | 139 | ?> 140 | -------------------------------------------------------------------------------- /php/navbar.php: -------------------------------------------------------------------------------- 1 | 16 |
17 | 23 | 24 | 27 | EOF; 28 | //Show php part 29 | 30 | if(isset($_SESSION['userId']) && isset($_SESSION['username'])){ 31 | $userUrl = "userProfile.php?id=".$_SESSION['userId']; 32 | echo ''; 38 | }else{ 39 | echo '
'; 40 | echo ''; 41 | echo 'how_to_reg Register'; 42 | echo ''; 43 | echo 'vpn_key Login'; 44 | echo '
'; 45 | } 46 | 47 | echo '
'; 48 | } 49 | 50 | function showFooter(){ 51 | echo << 53 |

osu!replayViewer is not affiliated with osu! - All credit to Dean Herbert

54 | 93 | 94 |
95 | website created by Ekode 96 | 97 | codevirtuel profile image 104 | 105 | 106 |
107 | 108 | EOF; 109 | } 110 | 111 | ?> -------------------------------------------------------------------------------- /php/patreon/1_pledgers.txt: -------------------------------------------------------------------------------- 1 | Josh Baker -------------------------------------------------------------------------------- /php/patreon/5_pledgers.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevEkode/osu-replayViewer-web/14262094e3f6660aea3565895930609f90852b20/php/patreon/5_pledgers.txt -------------------------------------------------------------------------------- /php/patreon/getPledgers.php: -------------------------------------------------------------------------------- 1 | '1_pledgers.txt', 13 | 1 => '5_pledgers.txt' 14 | ); 15 | 16 | //Creating URL request 17 | 18 | $url = 'https://www.patreon.com/api/oauth2/api/current_user/campaigns?access_token=' . getenv('PATREON_KEY'); 19 | 20 | //Get response json 21 | $url_content = file_get_contents($url); 22 | $json = json_decode($url_content); 23 | 24 | //Get rewards 25 | $rewards = array(); 26 | $index = 0; 27 | foreach($json->included as $data){ 28 | //Check if the data is a reward 29 | if(strcmp($data->type,'reward') == 0){ 30 | if($data->id == -1 || $data->id == 0) continue; 31 | $newData = $data->attributes; 32 | 33 | //Add pledgers names 34 | $pledgers = explode(";",file_get_contents('./'.$files[$index])); 35 | $newData->pledgers = $pledgers; 36 | 37 | array_push($rewards,$newData); 38 | $index++; 39 | } 40 | } 41 | 42 | header('Content-type: application/json'); 43 | echo json_encode($rewards); 44 | ?> -------------------------------------------------------------------------------- /php/profile/blockManager.php: -------------------------------------------------------------------------------- 1 | '; 22 | break; 23 | case 'pending': 24 | block_replayPending(); 25 | echo '
'; 26 | break; 27 | case 'graveyard': 28 | block_replayGraveyard(); 29 | echo '
'; 30 | break; 31 | case 'skin': 32 | block_skinChooser(); echo '
'; 33 | block_skinUploader(); echo '
'; 34 | block_skinRemover(); echo '
'; 35 | break; 36 | case 'game': 37 | block_dimChooser(); echo '
'; 38 | block_gameSettingsChooser(); echo '
'; 39 | block_cursorSizeChooser(); echo '
'; 40 | block_volumeChooser(); echo '
'; 41 | break; 42 | case 'security': 43 | block_changePassword(); echo '
'; 44 | block_changeEmail(); echo '
'; 45 | block_removeAccount(); echo '
'; 46 | break; 47 | } 48 | } 49 | 50 | function generateMenu(){ 51 | echo << 53 | 54 |