From: Malte Bublitz
Date: Sun, 8 May 2022 03:47:39 +0000 (+0200)
Subject: Git-Import
X-Git-Url: https://git.rt3x.de/?a=commitdiff_plain;h=5b9855c5c4285478219e96a93ef953297014b165;p=ip.malte70.de.git
Git-Import
---
5b9855c5c4285478219e96a93ef953297014b165
diff --git a/.htaccess b/.htaccess
new file mode 100644
index 0000000..f1e829a
--- /dev/null
+++ b/.htaccess
@@ -0,0 +1,13 @@
+#
+# ip.malte70.de/.htaccess
+#
+
+
+ RewriteEngine On
+
+ RewriteBase /
+
+ # The widget should be accessed using a filename
+ # containing the correct extendion for a PNG image
+ RewriteRule ^widget.png$ widget.php [QSA]
+
diff --git a/98.php b/98.php
new file mode 100644
index 0000000..fa497c4
--- /dev/null
+++ b/98.php
@@ -0,0 +1,161 @@
+ "Deutsch",
+ "de_DE" => "Deutsch (Deutschland)",
+ "de_AT" => "Deutsch (Ãsterreich)",
+ "de_CH" => "Deutsch (Schweiz)",
+ "en" => "Englisch",
+ "en_UK" => "Englisch (Vereinigtes Königreich)",
+ "en_US" => "Englisch (USA)",
+ "tlh" => "Klingonisch"
+);
+
+
+/**
+ * Retrieve GeoIP data
+ */
+$geo = $info->getGeoIPCity();
+if (empty($geo[1])) {
+ $geo = False;
+}
+
+
+$Data = Array(
+ "IP" => $info->getIP(),
+ "RealIP" => $info->getRealIP(),
+ "Host" => $info->getHostname() != $info->getIP() ? $info->getHostname() : NULL,
+ "Browser" => $info->getBrowser(),
+ "OS" => $info->getOS(),
+ "Lang" => array_key_exists($info->getLanguage(),$Languages) ? $Languages[$info->getLanguage()]." (".$info->getLanguage().")" : $info->getLanguage(),
+ "UserAgent" => $info->getUserAgent(),
+ "GeoIP" => $geo,
+ //"Stylesheet" => "https://unpkg.com/98.css",
+ "Stylesheet" => Array(
+ "/assets/css/98.css",
+ "/assets/css/ipinfo98.css"
+ ),
+ "Favicon" => Array(
+ "MIMEType" => "image/png",
+ "Size" => "48x48",
+ "URL" => "/assets/img/favicon98.png"
+ )
+);
+
+?>
+
+
+
+
+
+ Deine IP — ip.malte70.de
+
+
+
+
+
+ " sizes="=$Data["Favicon"]["Size"]?>" href="=$Data["Favicon"]["URL"]?>">
+
+
+
+
+
+
+
+
+
+ © =date("Y")?> malte70
+
+
+
+*/ ?>
+
+
+
diff --git a/API.md b/API.md
new file mode 100644
index 0000000..7872833
--- /dev/null
+++ b/API.md
@@ -0,0 +1,20 @@
+# ip.malte70.de API
+
+You can access the API at:
+
+ https://ip.malte70.de/api.php/*query*
+
+Query might be one of the following values:
+
+- ip
+- hostname
+- useragent
+- browser
+- operatingsystem
+- lang
+- country
+- city
+- postal_code
+- coordinates
+- latitute
+- longitude
diff --git a/ad.inc.php b/ad.inc.php
new file mode 100644
index 0000000..f9fd719
--- /dev/null
+++ b/ad.inc.php
@@ -0,0 +1,28 @@
+
+ Neu! Zugriff via Finger-Protokoll:
+
+$ finger ip@ip.malte70.de
+5.1.92.135
+$ finger myip@ip.malte70.de
+Your IP: 5.1.92.135
+Your Hostname: spandau.rolltreppe3.de
+EOT;
+
+ } else {
+ $ad = "\n\t";
+ $ad.= "IPInfo feat. 98.css\n\t
\n";
+
+ }
+
+ return $ad;
+}
+
+?>
diff --git a/api.php b/api.php
new file mode 100644
index 0000000..5332705
--- /dev/null
+++ b/api.php
@@ -0,0 +1,108 @@
+getIP();
+ break;
+
+ case "hostname":
+ case "host":
+ case "fqdn":
+ print $info->getHostname();
+ break;
+
+ case "useragent":
+ case "user-agent":
+ case "ua":
+ print $info->getUserAgent("");
+ break;
+
+ case "browser":
+ case "client":
+ print $info->getBrowser("");
+ break;
+
+ case "os":
+ case "operatingsystem":
+ case "operating-system":
+ print $info->getOS("");
+ break;
+
+ case "lang":
+ case "language":
+ case "locale":
+ print $info->getLanguage("");
+ break;
+
+ case "country":
+ print $info->getGeoIPCountry();
+ break;
+
+ case "region_code":
+ $region = $info->getGeoIPRegion();
+ if (is_array($region))
+ print $region[0];
+ break;
+
+ case "region":
+ $region = $info->getGeoIPRegion();
+ if (is_array($region))
+ print $region[1];
+ break;
+
+ case "city":
+ $city = $info->getGeoIPCity();
+ if ($city)
+ print $city[0];
+ break;
+
+ case "zip":
+ case "postal_code":
+ $city = $info->getGeoIPCity();
+ if ($city)
+ print $city[1];
+ break;
+
+ case "coordinates":
+ case "gps":
+ $city = $info->getGeoIPCity();
+ if ($city)
+ print $city[2][0] . " " . $city[2][1];
+ break;
+
+ case "latitude":
+ $city = $info->getGeoIPCity();
+ if ($city)
+ print $city[2][0];
+ break;
+
+ case "longitude":
+ $city = $info->getGeoIPCity();
+ if ($city)
+ print $city[2][1];
+ break;
+
+ default:
+ print "Error: Invalid query";
+
+}
+
+?>
\ No newline at end of file
diff --git a/assets/css/98.css b/assets/css/98.css
new file mode 100644
index 0000000..0e5a2b4
--- /dev/null
+++ b/assets/css/98.css
@@ -0,0 +1,513 @@
+/**
+ * 98.css
+ * Copyright (c) 2020 Jordan Scales
+ * https://github.com/jdan/98.css/blob/master/LICENSE
+ */
+
+:root {
+ /* Color */
+ --surface: #c0c0c0;
+ --button-highlight: #ffffff;
+ --button-face: #dfdfdf;
+ --button-shadow: #808080;
+ --window-frame: #0a0a0a;
+ --dialog-blue: #000080;
+ --dialog-blue-light: #1084d0;
+ --link-blue: #0000ff;
+
+ /* Spacing */
+ --element-spacing: 8px;
+ --grouped-button-spacing: 4px;
+ --grouped-element-spacing: 6px;
+ --radio-width: 12px;
+ --checkbox-width: 13px;
+ --radio-label-spacing: 6px;
+
+ /* Some detailed computations for radio buttons and checkboxes */
+ --radio-total-width-precalc: 12px + 6px;
+ --radio-total-width: 18px;
+ --radio-left: -6px;
+ --radio-dot-width: 4px;
+ --radio-dot-top: 4px;
+ --radio-dot-left: -14px;
+
+ --checkbox-total-width-precalc: 13px +
+ 6px;
+ --checkbox-total-width: 19px;
+ --checkbox-left: -7px;
+ --checkmark-width: 7px;
+ --checkmark-top: 3px;
+ --checkmark-left: 3px;
+
+ /* Borders */
+ --border-width: 1px;
+ --border-raised-outer: inset -1px -1px #0a0a0a,
+ inset 1px 1px #ffffff;
+ --border-raised-inner: inset -2px -2px #808080,
+ inset 2px 2px #dfdfdf;
+ --border-sunken-outer: inset -1px -1px #ffffff,
+ inset 1px 1px #0a0a0a;
+ --border-sunken-inner: inset -2px -2px #dfdfdf,
+ inset 2px 2px #808080;
+
+ /* Field borders (checkbox, input, etc) flip window-frame and button-shadow */
+ --border-field: inset -1px -1px #ffffff,
+ inset 1px 1px #808080, inset -2px -2px #dfdfdf,
+ inset 2px 2px #0a0a0a;
+}
+
+* {
+ font-family: Arial;
+ font-size: 12px;
+ letter-spacing: -0.03ch;
+ -webkit-font-smoothing: none;
+ color: #222222;
+}
+
+h1 {
+ font-size: 5rem;
+}
+
+h2 {
+ font-size: 2.5rem;
+}
+
+h3 {
+ font-size: 2rem;
+}
+
+h4 {
+ font-size: 1.5rem;
+}
+
+u {
+ text-decoration: none;
+ border-bottom: 0.5px solid #222222;
+}
+
+button {
+ box-sizing: border-box;
+ border: none;
+ background: #c0c0c0;
+ box-shadow: inset -1px -1px #0a0a0a,
+ inset 1px 1px #ffffff, inset -2px -2px #808080,
+ inset 2px 2px #dfdfdf;
+
+ min-width: 75px;
+ min-height: 23px;
+ padding: 0 12px;
+}
+
+button:active {
+ box-shadow: inset -1px -1px #ffffff,
+ inset 1px 1px #0a0a0a, inset -2px -2px #dfdfdf,
+ inset 2px 2px #808080;
+}
+
+button:focus {
+ outline: 1px dotted #000000;
+ outline-offset: -4px;
+}
+
+:disabled {
+ color: #808080;
+ text-shadow: 1px 1px 0 #ffffff;
+}
+
+:disabled + label {
+ color: #808080;
+ text-shadow: 1px 1px 0 #ffffff;
+}
+
+.window {
+ box-shadow: inset -1px -1px #0a0a0a,
+ inset 1px 1px #ffffff, inset -2px -2px #808080,
+ inset 2px 2px #dfdfdf;
+ background: #c0c0c0;
+ padding: 3px;
+}
+
+.title-bar {
+ background: linear-gradient(
+ 90deg,
+ #000080,
+ #1084d0
+ );
+ padding: 2px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.title-bar-text {
+ font-weight: bold;
+ color: white;
+ letter-spacing: 0;
+ margin-right: 24px;
+}
+
+.title-bar-controls {
+ display: flex;
+}
+
+.title-bar-controls button {
+ padding: 0;
+ display: block;
+ min-width: 14px;
+ min-height: 12px;
+}
+
+.title-bar-controls button:focus {
+ outline: none;
+}
+
+.title-bar-controls button[aria-label="Minimize"] {
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='6' height='2' viewBox='0 0 6 2' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Crect width='6' height='2' fill='black'/%3E %3C/svg%3E");
+ background-repeat: no-repeat;
+ background-position: bottom 2px left 3px;
+}
+
+.title-bar-controls button[aria-label="Maximize"] {
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='9' height='8' viewBox='0 0 9 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 2V7V8H1H8H9V7V2V0H8H1H0V2ZM8 7V2H1V7H8Z' fill='black'/%3E %3C/svg%3E");
+ background-repeat: no-repeat;
+ /* Off by 1px because contents can't go above the inner shadow */
+ /* Should be 9px by 9px, with top 1px */
+ background-position: top 2px left 2px;
+}
+
+.title-bar-controls button[aria-label="Close"] {
+ margin-left: 2px;
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='8' height='7' viewBox='0 0 8 7' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 0H1H2V1H3V2H4H5V1H6V0H7H8V1H7V2H6V3H5V4H6V5H7V6H8V7H7H6V6H5V5H4H3V6H2V7H1H0V6H1V5H2V4H3V3H2V2H1V1H0V0Z' fill='black'/%3E %3C/svg%3E");
+ background-repeat: no-repeat;
+ background-position: top 2px center;
+}
+
+.window-body {
+ margin: 8px;
+}
+
+fieldset {
+ border: none;
+ box-shadow: inset -1px -1px #ffffff,
+ inset 1px 1px #0a0a0a, inset -2px -2px #808080,
+ inset 2px 2px #dfdfdf;
+ padding: 10px;
+ padding-block-start: 8px;
+ margin: 0;
+}
+
+legend {
+ background: #c0c0c0;
+}
+
+.field-row {
+ display: flex;
+ align-items: center;
+}
+
+[class^="field-row"] + [class^="field-row"] {
+ margin-top: 6px;
+}
+
+.field-row * + * {
+ margin-left: 6px;
+}
+
+.field-row-stacked {
+ display: flex;
+ flex-direction: column;
+}
+
+.field-row-stacked * + * {
+ margin-top: 6px;
+}
+
+label {
+ display: inline-flex;
+ line-height: 1;
+ align-items: center;
+}
+
+input[type="radio"],
+input[type="checkbox"] {
+ appearance: none;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ margin: 0;
+ border: none;
+}
+
+input[type="radio"] + label {
+ position: relative;
+ margin-left: 18px;
+}
+
+input[type="radio"] + label::before {
+ content: "";
+ position: absolute;
+ left: -18px;
+ display: inline-block;
+ width: 12px;
+ height: 12px;
+ margin-right: 6px;
+ background: url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='12' viewBox='0 0 12 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M8 0H4V1H2V2H1V4H0V8H1V10H2V8H1V4H2V2H4V1H8V2H10V1H8V0Z' fill='%23808080'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M8 1H4V2H2V3V4H1V8H2V9H3V8H2V4H3V3H4V2H8V3H10V2H8V1Z' fill='black'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M9 3H10V4H9V3ZM10 8V4H11V8H10ZM8 10V9H9V8H10V9V10H8ZM4 10V11H8V10H4ZM4 10V9H2V10H4Z' fill='%23DFDFDF'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M11 2H10V4H11V8H10V10H8V11H4V10H2V11H4V12H8V11H10V10H11V8H12V4H11V2Z' fill='white'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M4 2H8V3H9V4H10V8H9V9H8V10H4V9H3V8H2V4H3V3H4V2Z' fill='white'/%3E %3C/svg%3E");
+}
+
+input[type="radio"]:checked + label::after {
+ content: "";
+ display: block;
+ width: 4px;
+ height: 4px;
+ top: 4px;
+ left: -14px;
+ position: absolute;
+ background: url("data:image/svg+xml;charset=utf-8,%3Csvg width='4' height='4' viewBox='0 0 4 4' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3 0H1V1H0V2V3H1V4H3V3H4V2V1H3V0Z' fill='black'/%3E %3C/svg%3E");
+}
+
+input[type="radio"]:focus + label,
+input[type="checkbox"]:focus + label {
+ outline: 1px dotted #000000;
+}
+
+input[type="radio"][disabled] + label::before {
+ background: url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='12' viewBox='0 0 12 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M8 0H4V1H2V2H1V4H0V8H1V10H2V8H1V4H2V2H4V1H8V2H10V1H8V0Z' fill='%23808080'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M8 1H4V2H2V3V4H1V8H2V9H3V8H2V4H3V3H4V2H8V3H10V2H8V1Z' fill='black'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M9 3H10V4H9V3ZM10 8V4H11V8H10ZM8 10V9H9V8H10V9V10H8ZM4 10V11H8V10H4ZM4 10V9H2V10H4Z' fill='%23DFDFDF'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M11 2H10V4H11V8H10V10H8V11H4V10H2V11H4V12H8V11H10V10H11V8H12V4H11V2Z' fill='white'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M4 2H8V3H9V4H10V8H9V9H8V10H4V9H3V8H2V4H3V3H4V2Z' fill='%23C0C0C0'/%3E %3C/svg%3E");
+}
+
+input[type="radio"][disabled]:checked + label::after {
+ background: url("data:image/svg+xml;charset=utf-8,%3Csvg width='4' height='4' viewBox='0 0 4 4' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3 0H1V1H0V2V3H1V4H3V3H4V2V1H3V0Z' fill='%23808080'/%3E %3C/svg%3E");
+}
+
+input[type="checkbox"] + label {
+ position: relative;
+ margin-left: 19px;
+}
+
+input[type="checkbox"] + label::before {
+ content: "";
+ position: absolute;
+ left: -19px;
+ display: inline-block;
+ width: 13px;
+ height: 13px;
+ background: #ffffff;
+ box-shadow: inset -1px -1px #ffffff,
+ inset 1px 1px #808080, inset -2px -2px #dfdfdf,
+ inset 2px 2px #0a0a0a;
+ margin-right: 6px;
+}
+
+input[type="checkbox"]:checked + label::after {
+ content: "";
+ display: block;
+ width: 7px;
+ height: 7px;
+ position: absolute;
+ top: 3px;
+ left: -16px;
+ background: url("data:image/svg+xml;charset=utf-8,%3Csvg width='7' height='7' viewBox='0 0 7 7' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M7 0H6V1H5V2H4V3H3V4H2V3H1V2H0V5H1V6H2V7H3V6H4V5H5V4H6V3H7V0Z' fill='black'/%3E %3C/svg%3E");
+}
+
+input[type="checkbox"][disabled] + label::before {
+ background: #c0c0c0;
+}
+
+input[type="checkbox"][disabled]:checked + label::after {
+ background: url("data:image/svg+xml;charset=utf-8,%3Csvg width='7' height='7' viewBox='0 0 7 7' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M7 0H6V1H5V2H4V3H3V4H2V3H1V2H0V5H1V6H2V7H3V6H4V5H5V4H6V3H7V0Z' fill='%23808080'/%3E %3C/svg%3E");
+}
+
+input[type="text"] {
+ padding: 3px 4px;
+ border: none;
+ box-shadow: inset -1px -1px #ffffff,
+ inset 1px 1px #808080, inset -2px -2px #dfdfdf,
+ inset 2px 2px #0a0a0a;
+ background-color: #ffffff;
+ box-sizing: border-box;
+}
+
+select {
+ padding: 3px 4px;
+ border: none;
+ box-shadow: inset -1px -1px #ffffff,
+ inset 1px 1px #808080, inset -2px -2px #dfdfdf,
+ inset 2px 2px #0a0a0a;
+ background-color: #ffffff;
+ box-sizing: border-box;
+}
+
+textarea {
+ padding: 3px 4px;
+ border: none;
+ box-shadow: inset -1px -1px #ffffff,
+ inset 1px 1px #808080, inset -2px -2px #dfdfdf,
+ inset 2px 2px #0a0a0a;
+ background-color: #ffffff;
+ box-sizing: border-box;
+}
+
+input[type="text"],
+select {
+ height: 21px;
+}
+
+input[type="text"] {
+ /* For some reason descenders are getting cut off without this */
+ line-height: 2;
+}
+
+select {
+ appearance: none;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ position: relative;
+ padding-right: 32px;
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='17' viewBox='0 0 16 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 0H0V1V16H1V1H15V0Z' fill='%23DFDFDF'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M2 1H1V15H2V2H14V1H2Z' fill='white'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M16 17H15H0V16H15V0H16V17Z' fill='black'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 1H14V15H1V16H14H15V1Z' fill='%23808080'/%3E %3Crect x='2' y='2' width='12' height='13' fill='%23C0C0C0'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M11 6H4V7H5V8H6V9H7V10H8V9H9V8H10V7H11V6Z' fill='black'/%3E %3C/svg%3E");
+ background-position: top 2px right 2px;
+ background-repeat: no-repeat;
+}
+
+select:focus,
+input[type="text"]:focus,
+textarea:focus {
+ outline: none;
+}
+
+select:focus {
+ color: #ffffff;
+ background-color: #000080;
+}
+select:focus option {
+ color: #000;
+ background-color: #fff;
+}
+
+select:active {
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='17' viewBox='0 0 16 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 0H15H16V17H15H0V16V1V0ZM1 16H15V1H1V16Z' fill='%23808080'/%3E %3Crect x='1' y='1' width='14' height='15' fill='%23C0C0C0'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M12 7H5V8H6V9H7V10H8V11H9V10H10V9H11V8H12V7Z' fill='black'/%3E %3C/svg%3E");
+}
+
+a {
+ color: #0000ff;
+}
+
+a:focus {
+ outline: 1px dotted #0000ff;
+}
+
+ul.tree-view {
+ display: block;
+ background: #ffffff;
+ box-shadow: inset -1px -1px #ffffff,
+ inset 1px 1px #808080, inset -2px -2px #dfdfdf,
+ inset 2px 2px #0a0a0a;
+ padding: 6px;
+ margin: 0;
+}
+
+ul.tree-view li {
+ list-style-type: none;
+}
+
+ul.tree-view a {
+ text-decoration: none;
+ color: #000;
+}
+
+ul.tree-view a:focus {
+ background-color: #000080;
+ color: #ffffff;
+}
+
+ul.tree-view ul,
+ul.tree-view li {
+ margin-top: 3px;
+}
+
+ul.tree-view ul {
+ margin-left: 16px;
+ padding-left: 16px;
+ /* Goes down too far */
+ border-left: 1px dotted #808080;
+}
+
+ul.tree-view ul > li {
+ position: relative;
+}
+ul.tree-view ul > li::before {
+ content: "";
+ display: block;
+ position: absolute;
+ left: -16px;
+ top: 6px;
+ width: 12px;
+ border-bottom: 1px dotted #808080;
+}
+
+/* Cover the bottom of the left dotted border */
+ul.tree-view ul > li:last-child::after {
+ content: "";
+ display: block;
+ position: absolute;
+ left: -20px;
+ top: 7px;
+ bottom: 0px;
+ width: 8px;
+ background: #ffffff;
+}
+
+pre {
+ display: block;
+ background: #ffffff;
+ box-shadow: inset -1px -1px #ffffff,
+ inset 1px 1px #808080, inset -2px -2px #dfdfdf,
+ inset 2px 2px #0a0a0a;
+ padding: 12px 8px;
+ margin: 0;
+}
+
+code,
+code * {
+ font-family: monospace;
+}
+
+summary:focus {
+ outline: 1px dotted #000000;
+}
+
+::-webkit-scrollbar {
+ width: 16px;
+}
+::-webkit-scrollbar:horizontal {
+ height: 17px;
+}
+
+::-webkit-scrollbar-corner {
+ background: #dfdfdf;
+}
+
+::-webkit-scrollbar-track {
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='2' height='2' viewBox='0 0 2 2' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M1 0H0V1H1V2H2V1H1V0Z' fill='%23C0C0C0'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M2 0H1V1H0V2H1V1H2V0Z' fill='white'/%3E %3C/svg%3E");
+}
+
+::-webkit-scrollbar-thumb {
+ background-color: #dfdfdf;
+ box-shadow: inset -1px -1px #0a0a0a,
+ inset 1px 1px #ffffff, inset -2px -2px #808080,
+ inset 2px 2px #dfdfdf;
+}
+
+::-webkit-scrollbar-button:vertical:start {
+ height: 17px;
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='17' viewBox='0 0 16 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 0H0V1V16H1V1H15V0Z' fill='%23DFDFDF'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M2 1H1V15H2V2H14V1H2Z' fill='white'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M16 17H15H0V16H15V0H16V17Z' fill='black'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 1H14V15H1V16H14H15V1Z' fill='%23808080'/%3E %3Crect x='2' y='2' width='12' height='13' fill='%23C0C0C0'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M8 6H7V7H6V8H5V9H4V10H11V9H10V8H9V7H8V6Z' fill='black'/%3E %3C/svg%3E");
+}
+::-webkit-scrollbar-button:vertical:end {
+ height: 17px;
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='17' viewBox='0 0 16 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 0H0V1V16H1V1H15V0Z' fill='%23DFDFDF'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M2 1H1V15H2V2H14V1H2Z' fill='white'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M16 17H15H0V16H15V0H16V17Z' fill='black'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 1H14V15H1V16H14H15V1Z' fill='%23808080'/%3E %3Crect x='2' y='2' width='12' height='13' fill='%23C0C0C0'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M11 6H4V7H5V8H6V9H7V10H8V9H9V8H10V7H11V6Z' fill='black'/%3E %3C/svg%3E");
+}
+::-webkit-scrollbar-button:horizontal:start {
+ width: 16px;
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='17' viewBox='0 0 16 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 0H0V1V16H1V1H15V0Z' fill='%23DFDFDF'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M2 1H1V15H2V2H14V1H2Z' fill='white'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M16 17H15H0V16H15V0H16V17Z' fill='black'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 1H14V15H1V16H14H15V1Z' fill='%23808080'/%3E %3Crect x='2' y='2' width='12' height='13' fill='%23C0C0C0'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M9 4H8V5H7V6H6V7H5V8H6V9H7V10H8V11H9V4Z' fill='black'/%3E %3C/svg%3E");
+}
+::-webkit-scrollbar-button:horizontal:end {
+ width: 16px;
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='17' viewBox='0 0 16 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 0H0V1V16H1V1H15V0Z' fill='%23DFDFDF'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M2 1H1V15H2V2H14V1H2Z' fill='white'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M16 17H15H0V16H15V0H16V17Z' fill='black'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15 1H14V15H1V16H14H15V1Z' fill='%23808080'/%3E %3Crect x='2' y='2' width='12' height='13' fill='%23C0C0C0'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M7 4H6V11H7V10H8V9H9V8H10V7H9V6H8V5H7V4Z' fill='black'/%3E %3C/svg%3E");
+}
diff --git a/assets/css/ipinfo98.css b/assets/css/ipinfo98.css
new file mode 100644
index 0000000..497e261
--- /dev/null
+++ b/assets/css/ipinfo98.css
@@ -0,0 +1,35 @@
+@charset "UTF-8";
+*, *:before, *:after {
+ box-sizing: border-box;
+}
+body {
+ background: #00807F;
+}
+.window {
+ width: 450px;
+ max-width: 100%;
+ margin: 80px auto 50px;
+}
+main.maximized {
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
+}
+main.maximized .window {
+ height: 100%;
+ width: 100%;
+ margin: 0;
+}
+label {
+ display: inline-block;
+ width: 20%;
+}
+input {
+ display: inline-block;
+ width: 80%;
+}
+p {
+ text-align: right;
+}
\ No newline at end of file
diff --git a/assets/css/style.css b/assets/css/style.css
new file mode 100644
index 0000000..24acdbb
--- /dev/null
+++ b/assets/css/style.css
@@ -0,0 +1,94 @@
+@charset "UTF-8";
+/**
+ * Stylesheet for ip.malte70.de
+ */
+
+@import url(https://fonts.googleapis.com/css?family=Source+Serif+Pro|Source+Sans+Pro|Inconsolata&subset=latin,latin-ext);
+
+*,
+*:before,
+*:after {
+ box-sizing: border-box;
+}
+
+html {
+ margin: 0;
+ padding: 0;
+}
+body {
+ margin: 0;
+ padding: 0;
+ background: #EDEBE6;
+ font: 18px "Source Serif Pro", serif;
+ color: #403B33;
+}
+
+a:link,
+a:visited {
+ color: #A40114;
+}
+a:hover,
+a:active {
+ color: #94C7B6;
+}
+.text-center {
+ text-align: center;
+ margin-bottom: 8em;
+}
+
+h1 {
+ margin: 0;
+ padding: 14px 10px 10px;
+ text-align: center;
+ border-bottom: 4px solid #94c7b6;
+ background: #94c7b6;
+}
+h1 a:link, h1 a:visited {
+ color: #403B33;
+ text-decoration: none;
+}
+h1 a:hover, h1 a:active {
+ /*color: #94c7b6;*/
+ text-decoration: underline;
+}
+h2 {
+ font: 1.6em "Source Sans Pro", sans-serif;
+ font-weight: normal;
+}
+main {
+ margin: 1em .5em 2em;
+}
+@media (min-width: 800px) {
+ main {
+ margin-left: auto;
+ margin-right: auto;
+ width: 600px;
+ }
+}
+
+main h3, main .lead {
+ font: 1.3em "Source Sans Pro", sans-serif;
+ font-weight: normal;
+}
+
+main .lead {
+ margin-top: 3em;
+}
+
+main p.info {
+ /*font-family: "Source Code Pro", monospace;*/
+ font-family: "Inconsolata", monospace;
+}
+
+footer {
+ font: 0.7em "Inconsolata", monospace;
+ text-align: center;
+}
+footer p {
+ margin: .5em 0;
+}
+footer a:link,
+footer a:visited {
+ color: #403B33;
+ text-decoration: underline;
+}
diff --git a/assets/img/favicon.png b/assets/img/favicon.png
new file mode 100644
index 0000000..c993918
Binary files /dev/null and b/assets/img/favicon.png differ
diff --git a/assets/img/favicon98.png b/assets/img/favicon98.png
new file mode 100644
index 0000000..e65b07b
Binary files /dev/null and b/assets/img/favicon98.png differ
diff --git a/assets/js/getipv4.js b/assets/js/getipv4.js
new file mode 100644
index 0000000..c38ccea
--- /dev/null
+++ b/assets/js/getipv4.js
@@ -0,0 +1,26 @@
+/**
+ * ip.malte70.de/assets/js/getipv4.js
+ *
+ * Get IPv4 address if site is accessed via IPv6
+ */
+
+$(function(){
+ api_url_v4 = "https://ip4.malte70.de/api.php";
+ api_url_v6 = "https://ip6.malte70.de/api.php";
+ elem_ipv4 = $("#ipv4");
+ elem_ipv6 = $("#ipv6");
+ elem_ipv6_headline = $("#ipv6_headline");
+
+ if (elem_ipv6.html().length > 4) {
+ // Site accessed via IPv6, so dynamically add IPv4
+ $.get(api_url_v4, function(data) {
+ elem_ipv4.html(data);
+ });
+
+ } else {
+ // Site accessed via IPv4, so remove IPv6 blocks
+ console.log("IPv4 access detected!");
+ elem_ipv6_headline.remove();
+ elem_ipv6.remove();
+ }
+});
\ No newline at end of file
diff --git a/assets/otf/SourceCodePro-Regular.otf b/assets/otf/SourceCodePro-Regular.otf
new file mode 100644
index 0000000..1bae002
Binary files /dev/null and b/assets/otf/SourceCodePro-Regular.otf differ
diff --git a/assets/otf/SourceCodePro-Semibold.otf b/assets/otf/SourceCodePro-Semibold.otf
new file mode 100644
index 0000000..a61686c
Binary files /dev/null and b/assets/otf/SourceCodePro-Semibold.otf differ
diff --git a/clientinfo.class.php b/clientinfo.class.php
new file mode 100644
index 0000000..e751843
--- /dev/null
+++ b/clientinfo.class.php
@@ -0,0 +1,635 @@
+IP)) {
+ $this->IP = $_SERVER["REMOTE_ADDR"];
+ }
+
+ return $this->IP;
+ }
+ public function isIPv6() {
+ return stristr($this->getIP(), ":");
+ }
+ public function getRealIP() {
+ if (empty($this->realIP)) {
+ if (@!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) {
+ $this->realIP = $_SERVER["HTTP_X_FORWARDED_FOR"];
+ } elseif (@!empty($_SERVER["HTTP_CLIENT_IP"])) {
+ $this->realIP = $_SERVER["HTTP_CLIENT_IP"];
+ }
+ }
+
+ return $this->realIP;
+ }
+ public function getHostname() {
+ if (empty($this->hostname)) {
+ $this->hostname = gethostbyaddr(
+ $this->getIP()
+ );
+ }
+
+ return $this->hostname;
+ }
+ public function getUserAgent() {
+ if (empty($this->userAgent)) {
+ $this->userAgent = $_SERVER["HTTP_USER_AGENT"];
+ }
+
+ return $this->userAgent;
+ }
+
+ public function getBrowser($fallback = "Unknown") {
+ if (empty($this->browser)) {
+ $ua = $this->getUserAgent();
+
+ if (stripos($ua, "PaleMoon") !== false) {
+ $this->browser = "Pale Moon";
+ $pos_version_start = stripos(
+ $ua,
+ "PaleMoon/"
+ ) + strlen("PaleMoon/");
+
+ $version = substr(
+ $ua,
+ $pos_version_start
+ );
+
+ $this->browser .= " " . $version;
+
+ } elseif (stripos($ua, "K-Meleon") !== false) {
+ $this->browser = "K-Meleon";
+ $pos_version_start = stripos(
+ $ua,
+ "K-Meleon/"
+ ) + strlen("K-Meleon/");
+
+ $version = substr(
+ $ua,
+ $pos_version_start
+ );
+
+ $this->browser .= " " . $version;
+
+ } elseif (stripos($ua, "Firefox") !== false) {
+ $this->browser = "Mozilla Firefox";
+ $pos_version_start = stripos(
+ $ua,
+ "Firefox/"
+ ) + strlen("Firefox/");
+ $pos_version_end = stripos(
+ $ua,
+ " ",
+ $pos_version_start
+ );
+
+ $version = substr(
+ $ua,
+ $pos_version_start,
+ $pos_version_end - $pos_version_start
+ );
+
+ $this->browser .= " " . $version;
+
+ } elseif (stripos($ua, "FxiOS") !== false) {
+ $this->browser = "Mozilla Firefox";
+ $pos_version_start = stripos(
+ $ua,
+ "FxiOS/"
+ ) + strlen("FxiOS/");
+ $pos_version_end = stripos(
+ $ua,
+ " ",
+ $pos_version_start
+ );
+
+ $version = substr(
+ $ua,
+ $pos_version_start,
+ $pos_version_end - $pos_version_start
+ );
+
+ $this->browser .= " " . $version;
+
+ } elseif (stripos($ua, "Edge") !== false) {
+ $this->browser = "Microsoft Edge";
+ $pos_version_start = stripos(
+ $ua,
+ "Edge/"
+ ) + strlen("Edge/");
+
+ $version = substr($ua, $pos_version_start);
+
+ $this->browser .= " " . $version;
+
+ } elseif (stripos($ua, "EdgA") !== false) {
+ $this->browser = "Microsoft Edge for Android";
+ $pos_version_start = stripos(
+ $ua,
+ "EdgA/"
+ ) + strlen("EdgA/");
+
+ $version = substr($ua, $pos_version_start);
+
+ $this->browser .= " " . $version;
+
+ } elseif (stripos($ua, "MSIE") !== false) {
+ $this->browser = "Microsoft Internet Explorer";
+ $pos_version_start = stripos(
+ $ua,
+ "MSIE"
+ ) + strlen("MSIE ");
+ $pos_version_end = stripos(
+ $ua,
+ ";",
+ $pos_version_start
+ );
+
+ $version = substr(
+ $ua,
+ $pos_version_start,
+ $pos_version_end - $pos_version_start
+ );
+
+ $this->browser .= " " . $version;
+
+ } elseif (stripos($ua, "QupZilla") !== false) {
+ $this->browser = "QupZilla";
+ $pos_version_start = stripos(
+ $ua,
+ "QupZilla/"
+ ) + strlen("QupZilla/");
+ $pos_version_end = stripos(
+ $ua,
+ " ",
+ $pos_version_start
+ );
+
+ $version = substr(
+ $ua,
+ $pos_version_start,
+ $pos_version_end - $pos_version_start
+ );
+
+ $this->browser .= " " . $version;
+
+ } elseif (stripos($ua, "Vivaldi") !== false) {
+ $this->browser = "Vivaldi";
+ $pos_version_start = stripos(
+ $ua,
+ "Vivaldi/"
+ ) + strlen("Vivaldi/");
+
+ $version = explode(
+ ".",
+ substr(
+ $ua,
+ $pos_version_start
+ )
+ );
+
+ $this->browser .= " " . $version[0] . "." . $version[1];
+
+ } elseif (stripos($ua, "OPR") !== false) {
+ $this->browser = "Opera";
+ $pos_version_start = stripos(
+ $ua,
+ "OPR/"
+ ) + strlen("OPR/");
+ $version = explode(
+ ".",
+ substr(
+ $ua,
+ $pos_version_start
+ )
+ );
+
+ $this->browser .= " " . $version[0] . "." . $version[1];
+
+ } elseif (stripos($ua, "Otter") !== false) {
+ $this->browser = "Otter";
+ $pos_version_start = stripos(
+ $ua,
+ "Otter/"
+ ) + strlen("Otter/");
+ $version = substr(
+ $ua,
+ $pos_version_start
+ );
+
+ $this->browser .= " " . $version;
+
+ } elseif (stripos($ua, "PlayStation 4") !== false) {
+ $this->browser = "PlayStation 4 Browser";
+ $pos_version_start = stripos(
+ $ua,
+ "PlayStation 4 "
+ ) + strlen("PlayStation 4 ");
+ $pos_version_end = stripos(
+ $ua,
+ ")",
+ $pos_version_start
+ );
+ $version = substr(
+ $ua,
+ $pos_version_start,
+ $pos_version_end - $pos_version_start
+ );
+ $this->browser .= " " . $version;
+
+ } elseif (stripos($ua, "Valve Steam GameOverlay") !== false) {
+ $this->browser = "Steam Game-Overlay";
+ $pos_version_start = stripos(
+ $ua,
+ "GameOverlay/"
+ ) + strlen("GameOverlay/");
+ $pos_version_end = stripos(
+ $ua,
+ ";",
+ $pos_version_start
+ );
+ $version = substr(
+ $ua,
+ $pos_version_start,
+ $pos_version_end - $pos_version_start
+ );
+ $this->browser .= " " . $version;
+
+ } elseif (stripos($ua, "Eolie") !== false) {
+ $this->browser = "Eolie";
+
+ } elseif (stripos($ua, "Chrome") !== false) {
+ $this->browser = "Google Chrome";
+ $pos_version_start = stripos(
+ $ua,
+ "Chrome/"
+ ) + strlen("Chrome/");
+ $pos_version_end = stripos(
+ $ua,
+ " ",
+ $pos_version_start
+ );
+ $version = explode(
+ ".",
+ substr(
+ $ua,
+ $pos_version_start,
+ $pos_version_end - $pos_version_start
+ )
+ );
+ $version = $version[0] . "." . $version[1];
+ if (stripos($ua, "Mobile") !== false) {
+ // Mobile Chrome (Android)
+ $this->browser .= " Mobile";
+ }
+ $this->browser .= " " . $version;
+
+ } else if (stripos($ua, "Epiphany") !== false) {
+ $this->browser = "GNOME Web (Epiphany)";
+ $pos_version_start = stripos(
+ $ua,
+ "Epiphany/"
+ ) + strlen("Epiphany/");
+ /*$pos_version_end = stripos(
+ $ua,
+ " ",
+ $pos_version_start
+ );*/
+ $pos_version_end = strlen($ua);
+
+ $version = substr(
+ $ua,
+ $pos_version_start,
+ $pos_version_end - $pos_version_start
+ );
+
+ //$this->browser .= " " . $version;
+
+ } else if (stripos($ua, "Safari") !== false) {
+ $this->browser = "Apple Safari";
+ $pos_version_start = stripos(
+ $ua,
+ "Version/"
+ ) + strlen("Version/");
+ $pos_version_end = stripos(
+ $ua,
+ " ",
+ $pos_version_start
+ );
+
+ $version = substr(
+ $ua,
+ $pos_version_start,
+ $pos_version_end - $pos_version_start
+ );
+
+ $this->browser .= " " . $version;
+
+ } elseif (stripos($ua, "ELinks") !== false) {
+ $this->browser = "ELinks";
+ $pos_version_start = stripos(
+ $ua,
+ "ELinks/"
+ ) + strlen("ELinks/");
+ $pos_version_end = stripos(
+ $ua,
+ " ",
+ $pos_version_start
+ );
+ $version = substr(
+ $ua,
+ $pos_version_start,
+ $pos_version_end - $pos_version_start
+ );
+ //$version = $version[0] . "." . $version[1];
+ $this->browser .= " " . $version;
+
+ } elseif (stripos($ua, "NetSurf") !== false) {
+ $this->browser = "NetSurf";
+ $pos_version_start = stripos(
+ $ua,
+ "NetSurf/"
+ ) + strlen("NetSurf/");
+ $pos_version_end = stripos(
+ $ua,
+ " ",
+ $pos_version_start
+ );
+ $version = substr(
+ $ua,
+ $pos_version_start,
+ $pos_version_end - $pos_version_start
+ );
+ $this->browser .= " " . $version;
+
+ } else {
+ $this->browser = $fallback;
+ }
+ }
+
+ return $this->browser;
+ }
+
+ public function getOS($fallback = "Unknown") {
+ if (empty($this->OS)) {
+ $this->OS = "AbsolutelyEpicOS";
+
+ $ua = $this->getUserAgent();
+ if (stripos($ua, "Android") !== false) {
+ // Check for Android before checking for GNU/Linux,
+ // since (at least) Android's Chrome identifies itself
+ // as âLinuxâ, since it simply is.
+ $this->OS = "Android ";
+ $pos_version_start = stripos(
+ $ua,
+ "Android"
+ ) + strlen("Android");
+ $pos_version_end = stripos(
+ $ua,
+ ";",
+ $pos_version_start
+ );
+ $this->OS .= substr(
+ $ua,
+ $pos_version_start,
+ $pos_version_end - $pos_version_start
+ );
+ } elseif (stripos($ua, "PlayStation 4") !== false) {
+ $this->OS = "PlayStation 4 System";
+
+ } elseif (stripos($ua, "FreeBSD") !== false) {
+ $this->OS = "FreeBSD";
+
+ } elseif (stripos($ua, "DragonFly") !== false) {
+ $this->OS = "DragonFly BSD";
+
+ } elseif (stripos($ua, "OpenBSD") !== false) {
+ $this->OS = "OpenBSD";
+
+ } elseif (stripos($ua, "Windows") !== false) {
+ $this->OS = "MS Windows";
+
+ if (stripos($ua, "Windows NT 10.0") !== false || stripos($ua, "Windows 10") !== false) {
+ $this->OS .= " 10";
+ } else if (stripos($ua, "Windows NT 6.3") !== false || stripos($ua, "Windows 8.1") !== false) {
+ $this->OS .= " 8.1";
+ } else if (stripos($ua, "Windows NT 6.2") !== false || stripos($ua, "Windows 8") !== false) {
+ $this->OS .= " 8";
+ } else if (stripos($ua, "Windows NT 6.1") !== false || stripos($ua, "Windows 7") !== false) {
+ $this->OS .= " 7";
+ } else if (stripos($ua, "Windows NT 6.0") !== false || stripos($ua, "Windows Vista") !== false) {
+ $this->OS .= " Vista";
+ } else if (stripos($ua, "Windows NT 5.1") !== false || stripos($ua, "Windows XP") !== false) {
+ $this->OS .= " XP";
+ }
+
+ } elseif (stripos($ua, "Linux") !== false) {
+ $this->OS = "GNU/Linux";
+
+ } elseif (stripos($ua, "iPhone OS") !== false) {
+ $this->OS = "iOS";
+
+ $pos_version_start = stripos(
+ $ua,
+ "iPhone OS"
+ ) + strlen("iPhone OS ");
+ $pos_version_end = stripos(
+ $ua,
+ " ",
+ $pos_version_start
+ );
+ $version = explode(
+ "_",
+ substr(
+ $ua,
+ $pos_version_start,
+ $pos_version_end - $pos_version_start
+ )
+ );
+
+ $this->OS .= " " . implode($version, ".");
+
+ } elseif (stripos($ua, "iPhone") !== false) {
+ $this->OS = "iOS";
+
+ $pos_version_start = stripos(
+ $ua,
+ "CPU OS"
+ ) + strlen("CPU OS ");
+ $pos_version_end = stripos(
+ $ua,
+ " ",
+ $pos_version_start
+ );
+ $version = explode(
+ "_",
+ substr(
+ $ua,
+ $pos_version_start,
+ $pos_version_end - $pos_version_start
+ )
+ );
+
+ $this->OS .= " " . implode($version, ".");
+
+ } elseif (stripos($ua, "Macintosh") !== false) {
+ $this->OS = "Apple OS X";
+
+ $pos_version_start = stripos(
+ $ua,
+ "OS X"
+ ) + strlen("OS X ");
+ $pos_version_bracket = stripos(
+ $ua,
+ ")",
+ $pos_version_start
+ );
+ $pos_version_semicolon = stripos(
+ $ua,
+ ";",
+ $pos_version_start
+ );
+ if ($pos_version_bracket > 1 && $pos_version_semicolon > 1) {
+ $pos_version_end = min(
+ $pos_version_bracket,
+ $pos_version_semicolon
+ );
+ } elseif ($pos_version_bracket > 1) {
+ $pos_version_end = $pos_version_bracket;
+ } else {
+ $pos_version_end = $pos_version_semicolon;
+ }
+ $version = explode(
+ "_",
+ substr(
+ $ua,
+ $pos_version_start,
+ $pos_version_end - $pos_version_start
+ )
+ );
+
+ $this->OS .= " " . implode($version, ".");
+ } else {
+ $this->OS = $fallback;
+
+ }
+ }
+
+ return $this->OS;
+ }
+
+ public function getLanguage($fallback = "en") {
+ if (empty($this->language)) {
+ $accept_languages = @$_SERVER["HTTP_ACCEPT_LANGUAGE"];
+ if (empty($accept_languages)) {
+ $this->language = $fallback;
+ return $this->language;
+ }
+
+ $this->language = explode(
+ ";",
+ explode(
+ ",",
+ $accept_languages
+ )[0]
+ )[0];
+ // Fix to look right (de_DE, not de-DE)
+ $this->language = str_replace(
+ "-",
+ "_",
+ $this->language
+ );
+ }
+
+ return $this->language;
+ }
+
+ public function getGeoIPCountry() {
+ if ($this->geoip_country!==FALSE && empty($this->geoip_country)) {
+ if ($this->geoip_db_country_available) {
+ $this->geoip_country = geoip_country_name_by_name($this->getIP());
+ }
+ }
+
+ return $this->geoip_country;
+ }
+
+ public function getGeoIPRegion() {
+ if ($this->geoip_region!==FALSE && empty($this->geoip_region)) {
+ if ($this->geoip_db_region_available) {
+ $record = geoip_region_by_name($this->getIP());
+ if ($record===FALSE) {
+ $this->geoip_region = FALSE;
+
+ } else {
+ $this->geoip_region = Array(
+ $record["region"],
+ geoip_region_name_by_code(
+ $record["country_code"],
+ $record["region"]
+ )
+ );
+
+ }
+ }
+ }
+
+ return $this->geoip_region;
+ }
+
+ public function getGeoIPCity() {
+ if ($this->geoip_city!==FALSE && empty($this->geoip_city)) {
+ if ($this->geoip_db_city_available) {
+ $record = geoip_record_by_name($this->getIP());
+
+ $this->geoip_city = Array(
+ $record["city"],
+ $record["postal_code"],
+ Array(
+ $record["latitude"],
+ $record["longitude"]
+ )
+ );
+ }
+ }
+
+ return $this->geoip_city;
+ }
+
+ public function getGeoIPCoordinates() {
+ $city = $this->getGeoIPCity();
+ if ($city !== FALSE) {
+ $coord = $city[2];
+ } else {
+ $coord = FALSE;
+ }
+
+ return $coord;
+ }
+ public function __construct() {
+ $this->geoip_db_country_available = TRUE; //geoip_db_avail(GEOIP_COUNTRY_EDITION);
+ $this->geoip_db_region_available = FALSE; //geoip_db_avail(GEOIP_REGION_EDITION_REV1);
+ $this->geoip_db_city_available = TRUE; //geoip_db_avail(GEOIP_CITY_EDITION_REV1);
+ }
+}
+
+?>
diff --git a/config.inc.php b/config.inc.php
new file mode 100644
index 0000000..eb52c10
--- /dev/null
+++ b/config.inc.php
@@ -0,0 +1,65 @@
+ "ip.malte70.de",
+ "URL" => "https://github.com/projekt-ancistrus/ipinfo",
+ "Copyright" => Array(
+ "Year" => "2016-".date("Y"),
+ "AuthorName" => "malte70",
+ "AuthorLink" => "https://malte70.de/"
+ )
+);
+
+
+/**
+ * Configuration for the widget
+ *
+ * Array keys should be mostly self-explaining; colors
+ * are given as RGB values. Y start coordinates are measured
+ * from the lower left corner of the first character, so don't
+ * forget to add the font size to a margin from top upper left
+ * image corner!
+ */
+$WidgetConfig = Array(
+ "Type" => "image/png",
+ "Size" => Array(320, 200),
+// "BackgroundColor" => Array( 17, 17, 17),
+// "TextColor" => Array( 1, 255, 112),
+// "HeadingColor" => Array(255, 255, 255),
+ "BackgroundColor" => Array(237, 235, 230),
+ "TextColor" => Array(164, 1, 20),
+ "HeadingColor" => Array( 0, 0, 0),
+ "FontSize" => 12,
+ "FontFamily" => "assets/otf/SourceCodePro-Regular.otf",
+ "FontSizeBig" => 13,
+ "FontFamilyBig" => "assets/otf/SourceCodePro-Semibold.otf",
+ "YCoords" => Array(
+ "Title" => Array( 32, 40),
+ "IP" => Array( 60, 85),
+ "Browser" => Array(110, 130),
+ "OS" => Array(155, 175),
+ ),
+);
+
+@$debug = in_array(
+ strtolower($_GET["debug"]),
+ Array(
+ "yes",
+ "on",
+ "true"
+ )
+);
+if ($debug) {
+ error_reporting(E_ALL);
+ ini_set("display_errors", "On");
+}
+
+?>
\ No newline at end of file
diff --git a/debug.php b/debug.php
new file mode 100644
index 0000000..05cbd99
--- /dev/null
+++ b/debug.php
@@ -0,0 +1,7 @@
+\n";
+$c .= " \t" . $info->getIP() . "
\n";
+$c .= "\t\n\t\t";
+$c .= 'Details';
+$c .= " \n\t
\n";
+$c .= "\t\n\t\t";
+$c .= 'Speedtest';
+$c .= " \n\t
\n";
+$c .= get_ad();
+$c .= "\n";
+
+$contentData = Array(
+ "Main" => $c
+);
+$footerData = Array(
+ "© " . $AppInfo["Copyright"]["Year"] . ' ' . $AppInfo["Copyright"]["AuthorName"] . '',
+ 'Powered by ' . $AppInfo["Name"] . '',
+ 'API'
+);
+
+$lang = substr(
+ $info->getLanguage(),
+ 0,
+ 2
+);
+if ($lang == "de") {
+ $msg_your_ip = "Deine IPâAdresse";
+} else {
+ $msg_your_ip = "Your IP";
+}
+$Data = Array(
+ "Meta" => Array(
+ "Lang" => $lang,
+ "Charset" => "UTF-8",
+ "Title" => $msg_your_ip . " :: " . $AppInfo["Name"],
+ "Author" => "Malte Bublitz",
+ "HumansTXT" => false,
+ "Stylesheet" => "assets/css/style.css"
+ ),
+ "Content" => Array(
+ "Header" => Array(
+ "LinkURL" => "./",
+ "Title" => $msg_your_ip
+ ),
+ "Content" => $contentData,
+ "Footer" => $footerData
+ )
+);
+
+if ($debug) {
+ header("Content-Type: text/plain; charset=".$Data["Meta"]["Charset"]);
+ print "==> \$Data\n";
+ print_r($Data);
+} else {
+ require_once("template.inc.php");
+}
+
+?>
\ No newline at end of file
diff --git a/info.php b/info.php
new file mode 100644
index 0000000..31b7d76
--- /dev/null
+++ b/info.php
@@ -0,0 +1,128 @@
+getIP();
+if ($info->getHostname() != $info->getIP()) {
+ $hostContent .= " / " . $info->getHostname();
+}
+$lang = substr(
+ $info->getLanguage(),
+ 0,
+ 2
+);
+function getMsg($lang, $id) {
+ global $info;
+ $is_ipv6 = $info->isIPv6();
+ $Translations = Array(
+ "de" => Array(
+ "Title" => "Deine IP",
+ "IP" => "IP-Adresse" . ($is_ipv6 ? " (IPv6)" : " (IPv4)"),
+ "IPv4" => "IP-Adresse (IPv4)",
+ "IPv6" => "IP-Adresse (IPv6)",
+ "Browser" => "Browser",
+ "OS" => "Betriebssystem",
+ "Lang" => "Sprache",
+ "UA" => "User-Agent",
+ "Loc" => "Ort"
+ ),
+ "en" => Array(
+ "Title" => "Your IP",
+ "IP" => "IP Address" . ($is_ipv6 ? " (IPv6)" : " (IPv4)"),
+ "IPv4" => "IP Address (IPv4)",
+ "IPv6" => "IP Address (IPv6)",
+ "Browser" => "Browser",
+ "OS" => "Operating System",
+ "Lang" => "Language",
+ "UA" => "User Agent",
+ "Loc" => "Location"
+ )
+ );
+
+ return $Translations[$lang][$id];
+}
+ob_start();
+?>
+
+=getMsg($lang, "IPv4")?>
+
+ =($info->isIPv6() ? "" : $hostContent)?>
+
+=getMsg($lang, "IPv6")?>
+
+ =($info->isIPv6() ? $hostContent : "")?>
+
+=getMsg($lang, "Browser")?>
+
+ =$info->getBrowser()?>
+
+=getMsg($lang, "OS")?>
+
+ =$info->getOS()?> (=getMsg($lang, "Lang")?>: =$info->getLanguage()?>)
+
+';
+ print "\$info->getGeoIPCountry() = " . $info->getGeoIPCountry() . "\n";
+
+ print "\n\$info->getGeoIPCity() = ";
+ print_r($info->getGeoIPCity());
+ print '';
+}
+if (!empty($info->getGeoIPCity()[0])) {
+ $coord = Array(
+ number_format($info->getGeoIPCity()[2][0], 4, ".", ""),
+ number_format($info->getGeoIPCity()[2][1], 4, ".", "")
+ );
+?>
+=getMsg($lang, "Loc")?>
+
+ =$info->getGeoIPCity()[0]?>, =$info->getGeoIPCountry()?>
+
+
+=getMsg($lang, "UA")?>
+
+ =$info->getUserAgent()?>
+
+ ob_get_clean()
+);
+$footerData = Array(
+ "© " . $AppInfo["Copyright"]["Year"] . ' ' . $AppInfo["Copyright"]["AuthorName"] . '',
+ 'Powered by ' . $AppInfo["Name"] . '',
+ 'API'
+);
+
+$Data = Array(
+ "Meta" => Array(
+ "Lang" => $lang,
+ "Charset" => "UTF-8",
+ "Title" => getMsg($lang, "Title") . " :: " . $AppInfo["Name"],
+ "Author" => "Malte Bublitz",
+ "HumansTXT" => false,
+ "Stylesheet" => "assets/css/style.css"
+ ),
+ "Content" => Array(
+ "Header" => Array(
+ //"LinkURL" => "./",
+ "LinkURL" => "https://ip.malte70.de/",
+ "Title" => getMsg($lang, "Title")
+ ),
+ "Content" => $contentData,
+ "Footer" => $footerData
+ )
+);
+
+require_once("template.inc.php");
+
+?>
diff --git a/ip.php b/ip.php
new file mode 100644
index 0000000..4d5eedf
--- /dev/null
+++ b/ip.php
@@ -0,0 +1,49 @@
+\n";
+$c .= " \t" . $info->getIP() . "
\n";
+$c .= "\t\n\t\t";
+$c .= 'Details';
+$c .= " \n\t
\n\n";
+
+$contentData = Array(
+ "Main" => $c
+);
+$footerData = Array(
+ "© " . $AppInfo["Copyright"]["Year"] . ' ' . $AppInfo["Copyright"]["AuthorName"] . '',
+ 'Powered by ' . $AppInfo["Name"] . ''
+);
+
+$lang = substr(
+ $info->getLanguage(),
+ 0,
+ 2
+);
+if ($lang == "de") {
+ $msg_your_ip = "Deine IPâAdresse";
+} else {
+ $msg_your_ip = "Your IP";
+}
+$Data = Array(
+ "Meta" => Array(
+ "Lang" => $lang,
+ "Charset" => "UTF-8",
+ "Title" => $msg_your_ip . " :: " . $AppInfo["Name"],
+ "Author" => "Malte Bublitz",
+ "HumansTXT" => false,
+ "Stylesheet" => "assets/css/style.css"
+ ),
+ "Content" => Array(
+ "Header" => NULL,
+ "Content" => $contentData,
+ "Footer" => $footerData
+ )
+);
+
+require_once("template.inc.php");
+?>
diff --git a/template.inc.php b/template.inc.php
new file mode 100644
index 0000000..40df25c
--- /dev/null
+++ b/template.inc.php
@@ -0,0 +1,51 @@
+This file should never be accessed direct.');
+}
+
+?>
+">
+
+ ">
+
+
+ =$Data["Meta"]["Title"]?>
+
+ ">
+
+ ">
+
+
+
+
+
+
+
+
+
+
+
+=$Data["Content"]["Content"]["Main"]?>
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/widget.php b/widget.php
new file mode 100644
index 0000000..871613f
--- /dev/null
+++ b/widget.php
@@ -0,0 +1,197 @@
+Fatal PHP-GD error! Cannot initialize new GD image stream.");
+
+
+// Background/Text/Heading color
+$background_color = imagecolorallocate(
+ $im,
+ $WidgetConfig["BackgroundColor"][0],
+ $WidgetConfig["BackgroundColor"][1],
+ $WidgetConfig["BackgroundColor"][2]
+);
+$text_color = imagecolorallocate(
+ $im,
+ $WidgetConfig["TextColor"][0],
+ $WidgetConfig["TextColor"][1],
+ $WidgetConfig["TextColor"][2]
+);
+$heading_color = imagecolorallocate(
+ $im,
+ $WidgetConfig["HeadingColor"][0],
+ $WidgetConfig["HeadingColor"][1],
+ $WidgetConfig["HeadingColor"][2]
+);
+
+
+/**
+ * Fill with background color
+ */
+imagefill($im, 0, 0, $background_color);
+
+
+/**
+ * Headline
+ */
+$headline = $AppInfo["Name"];
+$headline_box = imagettfbbox(
+ $WidgetConfig["FontSizeBig"],
+ 0,
+ $WidgetConfig["FontFamilyBig"],
+ $headline
+);
+$center = (imagesx($im)/2) - ($headline_box[2] - $headline_box[0])/2;
+imagettftext(
+ $im,
+ $WidgetConfig["FontSizeBig"],
+ 0,
+ $center,
+ $WidgetConfig["YCoords"]["Title"][0],
+ $heading_color,
+ $WidgetConfig["FontFamilyBig"],
+ $headline
+);
+
+/**
+ * IP
+ */
+imagettftext(
+ $im,
+ $WidgetConfig["FontSize"],
+ 0,
+ 25,
+ $WidgetConfig["YCoords"]["IP"][0],
+ $heading_color,
+ $WidgetConfig["FontFamily"],
+ "IP"
+);
+imagettftext(
+ $im,
+ $WidgetConfig["FontSize"],
+ 0,
+ 35,
+ $WidgetConfig["YCoords"]["IP"][1],
+ $text_color,
+ $WidgetConfig["FontFamily"],
+ $info->getIP()
+);
+
+
+/**
+ * Browser (Heading)
+ */
+// ImageString(
+// $im,
+// $WidgetConfig["FontSize"],
+// 10,
+// $WidgetConfig["YCoords"]["Browser"][0],
+// 'Browser',
+// $heading_color
+// );
+// // Browser (Value)
+// ImageString(
+// $im,
+// $WidgetConfig["FontSize"],
+// 18,
+// $WidgetConfig["YCoords"]["Browser"][1],
+// $info->getBrowser(),
+// $text_color
+// );
+imagettftext(
+ $im,
+ $WidgetConfig["FontSize"],
+ 0,
+ 25,
+ $WidgetConfig["YCoords"]["Browser"][0],
+ $heading_color,
+ $WidgetConfig["FontFamily"],
+ "Browser"
+);
+imagettftext(
+ $im,
+ $WidgetConfig["FontSize"],
+ 0,
+ 35,
+ $WidgetConfig["YCoords"]["Browser"][1],
+ $text_color,
+ $WidgetConfig["FontFamily"],
+ $info->getBrowser()
+);
+
+
+/**
+ * Operating System
+ */
+imagettftext(
+ $im,
+ $WidgetConfig["FontSize"],
+ 0,
+ 25,
+ $WidgetConfig["YCoords"]["OS"][0],
+ $heading_color,
+ $WidgetConfig["FontFamily"],
+ "Betriebssystem"
+);
+imagettftext(
+ $im,
+ $WidgetConfig["FontSize"],
+ 0,
+ 35,
+ $WidgetConfig["YCoords"]["OS"][1],
+ $text_color,
+ $WidgetConfig["FontFamily"],
+ $info->getOS()
+);
+
+
+/**
+ * Send Content-Type header
+ */
+header("Content-Type: ".$WidgetConfig["Type"]);
+header("Cache-Control: no-cache"); // HTTP/1.1
+header("Pragma: no-cache"); // HTTP/1.0
+
+imagepng($im);
+imagedestroy($im);
+
+?>