Skip to content

Commit

Permalink
Merge pull request #126 from Team-VoW/development
Browse files Browse the repository at this point in the history
Releases with remotely hosted JAR files and fixes
  • Loading branch information
ShadyMedic authored Sep 25, 2024
2 parents 61d05e8 + 54892df commit bb85613
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 48 deletions.
3 changes: 3 additions & 0 deletions Controllers/Website/Administration/NewRelease.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ private function get(array $args): int
self::$data['newrelease_wynn_version'] = '';
self::$data['newrelease_mc_version'] = '';
self::$data['newrelease_filename'] = '';
self::$data['newrelease_download_link'] = '';
self::$data['newrelease_changelog'] = '';
self::$data['newrelease_error'] = '';
self::$data['newrelease_releaseId'] = '';
Expand All @@ -54,6 +55,7 @@ private function post(array $args): int
$_POST['wynnVersion'],
$_POST['version'],
$_POST['changelog'],
$_POST['downloadLink'],
$_POST['filename']
);
self::$data['newrelease_releaseId'] = $releaseId;
Expand All @@ -64,6 +66,7 @@ private function post(array $args): int
self::$data['newrelease_wynn_version'] = $_POST['wynnVersion'];
self::$data['newrelease_mc_version'] = $_POST['mcVersion'];
self::$data['newrelease_filename'] = $_POST['filename'];
self::$data['newrelease_download_link'] = $_POST['downloadLink'];
self::$data['newrelease_changelog'] = $_POST['changelog'];
self::$data['newrelease_error'] = $e->getMessage();
}
Expand Down
2 changes: 1 addition & 1 deletion Models/Website/ContentManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public function getQuests(?int $questId = null): array
FROM quest
JOIN npc_quest ON npc_quest.quest_id = quest.quest_id
JOIN npc ON npc.npc_id = npc_quest.npc_id
JOIN recording ON recording.npc_id = npc.npc_id AND recording.quest_id = quest.quest_id
LEFT JOIN recording ON recording.npc_id = npc.npc_id AND recording.quest_id = quest.quest_id
LEFT JOIN user ON npc.voice_actor_id = user.user_id
'.(is_null($questId) ? '' : 'WHERE quest.quest_id = ?').'
GROUP BY quest.quest_id, npc.npc_id, npc_quest.sorting_order
Expand Down
48 changes: 29 additions & 19 deletions Models/Website/DownloadsManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,37 +59,42 @@ public function downloadFile(string $fileType, int $downloadId): bool
$db = new Db('Website/DbInfo.ini');

if ($fileType === self::DOWNLOAD_TYPE_MODFILE) {
$result = $db->fetchQuery('SELECT filename,mc_version,version FROM download WHERE download_id = ?', array($downloadId));
$result = $db->fetchQuery('SELECT download_link,filename,mc_version,version,size FROM download WHERE download_id = ?', array($downloadId));
if ($result === false) {
return false;
}

$filePath = self::ROOT_DOWNLOADS_DIRECTORY.'/'.$result['filename'];
$filePath = empty($result['download_link']) ? self::ROOT_DOWNLOADS_DIRECTORY.'/'.$result['filename'] : $result['download_link'];
$fileName = str_replace('{mcVersion}', $result['mc_version'],
str_replace('{version}', $result['version'], self::FILE_NAME_FORMATS)
);
$fileSize = $result['size'];
} else if ($fileType === self::DOWNLOAD_TYPE_INSTALLER) {
$filePath = self::ROOT_DOWNLOADS_DIRECTORY.'/'.self::INSTALLER_FILE_NAME;
$fileName = self::INSTALLER_FILE_NAME;
$fileSize = filesize($filePath);
} else {
throw new InvalidArgumentException('Invalid download type.');
}

$obContent = ob_get_contents(); //Pause the output bufferer to prevent memory overflow caused by "readfile()"
ob_end_clean();

