Skip to content

Instantly share code, notes, and snippets.

@Bluscream
Last active July 5, 2024 18:28
Show Gist options
  • Save Bluscream/a82c140f081ba14a23fe77409b4296b8 to your computer and use it in GitHub Desktop.
Save Bluscream/a82c140f081ba14a23fe77409b4296b8 to your computer and use it in GitHub Desktop.
Overwolf WebApp Generator

Overwolf WebApp Generator

Generates simple Overwolf WebApps for displaying websites as Overlays

To use it, simply drop the php file somewhere on a webserver using PHP >8, download the accompanying template and extract it into a template/ subfolder next to the php file

<?php
// ini_set('display_errors', 1);
// ini_set('display_startup_errors', 1);
// error_reporting(E_ALL);
// Template can be found at https://github.com/OverwolfApps/template
$replacements = [
"url" => "https://minopia.de/ow/webapp-generator/",
"name" => "WebApp Generator",
// "description" => "WebApp Generator WebApp for Overwolf",
"transparent" => "false",
"resizable" => "true",
"block_top_window_navigation" => "false",
"in_game_only" => "false",
"width" => "1280",
"height" => "720",
"top" => "100",
"left" => "100",
"hotkey_toggle" => "Alt+W"
];
$templateDir = 'template/';
$memoryLimit = '1024M';
ob_start();
if (!empty($_GET)) {
foreach ($_GET as $key => $value) {
if (array_key_exists($key, $replacements)) {
$replacements[$key] = $value;
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Overwolf WebApp Generator</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<h2>Generate Overwolf WebApp</h2>
<form method="post" action="" enctype="multipart/form-data">
<?php foreach ($replacements as $replacement => $placeholder): ?>
<div class="mb-3">
<label for="<?= $replacement ?>"
class="form-label"><?= ucfirst(str_replace("_", " ", $replacement)) ?></label>
<input type="text" class="form-control" id="<?= $replacement ?>" name="<?= $replacement ?>"
value="<?= $placeholder ?>">
</div>
<?php endforeach; ?>
<button type="submit" class="btn btn-primary">Generate</button>
</form>
</div>
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!filter_var($_POST["url"], FILTER_VALIDATE_URL)) {
echo "Invalid URL provided.";
exit;
}
ini_set('memory_limit', $memoryLimit);
$generator_url = full_url( $_SERVER );
$now = date('Y-m-d H:i:s');
$url_hash = md5($_POST["url"]);
$archivePath = sys_get_temp_dir() . "/$url_hash.zip";
if (is_file($archivePath))
unlink($archivePath);
$zip = new ZipArchive();
if ($zip->open($archivePath, ZipArchive::CREATE) !== TRUE)
throw new Exception("Unable to create zip file at $archivePath");
$dirIterator = new RecursiveDirectoryIterator($templateDir);
$iterator = new RecursiveIteratorIterator($dirIterator);
foreach ($iterator as $file) {
$file_no_prefix = removeOccurence($file, DIRECTORY_SEPARATOR);
if (str_ends_with($file, '.')) {
} else if (substr($file, -1) === DIRECTORY_SEPARATOR) {
$zip->addEmptyDir($file_no_prefix);
} else {
$get_path = $file->getRealPath();
if (is_file($get_path)) {
$originalFile = fopen($get_path, 'r+');
rewind($originalFile);
$file_content = stream_get_contents($originalFile);
foreach ($replacements as $replacement => $placeholder) {
$file_content = str_replace("{" . $replacement . "}", $_POST[$replacement], $file_content);
}
$file_content = str_replace('{now}', $now, $file_content);
$file_content = str_replace('{generator_url}', $generator_url, $file_content);
rewind($originalFile);
$zip->addFromString($file_no_prefix, $file_content);
fclose($originalFile);
}
}
}
$zip->addFromString('icons/IconMouseNormal.png', fetchFaviconAsString($_POST["url"]));
$zip->close();
header('Content-Type: application/zip');
$archiveName = $_POST["name"] . '.opk';
header('Content-Disposition: attachment; filename="' . $archiveName . '"');
readfile($archivePath);
unlink($archivePath); // Clean up the ZIP file after sending
}
function removeOccurence(string $input, string $separator, int $occurence = 0): string
{
$split = explode($separator, $input);
unset($split[$occurence]);
return implode($separator, $split);
}
function removeDir(string $dir): void
{
$it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($files as $file) {
if ($file->isDir()) {
rmdir($file->getPathname());
} else {
unlink($file->getPathname());
}
}
rmdir($dir);
}
function fetchFaviconAsString($url) : string {
$faviconUrl = "https://t2.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&size=64&url=" . urlencode($url);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $faviconUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$content = curl_exec($ch);
curl_close($ch);
if ($content === false)
return false;
return $content;
}
function url_origin( $s, $use_forwarded_host = false ) : string {
$ssl = ( ! empty( $s['HTTPS'] ) && $s['HTTPS'] == 'on' );
$sp = strtolower( $s['SERVER_PROTOCOL'] );
$protocol = substr( $sp, 0, strpos( $sp, '/' ) ) . ( ( $ssl ) ? 's' : '' );
$port = $s['SERVER_PORT'];
$port = ( ( ! $ssl && $port=='80' ) || ( $ssl && $port=='443' ) ) ? '' : ':'.$port;
$host = ( $use_forwarded_host && isset( $s['HTTP_X_FORWARDED_HOST'] ) ) ? $s['HTTP_X_FORWARDED_HOST'] : ( isset( $s['HTTP_HOST'] ) ? $s['HTTP_HOST'] : null );
$host = isset( $host ) ? $host : $s['SERVER_NAME'] . $port;
return $protocol . '://' . $host;
}
function full_url( $s, $use_forwarded_host = false ) : string {
return url_origin( $s, $use_forwarded_host ) . $s['REQUEST_URI'];
}
?>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
var urlParams = new URLSearchParams(window.location.search);
var submitParam = urlParams.get('submit');
if (submitParam) document.querySelector('form').submit();
});
</script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment