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/[email protected]/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/[email protected]/dist/umd/popper.min.js"></script> | |
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script> | |
</body> | |
</html> |