header('Content-Description: File Transfer');
header('Content-Type: application/java-archive');
header('Content-Disposition: attachment; filename="'.$fileName.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: '.filesize($filePath));
readfile($filePath);

ob_start(); //Resume the output bufferer
echo $obContent;

if (!empty($result['download_link'])) {
header('Location: '.$result['download_link']); //Remote download
} else {
$obContent = ob_get_contents(); //Pause the output bufferer to prevent memory overflow caused by "readfile()"
ob_end_clean();

header('Content-Description: File Transfer');
header('Content-Type: application/java-archive');
header('Content-Disposition: attachment; filename="'.$fileName.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: '.$fileSize);
readfile($filePath);

ob_start(); //Resume the output bufferer
echo $obContent;
}
return $db->executeQuery('UPDATE download SET downloaded_times = downloaded_times + 1 WHERE download_id = ?', array($downloadId));
}

Expand All @@ -99,30 +104,35 @@ public function downloadFile(string $fileType, int $downloadId): bool
* @param string $wynnVersion Version of Wynncraft for which this download is made
* @param string $version Version of the mod
* @param string $changelog HTML text containing the changelog for the new version
* @param string $downloadLink Direct download link (not required if $filename is provided and vice-versa)
* @param string $filename Name of the file on the server. NOTE: The .jar file must be uploaded into the /files/mod directory when this function is run
* @return int ID of the new release if the download has successfully been created
* @throws UserException In case one or more of the provided strings is invalid
*/
public function createDownload(string $type, string $mcVersion, string $wynnVersion, string $version, string $changelog, string $filename): int
public function createDownload(string $type, string $mcVersion, string $wynnVersion, string $version, string $changelog, string $downloadLink, string $filename): int
{
$download = new ModDownload(array(
'type' => $type,
'mcVersion' => $mcVersion,
'wynnVersion' => $wynnVersion,
'version' => $version,
'changelog' => $changelog,
'download_link' => $downloadLink,
'filename' => $filename,
'date' => date('Y-m-d')
));

$download->validate();

$db = new Db('Website/DbInfo.ini');
return $db->executeQuery('INSERT INTO download(release_type,mc_version,wynn_version,version,changelog,filename,size) VALUES (?,?,?,?,?,?,?)', array(
return $db->executeQuery('INSERT INTO download(release_type,mc_version,wynn_version,version,changelog,download.release_date,download_link,filename,size) VALUES (?,?,?,?,?,?,?,?,?)', array(
$download->releaseType,
$download->mcVersion,
$download->wynnVersion,
$download->version,
$download->changelog,
$download->releaseDate->format('Y-m-d'),
$download->downloadLink,
$download->fileName,
$download->size
), true);
Expand Down
82 changes: 57 additions & 25 deletions Models/Website/ModDownload.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ class ModDownload
public string $version;
public string $changelog;
public DateTime $releaseDate;
public string $fileName;
public ?string $downloadLink;
public ?string $fileName;
public int $size;
public int $downloadedTimes;

Expand Down Expand Up @@ -78,6 +79,10 @@ public function __construct(array $data)
$this->releaseDate = new DateTime($value);
}
break;
case 'download_link':
case 'dl_link':
case 'link':
$this->downloadLink = $value;
case 'file':
case 'filename':
case 'fileName':
Expand Down Expand Up @@ -123,7 +128,7 @@ public function validate(): bool
empty($this->wynnVersion) ||
empty($this->version) ||
empty($this->changelog) ||
empty($this->fileName)
(empty($this->fileName) && empty($this->downloadLink))
) {
throw new UserException('All fields must be filled to create a new release');
}
Expand Down Expand Up @@ -161,32 +166,59 @@ public function validate(): bool
$adv = new AccountDataValidator();
$this->changelog = $adv->sanitizeBio($this->changelog); //Purify the HTML for consistent database

//Validate file name
if (!file_exists(DownloadsManager::ROOT_DOWNLOADS_DIRECTORY.'/'.$this->fileName)) {
throw new UserException('Mod file of this name wasn\'t found on the server. Make sure to first log in into website administration and upload the .jar file to /files/mod');
}
//Rename the file in case it doesn't follow the naming convention
$idealFileName = str_replace('.', '_', $this->mcVersion).
'-'.
str_replace('.', '_', $this->version).
'.jar';
if ($this->fileName !== $idealFileName) {
if (file_exists(DownloadsManager::ROOT_DOWNLOADS_DIRECTORY.'/'.$idealFileName)) {
throw new UserException('It looks like the .jar file for this version of the mod is already uploaded. Try changing either the Minecraft version or the Mod version field.');
if (empty($this->downloadLink)) {
//Validate file name or the download link
if (!file_exists(DownloadsManager::ROOT_DOWNLOADS_DIRECTORY . '/' . $this->fileName)) {
throw new UserException('Mod file of this name wasn\'t found on the server. Make sure to first log in into website administration and upload the .jar file to /files/mod');
}
rename(
DownloadsManager::ROOT_DOWNLOADS_DIRECTORY.'/'.$this->fileName,
DownloadsManager::ROOT_DOWNLOADS_DIRECTORY.'/'.$idealFileName
);
$this->fileName = $idealFileName;
}

//Validate size
if (filesize(DownloadsManager::ROOT_DOWNLOADS_DIRECTORY.'/'.$this->fileName) > self::MODFILE_MAX_SIZE) {
throw new UserException('The mod file is too big, its size cannot be saved in the database. Contact shady_medic on Discord to make him increase the maximum value.');
}
$this->size = filesize(DownloadsManager::ROOT_DOWNLOADS_DIRECTORY.'/'.$this->fileName);
//Rename the file in case it doesn't follow the naming convention
$idealFileName = str_replace('.', '_', $this->mcVersion) .
'-' .
str_replace('.', '_', $this->version) .
'.jar';
if ($this->fileName !== $idealFileName) {
if (file_exists(DownloadsManager::ROOT_DOWNLOADS_DIRECTORY . '/' . $idealFileName)) {
throw new UserException('It looks like the .jar file for this version of the mod is already uploaded. Try changing either the Minecraft version or the Mod version field.');
}
rename(
DownloadsManager::ROOT_DOWNLOADS_DIRECTORY . '/' . $this->fileName,
DownloadsManager::ROOT_DOWNLOADS_DIRECTORY . '/' . $idealFileName
);
$this->fileName = $idealFileName;
}

//Validate size
if (filesize(DownloadsManager::ROOT_DOWNLOADS_DIRECTORY . '/' . $this->fileName) > self::MODFILE_MAX_SIZE) {
throw new UserException('The mod file is too big, its size cannot be saved in the database. Contact shady_medic on Discord to make him increase the maximum value.');
}
$this->size = filesize(DownloadsManager::ROOT_DOWNLOADS_DIRECTORY . '/' . $this->fileName);
$this->downloadLink = null;
} else {
$ch = curl_init($this->downloadLink);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HEADER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$contentSize = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
$header = substr($response, 0, $headerSize);
$headers = explode("\r\n", $header);
$contentDisposition = @array_filter($headers, function($element)
{return (stripos($element, 'Content-Disposition:') === 0); })[0];
curl_close($ch);
if ($httpCode >= 300 || (
strpos($contentType, 'application/java-archive') === false &&
strpos($contentDisposition, 'attachment') === false)
) {
throw new UserException("The provided link does not seem to lead to a direct download of a JAR file.".$contentType." ".$contentDisposition);
}
$this->size = $contentSize;
$this->fileName = null;
}
return true;
}

Expand Down
16 changes: 13 additions & 3 deletions Views/new-release.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@
<?php else : ?>
<h2 style="text-align: center;">Create a new release</h2>
<p>
To create a new release, you must first log in to FTP (login details will be provided by Shady#2948 upon request)
To create a new release from a local JAR file, you must first log in to FTP (login details will be provided by @shady_medic upon request)
and upload the .jar file into the 📁<code>files/mod</code> folder. Note the name of the file and fill it in the form
below, along with other details about the release.
</p>
<p>
To create a release from a file uploaded to a cloud storage service (GitHub, CurseForge, Modrinth), obtain a direct
download link first (entering it into the URL bar in an anonymous window will immediately trigger download) and
paste it into the field below.
</p>
<div style="text-align: center;
display: block;">
<form method="post" class="newaccform">
Expand Down Expand Up @@ -40,8 +45,13 @@ display: block;">
</div>
</div>

<label for="filename">File name on the server</label><br>
<input type="text" name="filename" id="filename" placeholder="VoicesOfWynn-MC1.12.2-v1.0.0.jar" value="<?= @${str_replace('-', '', basename(__FILE__, '.phtml')).'_filename'};?>" required/><br><br>
<fieldset>
<label for="filename">File name on the server</label><br>
<input type="text" name="filename" id="filename" placeholder="VoicesOfWynn-MC1.12.2-v1.0.0.jar" value="<?= @${str_replace('-', '', basename(__FILE__, '.phtml')).'_filename'};?>"/>
<br><b>Or</b><br>
<label for="download-link">Direct download link from 3rd-party service</label><br>
<input type="link" name="downloadLink" id="download-link" placeholder="https://mediafilez.forgecdn.net/files/5733/592/Voices-of-Wynn-fabric-1.9.2-fabric%2BMC-1.21.jar" value="<?= @${str_replace('-', '', basename(__FILE__, '.phtml')).'_download_link'};?>"/><br><br>
</fieldset>

<label for="changelog">Changelog</label><br>
<textarea name="changelog" id="changelog">
Expand Down
4 changes: 4 additions & 0 deletions css/administration.css
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ td th {
#filename {
width: 26rem;
}
#download-link {
width: 100%;
}

.error {
margin: 2rem;
text-align: center;
Expand Down

0 comments on commit bb85613

Please sign in to comment.