first commit
This commit is contained in:
commit
1b4073b3a4
3
.htaccess
Normal file
3
.htaccess
Normal file
@ -0,0 +1,3 @@
|
||||
RewriteEngine on
|
||||
RewriteRule ^doppelklinge/? /?p=doppelklinge [L]
|
||||
RewriteRule ^vermessung/? /?p=vermessung [L]
|
7
css/bootstrap.min.css
vendored
Normal file
7
css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
71
css/style.css
Normal file
71
css/style.css
Normal file
@ -0,0 +1,71 @@
|
||||
body {
|
||||
counter-reset: toplist;
|
||||
font-size: .875rem;
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 100;
|
||||
padding: 48px 0 0;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.sidebar {
|
||||
top: 4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-sticky {
|
||||
height: calc(100vh - 48px);
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.sidebar .nav-link {
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.sidebar .nav-link {
|
||||
margin-right: 4px;
|
||||
color: #727272;
|
||||
}
|
||||
|
||||
.sidebar .nav-link.active {
|
||||
color: #2470dc;
|
||||
}
|
||||
|
||||
.sidebar .nav-link:hover,
|
||||
.sidebar .nav-link.active {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.sidebar-heading {
|
||||
font-size: .75rem;
|
||||
}
|
||||
|
||||
/* Navbar */
|
||||
.navbar-brand {
|
||||
padding-top: .75rem;
|
||||
padding-bottom: .75rem;
|
||||
background-color: rgba(0, 0, 0, .25);
|
||||
}
|
||||
|
||||
.navbar .navbar-toggler {
|
||||
top: .25rem;
|
||||
right: 1rem;
|
||||
}
|
||||
|
||||
.navbar .form-control {
|
||||
padding: .75rem 1rem;
|
||||
}
|
||||
|
||||
/* custom */
|
||||
ul.list-top > li::before {
|
||||
counter-increment: toplist;
|
||||
content: "# " counter(toplist) ": ";
|
||||
}
|
BIN
img/logo-big.png
Normal file
BIN
img/logo-big.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 271 KiB |
15
inc/router.inc.php
Normal file
15
inc/router.inc.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
$routes = [
|
||||
'doppelklinge' => 'doppelklinge',
|
||||
'vermessung' => 'vermessung',
|
||||
'default' => 'default'
|
||||
];
|
||||
|
||||
ob_start();
|
||||
if(array_key_exists($_page, $routes))
|
||||
require_once("./pages/{$routes[$_page]}.page.php");
|
||||
else
|
||||
require_once("./pages/{$routes['default']}.page.php");
|
||||
|
||||
$_content = ob_get_contents();
|
||||
ob_end_clean();
|
77
inc/tpl.class.php
Normal file
77
inc/tpl.class.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
class tpl {
|
||||
static $blocks = array();
|
||||
static $cache_path = '/home/users/flumm/tmp/';
|
||||
|
||||
static function view($file, $data = array()) {
|
||||
$cached_file = self::cache($file);
|
||||
extract($data, EXTR_SKIP);
|
||||
require $cached_file;
|
||||
unlink($cached_file);
|
||||
}
|
||||
|
||||
static function cache($file) {
|
||||
if(!file_exists(self::$cache_path))
|
||||
mkdir(self::$cache_path, 0744);
|
||||
$cached_file = self::$cache_path . str_replace(array('/', '.html'), array('_', ''), $file . '.php');
|
||||
if(!file_exists($cached_file) || filemtime($cached_file) < filemtime($file)) {
|
||||
$code = self::includeFiles($file);
|
||||
$code = self::compileCode($code);
|
||||
file_put_contents($cached_file, '<?php class_exists(\'' . __CLASS__ . '\') or exit; ?>' . PHP_EOL . $code);
|
||||
}
|
||||
return $cached_file;
|
||||
}
|
||||
|
||||
static function compileCode($code) {
|
||||
$code = self::compileBlock($code);
|
||||
$code = self::compileYield($code);
|
||||
$code = self::compileEscapedEchos($code);
|
||||
$code = self::compileEchos($code);
|
||||
$code = self::compilePHP($code);
|
||||
return $code;
|
||||
}
|
||||
|
||||
static function includeFiles($file) {
|
||||
$code = file_get_contents($file);
|
||||
preg_match_all('/{% ?(extends|include) ?\'?(.*?)\'? ?%}/i', $code, $matches, PREG_SET_ORDER);
|
||||
foreach($matches as $value)
|
||||
$code = str_replace($value[0], self::includeFiles($value[2]), $code);
|
||||
$code = preg_replace('/{% ?(extends|include) ?\'?(.*?)\'? ?%}/i', '', $code);
|
||||
return $code;
|
||||
}
|
||||
|
||||
static function compilePHP($code) {
|
||||
return preg_replace('~\{%\s*(.+?)\s*\%}~is', '<?php $1 ?>', $code);
|
||||
}
|
||||
|
||||
static function compileEchos($code) {
|
||||
return preg_replace('~\{{\s*(.+?)\s*\}}~is', '<?php echo $1 ?>', $code);
|
||||
}
|
||||
|
||||
static function compileEscapedEchos($code) {
|
||||
return preg_replace('~\{{{\s*(.+?)\s*\}}}~is', '<?php echo htmlentities($1, ENT_QUOTES, \'UTF-8\') ?>', $code);
|
||||
}
|
||||
|
||||
static function compileBlock($code) {
|
||||
preg_match_all('/{% ?block ?(.*?) ?%}(.*?){% ?endblock ?%}/is', $code, $matches, PREG_SET_ORDER);
|
||||
foreach($matches as $value) {
|
||||
if(!array_key_exists($value[1], self::$blocks))
|
||||
self::$blocks[$value[1]] = '';
|
||||
if(strpos($value[2], '@parent') === false)
|
||||
self::$blocks[$value[1]] = $value[2];
|
||||
else
|
||||
self::$blocks[$value[1]] = str_replace('@parent', self::$blocks[$value[1]], $value[2]);
|
||||
$code = str_replace($value[0], '', $code);
|
||||
}
|
||||
return $code;
|
||||
}
|
||||
|
||||
static function compileYield($code) {
|
||||
foreach(self::$blocks as $block => $value) {
|
||||
$code = preg_replace('/{% ?yield ?' . $block . ' ?%}/', $value, $code);
|
||||
}
|
||||
$code = preg_replace('/{% ?yield ?(.*?) ?%}/i', '', $code);
|
||||
return $code;
|
||||
}
|
||||
}
|
||||
?>
|
24
index.php
Normal file
24
index.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
$_page = isset($_GET['p']) ? $_GET['p'] : '';
|
||||
|
||||
require_once('./inc/tpl.class.php');
|
||||
require_once('./inc/router.inc.php');
|
||||
|
||||
$tpl = (object)$tpl;
|
||||
|
||||
if(!@$tpl->debug) {
|
||||
tpl::view('tpl/' . $tpl->file,
|
||||
array_merge([
|
||||
'page' => $_page
|
||||
],
|
||||
gettype($tpl->data) !== 'string' ? $tpl->data : [])
|
||||
);
|
||||
}
|
||||
else {
|
||||
echo "<pre>";
|
||||
print_r($_content);
|
||||
echo "</pre>";
|
||||
}
|
2
js/bootstrap-native.min.js
vendored
Normal file
2
js/bootstrap-native.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
3
pages/default.page.php
Normal file
3
pages/default.page.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
$tpl['file'] = 'default.html';
|
||||
$tpl['data'] = '';
|
41
pages/doppelklinge.page.php
Normal file
41
pages/doppelklinge.page.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
$tpl['file'] = 'doppelklinge.html';
|
||||
$tpl['data'] = [];
|
||||
|
||||
$progress = !empty($_POST['progress']) ? $_POST['progress'] : '';
|
||||
|
||||
if(!empty($progress)) {
|
||||
$list = [];
|
||||
preg_match_all("/(?<task>.*): (?<act>.*) \/ (?<max>.*)/m", $progress, $tmp);
|
||||
|
||||
for($i = 0; $i < count($tmp[0]); $i++) {
|
||||
$list[$i] = (object)[
|
||||
'task' => trim($tmp['task'][$i]),
|
||||
'act' => (int)str_replace('.', '', $tmp['act'][$i]),
|
||||
'max' => (int)str_replace('.', '', $tmp['max'][$i])
|
||||
];
|
||||
$list[$i]->percent = round($list[$i]->act / $list[$i]->max * 100, 2);
|
||||
}
|
||||
|
||||
usort($list, function($a, $b) { return $b->percent <=> $a->percent; });
|
||||
|
||||
$act = $max = $avg = 0;
|
||||
for($i = 0; $i < 5; $i++) {
|
||||
$act += $list[$i]->act;
|
||||
$max += $list[$i]->max;
|
||||
$avg += $list[$i]->percent;
|
||||
}
|
||||
$percent = round($act / $max * 100, 2);
|
||||
|
||||
$tpl['data'] = [
|
||||
'progress' => $progress,
|
||||
'list' => $list,
|
||||
'percent' => $percent,
|
||||
'avg' => round($avg / 5, 2)
|
||||
];
|
||||
}
|
||||
else {
|
||||
$tpl['data'] = [
|
||||
'progress' => ''
|
||||
];
|
||||
}
|
60
pages/vermessung.page.php
Normal file
60
pages/vermessung.page.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
$tpl['file'] = 'vermessung.html';
|
||||
$tpl['data'] = [];
|
||||
$tpl['debug'] = false;
|
||||
|
||||
$protocol = !empty($_POST['protocol']) ? $_POST['protocol'] : '';
|
||||
|
||||
if(!empty($protocol)) {
|
||||
preg_match_all("/(?<datetime>.*)\t(?<amt>.*) führt mit (?<laeufer>.*) eine.*erwirtschaftet (?<gm>.*) Goldmünzen/m", $protocol, $res);
|
||||
|
||||
$dtact = date('m.Y');
|
||||
$vms = $newest = [];
|
||||
|
||||
for($i = 0; $i < count($res['datetime']); $i++) {
|
||||
$tmpdt = date('m.Y', strtotime($res['datetime'][$i]));
|
||||
|
||||
if(!array_key_exists($tmpdt, $vms)) {
|
||||
$vms[$tmpdt] = [
|
||||
'user' => [],
|
||||
'gm' => 0,
|
||||
'list' => [],
|
||||
'dtact' => $tmpdt
|
||||
];
|
||||
}
|
||||
|
||||
if(!array_key_exists($res['amt'][$i], $vms[$tmpdt]['user']))
|
||||
$vms[$tmpdt]['user'][$res['amt'][$i]] = 1;
|
||||
else
|
||||
$vms[$tmpdt]['user'][$res['amt'][$i]] += 1;
|
||||
|
||||
$laeufer = explode(', ', str_replace(' und ', ', ', trim($res['laeufer'][$i], ',')));
|
||||
foreach($laeufer as $tmp) {
|
||||
if(!array_key_exists($tmp, $vms[$tmpdt]['user']))
|
||||
$vms[$tmpdt]['user'][$tmp] = 1;
|
||||
else
|
||||
$vms[$tmpdt]['user'][$tmp] += 1;
|
||||
}
|
||||
arsort($vms[$tmpdt]['user']);
|
||||
|
||||
$vms[$tmpdt]['gm'] += (int)str_replace('.', '', $res['gm'][$i]);
|
||||
|
||||
$vms[$tmpdt]['list'][] = [
|
||||
'datum' => $res['datetime'][$i],
|
||||
'gold' => (int)str_replace('.', '', $res['gm'][$i]),
|
||||
'amt' => $res['amt'][$i],
|
||||
'laeufer' => $laeufer
|
||||
];
|
||||
}
|
||||
|
||||
$tpl['data'] = [
|
||||
'protocol' => $protocol,
|
||||
'vms' => $vms,
|
||||
'newest' => array_shift($vms)
|
||||
];
|
||||
}
|
||||
else {
|
||||
$tpl['data'] = [
|
||||
'protocol' => $protocol
|
||||
];
|
||||
}
|
10
tpl/default.html
Normal file
10
tpl/default.html
Normal file
@ -0,0 +1,10 @@
|
||||
{% extends tpl/layout.html %}
|
||||
|
||||
{% block title %}Willkommen auf fwtrash.de!{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p>Wir sind stolz darauf, Ihnen eine Vielzahl von nützlichen Tools und Ressourcen für das Onlinespiel Freewar zur Verfügung zu stellen. Unser Ziel ist es, Ihnen das Spielen von Freewar zu erleichtern und Ihnen zu helfen, das Beste aus dem Spiel herauszuholen.</p>
|
||||
<p>Auf unserer Webseite finden Sie alles, von praktischen Rechnern und Simulatoren bis hin zu umfassenden Anleitungen und Strategieguides. Wir sind ständig bemüht, unser Angebot zu erweitern und zu verbessern, um Ihnen die bestmögliche Unterstützung zu bieten.</p>
|
||||
<p>Schauen Sie sich um und entdecken Sie alles, was fwtrash.de zu bieten hat. Wir hoffen, dass Sie viel Freude beim Stöbern und Nutzen unserer Tools haben werden.</p>
|
||||
<strong>Viel Spaß beim Erkunden und Happy Gaming!</strong>
|
||||
{% endblock %}
|
37
tpl/doppelklinge.html
Normal file
37
tpl/doppelklinge.html
Normal file
@ -0,0 +1,37 @@
|
||||
{% extends tpl/layout.html %}
|
||||
|
||||
{% block title %}irgendwas mit Doppelklinge{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form action="/doppelklinge" method="post">
|
||||
<p>Gesamten Mainframe von Position X: 80 Y: 126 einfügen (strg-a, strg-c):</p>
|
||||
<textarea name="progress" rows="4" cols="60">{{ $progress }}</textarea>
|
||||
<br />
|
||||
<input type="submit" value="abschnalzen" />
|
||||
</form>
|
||||
|
||||
{% if(isset($list)): %}
|
||||
<hr />
|
||||
<table class="table table-sm table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Aufgabe</th>
|
||||
<th>Fortschritt</th>
|
||||
<th>Ziel</th>
|
||||
<th>Prozent</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for($i = 0; $i < count($list); $i++): %}
|
||||
<tr style="background-color: {{ $i >= 5 ? 'red' : 'white' }}">
|
||||
<td>{{ $list[$i]->task }}</td>
|
||||
<td>{{ $list[$i]->act }}</td>
|
||||
<td>{{ $list[$i]->max }}</td>
|
||||
<td>{{ $list[$i]->percent }}</td>
|
||||
</tr>
|
||||
{% endfor; %}
|
||||
</tbody>
|
||||
</table>
|
||||
insgesamt {{ $percent }}% erledigt (ø {{ $avg }}%).
|
||||
{% endif; %}
|
||||
{% endblock %}
|
46
tpl/layout.html
Normal file
46
tpl/layout.html
Normal file
@ -0,0 +1,46 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<base href="https://fwtrash.de/" />
|
||||
<title>{% yield title %}</title>
|
||||
<link rel="stylesheet" type="text/css" href="./css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" type="text/css" href="./css/style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<header class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow">
|
||||
<a class="navbar-brand col-md-3 col-lg-2 me-0 px-3 fs-6" href="./">
|
||||
<img src="./img/logo-big.png" style="height: 38px;" />
|
||||
fwtrash.de
|
||||
</a>
|
||||
<button class="navbar-toggler position-absolute d-md-none collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#sidebarMenu" aria-controls="sidebarMenu" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="navbar-nav">
|
||||
<div class="nav-item text-nowrap"> </div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse">
|
||||
<div class="position-sticky pt-3 sidebar-sticky">
|
||||
<ul class="nav flex-column">
|
||||
<li class="nav-item"><a class="nav-link{% if(empty($page)): %} active{% endif; %}" href="/">Home</a></li>
|
||||
<li class="nav-item"><a class="nav-link{% if($page == 'doppelklinge'): %} active{% endif; %}" href="/doppelklinge">Doppelklinge</a></li>
|
||||
<li class="nav-item"><a class="nav-link{% if($page == 'vermessung'): %} active{% endif; %}" href="/vermessung">Vermessungen</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
|
||||
<h1 class="h2">{% yield title %}</h1>
|
||||
<hr />
|
||||
{% yield content %}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
<script src="./js/bootstrap-native.min.js" defer></script>
|
||||
</body>
|
||||
</html>
|
109
tpl/vermessung.html
Normal file
109
tpl/vermessung.html
Normal file
@ -0,0 +1,109 @@
|
||||
{% extends tpl/layout.html %}
|
||||
|
||||
{% block title %}irgendwas mit Vermessungen{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form action="/vermessung" method="post">
|
||||
<p>Gesamtes Clanprotokoll einfügen (strg-a, strg-c):</p>
|
||||
<textarea name="protocol" rows="4" cols="60">{{ $protocol }}</textarea>
|
||||
<br />
|
||||
<input type="submit" value="abschnalzen" />
|
||||
</form>
|
||||
|
||||
{% if(isset($newest)): %}
|
||||
<hr />
|
||||
<span id="wao">wao, {{ number_format($newest['gm'], 0, '', '.') }} Goldmünzen durch {{ count($newest['list']) }} Vermessungen erwirtschaftet!</span>
|
||||
<select id="dtswitch">
|
||||
{% foreach($vms as $vm): %}
|
||||
<option>{{ $vm['dtact'] }}</option>
|
||||
{% endforeach; %}
|
||||
</select>
|
||||
<hr />
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row justify-content-md-center">
|
||||
<div class="col-sm-4">
|
||||
<div class="card">
|
||||
<h5 class="card-header">Topliste:</h5>
|
||||
<div class="card-body">
|
||||
<ul class="list-group list-group-flush list-top" id="toplist">
|
||||
{% foreach($newest['user'] as $name => $c): %}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center p-1">
|
||||
{{ $name }}
|
||||
<span class="badge bg-primary rounded-pill">{{ $c }} Vermessungen</span>
|
||||
</li>
|
||||
{% endforeach; %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<h5 class="card-header">berücksichtigte Messungen:</h5>
|
||||
<div class="card-body">
|
||||
<table class="table table-sm table-striped" style="width: 100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Goldmünzen</th>
|
||||
<th>Amtsteher</th>
|
||||
<th>Läufer</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="vmlist">
|
||||
{% foreach($newest['list'] as $tmp): %}
|
||||
<tr>
|
||||
<td style="vertical-align: top">{{ $tmp['datum'] }}</td>
|
||||
<td style="vertical-align: top">{{ $tmp['gold'] }} gm</td>
|
||||
<td style="vertical-align: top">{{ $tmp['amt'] }}</td>
|
||||
<td style="vertical-align: top">{{ implode(', ', $tmp['laeufer']) }}</td>
|
||||
</tr>
|
||||
{% endforeach; %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>const vms = {{ json_encode($vms) }};
|
||||
(() => {
|
||||
const toplist = document.querySelector('#toplist');
|
||||
const vmlist = document.querySelector('#vmlist');
|
||||
const wao = document.querySelector('#wao');
|
||||
const dtswitch = document.querySelector('#dtswitch');
|
||||
|
||||
dtswitch.addEventListener('change', e => {
|
||||
const vm = vms[dtswitch.value];
|
||||
|
||||
toplist.innerHTML = '';
|
||||
vmlist.innerHTML = '';
|
||||
|
||||
let gm = 0;
|
||||
let cvm = 0;
|
||||
|
||||
for(let [ user, count ] of Object.entries(vm.user)) {
|
||||
// fill toplist
|
||||
const li = document.createElement('li');
|
||||
li.classList.add('list-group-item', 'd-flex', 'justify-content-between', 'align-items-center', 'p-1');
|
||||
li.innerText = user;
|
||||
const span = document.createElement('span');
|
||||
span.classList.add('badge', 'bg-primary', 'rounded-pill');
|
||||
span.innerText = `${count} Vermessungen`;
|
||||
li.insertAdjacentElement('beforeend', span);
|
||||
toplist.insertAdjacentElement('beforeend', li);
|
||||
}
|
||||
|
||||
for(let entry of vm.list) {
|
||||
// fill vmlist
|
||||
const tr = document.createElement('tr');
|
||||
tr.innerHTML = `<td>${entry.datum}</td><td>${entry.gold} gm</td><td>${entry.amt}</td><td>${entry.laeufer.join(', ')}</td>`;
|
||||
vmlist.insertAdjacentElement('beforeend', tr);
|
||||
}
|
||||
|
||||
wao.innerHTML = `wao, ${vm.gm.toLocaleString('de-DE')} Goldmünzen durch ${vm.list.length} Vermessungen erwirtschaftet!`;
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
{% endif; %}
|
||||
{% endblock %}
|
Loading…
Reference in New Issue
Block a user