commit f490b457cfffa7b94e87051ecfc697bfe2498ae0 Author: jenz Date: Tue Aug 11 13:31:08 2026 +0200 initial repo creation diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6c4723b --- /dev/null +++ b/.gitignore @@ -0,0 +1,477 @@ +##### Windows +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +##### Linux +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +##### MacOS +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +##### Backup +*.bak +*.gho +*.ori +*.orig +*.tmp + +##### GPG +secring.* + +##### Dropbox +# Dropbox settings and caches +.dropbox +.dropbox.attr +.dropbox.cache + +##### SynopsysVCS +# Waveform formats +*.vcd +*.vpd +*.evcd +*.fsdb + +# Default name of the simulation executable. A different name can be +# specified with this switch (the associated daidir database name is +# also taken from here): -o / +simv + +# Generated for Verilog and VHDL top configs +simv.daidir/ +simv.db.dir/ + +# Infrastructure necessary to co-simulate SystemC models with +# Verilog/VHDL models. An alternate directory may be specified with this +# switch: -Mdir= +csrc/ + +# Log file - the following switch allows to specify the file that will be +# used to write all messages from simulation: -l +*.log + +# Coverage results (generated with urg) and database location. The +# following switch can also be used: urg -dir .vdb +simv.vdb/ +urgReport/ + +# DVE and UCLI related files. +DVEfiles/ +ucli.key + +# When the design is elaborated for DirectC, the following file is created +# with declarations for C/C++ functions. +vc_hdrs.h + +##### SVN +.svn/ + +##### Mercurial +.hg/ +.hgignore +.hgsigs +.hgsub +.hgsubstate +.hgtags + +##### Bazaar +.bzr/ +.bzrignore + +##### CVS +/CVS/* +**/CVS/* +.cvsignore +*/.cvsignore + +##### TortoiseGit +# Project-level settings +/.tgitconfig + +##### PuTTY +# Private key +*.ppk + +##### Vim +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +*~ +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +##### Emacs +# -*- mode: gitignore; -*- +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive + +# flymake-mode +*_flymake.* + +# eshell files +/eshell/history +/eshell/lastdir + +# elpa packages +/elpa/ + +# reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# cask packages +.cask/ +dist/ + +# Flycheck +flycheck_*.el + +# server auth directory +/server/ + +# projectiles files +.projectile + +# directory configuration +.dir-locals.el + +# network security +/network-security.data + +##### SublimeText +# Cache files for Sublime Text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache + +# Workspace files are user-specific +*.sublime-workspace + +# Project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using Sublime Text +# *.sublime-project + +# SFTP configuration file +sftp-config.json +sftp-config-alt*.json + +# Package control specific files +Package Control.last-run +Package Control.ca-list +Package Control.ca-bundle +Package Control.system-ca-bundle +Package Control.cache/ +Package Control.ca-certs/ +Package Control.merged-ca-bundle +Package Control.user-ca-bundle +oscrypto-ca-bundle.crt +bh_unicode_properties.cache + +# Sublime-github package stores a github token in this file +# https://packagecontrol.io/packages/sublime-github +GitHub.sublime-settings + +##### Notepad++ +# Notepad++ backups # +*.bak + +##### TextMate +*.tmproj +*.tmproject +tmtags + +##### VisualStudioCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +##### NetBeans +**/nbproject/private/ +**/nbproject/Makefile-*.mk +**/nbproject/Package-*.bash +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +##### JetBrains +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +##### Eclipse +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ +.apt_generated_test/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +# Uncomment this line if you wish to ignore the project description file. +# Typically, this file would be tracked if it contains build/dependency configurations: +#.project + +##### Dreamweaver +# DW Dreamweaver added files +_notes +_compareTemp +configs/ +dwsync.xml +dw_php_codehinting.config +*.mno + +##### CodeKit +# General CodeKit files to ignore +config.codekit +config.codekit3 +/min + +##### Gradle +.gradle +**/build/ +!src/**/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +##### Composer +composer.phar +/vendor/ + +# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control +# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file +composer.lock + +##### PHP CodeSniffer +# gitignore for the PHP Codesniffer framework +# website: https://github.com/squizlabs/PHP_CodeSniffer +# +# Recommended template: PHP.gitignore + +/wpcs/* + +##### SASS +.sass-cache/ +*.css.map +*.sass.map +*.scss.map + +##### Project related +config.php diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/config.example.php b/config.example.php new file mode 100644 index 0000000..7c17474 --- /dev/null +++ b/config.example.php @@ -0,0 +1,33 @@ + diff --git a/connect.php b/connect.php new file mode 100644 index 0000000..a9e125d --- /dev/null +++ b/connect.php @@ -0,0 +1,54 @@ + diff --git a/css/style.css b/css/style.css new file mode 100644 index 0000000..fb5ba64 --- /dev/null +++ b/css/style.css @@ -0,0 +1,1274 @@ +@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;700;900&display=swap'); + +/** + * Variable + */ +:root { + --layout_main_code--color: 26, 122, 191; + --layout_main--color: rgb(var(--layout_main_code--color)); + --layout_main--color_0_3: rgba(var(--layout_main_code--color), 0.3); + --layout_main--color_0_15: rgba(var(--layout_main_code--color), 0.15); + + --theme-background: #0f1015; + --theme-link: var(--layout_main--color); + --theme-text: #efefef; + --theme-text_light: #bdbdbd; + --theme-text_light-hover: #fff; + --theme-area_background_light: rgba(19, 20, 27, 1); + + --box-shadow: none; + --box--backgroundColor: var(--theme-area_background_light); + --box-shadow--child: 0 0 0 1px rgba(147, 161, 181, 0.2), 0 0 40px 0 transparent; + + --backdrop-background: rgba(19, 20, 27, 0.65); + --backdrop-text_color: #ffffff; + + --input--desc: #98a3ad; + --input-disabled: rgba(26, 122, 191, 0.50); + + --button-infos: #e06d22; + --button-light: #22242f; + --button-success: #267b3c; + --button-important: #ca1e1e; + --button-light-text: #ffffff; + --button--background-hover: rgba(255, 255, 255, 0.08); + + --button-text-color: #edf0f1; + --button-background-color: rgba(0, 136, 169, 1); + --button-background-hover: rgba(87, 118, 126, 0.8); + + --color-expired-: 56, 122, 98; + --color-active-: 221, 107, 32; + --color-permanent-: 197, 48, 48; + + --container--width: 1830px; + --line-hr: rgba(255, 255, 255, 0.1); +} + +/** + * Global + */ +* { + -webkit-box-sizing: border-box; + box-sizing: border-box; + margin: 0; + padding: 0; +} + +html { + height: 100%; + font-size: 10px; +} + +body { + font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, + 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; + font-size: 1.3rem; + line-height: 1.5; + height: 100%; + background-color: var(--theme-area_background_light); + margin: 0; + cursor: inherit !important; +} + +/** + * Header + */ +.header1 { + display: flex; + position: fixed; + top: 0; + width: 100%; + z-index: 1; + + justify-content: space-between; + align-items: center; + height: 60px; + padding: 17px; + background-color: rgba(0, 0, 0, 0.5); + border: none; +} + +.header1-icons { + display: inline-block; + order: 1; +} + +.header1-icons a:hover { + text-decoration: none; +} + +.header2 { + margin-top: 1.4cm; + display: flex; + width: 100%; + justify-content: space-between; + align-items: center; + height: 100px; + padding: 10px; + border: none; +} + +.header3 { + flex: 1 auto; + display: block; + height: 100%; + width: 20%; + padding: 2px; +} + +.header3 ul { + width: 100%; + height: 100%; + list-style: none; +} + +.header3 ul li { + margin-top: 8px; + position: relative; + width: 100%; + height: 46px; +} + +.header3 ul li a:hover, +.header3 ul li a:focus { + text-decoration: none; + box-shadow: inset 400px 0 0 0 rgba(0, 136, 169, 0.2); +} + +/** + * Login + */ +.login { + display: inline-block; + order: 2; +} + +.login p { + color: var(--theme-text); + font-size: 13px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.login a { + display: inline-block; +} + +.logo { + cursor: pointer; + order: 1; + margin-right: auto; +} + +/** + * Search Bar + */ +.search_input { + cursor: pointer; + order: 2; + display: inline-block; + text-align: center; + vertical-align: middle; + background-color: var(--box--backgroundColor); + width: 30%; + height: 100%; +} + +.search_input p { + color: var(--theme-text); + font-size: 13px; +} + +.search_input::after { + content: ""; + clear: both; + display: table; +} + +.input-header-search { + width: 300px; + height: 40px; + margin-top: 0.4cm; +} + +.input { + border: 2px solid var(--button-light); + ; + border-radius: 4px; + font-size: 15px; + padding: 5px; + color: var(--theme-text); + background-color: var(--box--backgroundColor); +} + +.input:focus { + outline: none; + border-color: #008afc; + box-shadow: 0 0 15px #008afc; + transition: box-shadow 0.2s, border-color 0.2s; +} + +#search_icon { + cursor: pointer; + background-color: var(--button-background-color); + color: var(--theme-text); + width: 40px; + height: 40px; + border: 0; + border-radius: 3px; + font-size: 15px; +} + +.body_content { + width: 100%; + height: 100%; + display: flex; + + flex-wrap: wrap; + align-items: flex-start; +} + +.not-active { + display: block; + padding: 15px 25px; + color: var(--theme-text_light); + position: relative; + z-index: 1; + overflow: hidden; + font-size: 15px; + transition: all 0.5s ease 0s; +} + +.active { + display: block; + padding: 15px 25px; + color: var(--theme-text_light); + position: relative; + z-index: 1; + overflow: hidden; + font-size: 15px; + transition: all 0.5s ease 0s; + border: none; + border-left: 5px var(--button-background-color) solid; +} + +/** + * Breadcrumb + */ +.breadcrumb { + font-size: 13px; + font-weight: 400; + padding: 10px 0; + margin-bottom: 20px; + margin-left: 1.5%; +} + +.breadcrumb>*:last-child { + font-weight: bold; +} + +.fa-angle-right:before { + color: white; +} + +/** + * Container + */ +.container { + flex: 2 auto; + display: block; + justify-content: center; + align-items: center; + width: 80%; + height: auto; + background-color: var(--theme-background); +} + +.container-header { + margin-top: 10px; +} + +.container-header>h1 { + font-size: 24px; + font-weight: bold; + line-height: 1.2; + letter-spacing: -0.02em; + margin: 0; + margin-left: 1.5%; + color: var(--theme-text); +} + +.container-header p { + color: var(--theme-link); + font-weight: bold; + font-size: 25px; + margin-left: 1.5%; +} + +.container-box1 { + border-radius: 7px; + margin-top: 20px; + margin-left: 1.5%; + width: 97%; + height: 40px; + display: flex; + justify-content: space-between; + align-items: center; + background-color: var(--theme-area_background_light); +} + +.container-box1 .order1 { + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + order: 1; + color: var(--theme-text); + font-size: 12px; +} + +.container-box1 .order2 { + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + order: 2; + color: var(--theme-text); + font-size: 12px; + line-height: 26px; +} + +.container-search { + border-radius: 7px; + margin-top: 10px; + margin-left: 1.5%; + width: 97%; + height: 40px; + display: flex; + justify-content: space-between; + align-items: center; + background-color: var(--theme-area_background_light); +} + +.search-button { + text-align: center; + cursor: pointer; + width: 97%; + margin-left: 1.5%; + height: 25px; + background-color: var(--theme-area_background_light); + transition: all 0.5s ease 0s; +} + +.search-button p { + color: var(--theme-text); + font-size: 13.5px; + font-weight: bold; +} + +.search-button:hover { + background-color: rgba(0, 136, 169, 0.2); +} + +/* +.container-search .search-button p { + color: var(--theme-text); + font-size: 13px; +} +*/ + +/* ERROR BOX */ +.error-box { + border-radius: 7px; + margin-top: 20px; + margin-bottom: 20px; + margin-left: 1.5%; + width: 97%; + height: auto; + align-items: center; + background-color: var(--theme-area_background_light); + text-align: center; + color: red; + font-size: 25px; +} + +/* CONTAINER 2 */ +.container-box2 { + border-radius: 7px; + margin-top: 20px; + margin-bottom: 20px; + margin-left: 1.5%; + width: 97%; + height: auto; + display: flex; + justify-content: space-between; + align-items: center; + background-color: var(--theme-area_background_light); +} + +.container-box2-table { + margin-top: 20px; + margin-bottom: 20px; + margin-left: 1.5%; + width: 97%; + height: auto; +} + +a { + -webkit-transition: color 0.2s ease; + transition: color 0.2s ease; + color: var(--theme-link); + text-decoration: none; +} + +a:hover { + text-decoration: revert; +} + +/** + * Layout + */ +.layout_container { + max-width: var(--container--width); + padding: 0 15px; + margin: 0 auto; + position: relative; +} + +.layout_box { + -webkit-box-shadow: var(--box-shadow); + box-shadow: var(--box-shadow); + border-radius: var(--border--radius); + background-color: var(--box--backgroundColor); +} + +.layout_box_title { + background-color: var(--layout_main--color); + padding: 16px; + border-top-left-radius: inherit; + border-top-right-radius: inherit; + color: #fff; + border-radius: var(--border--radius); +} + +li.layout_box_title { + list-style-type: none; +} + +.layout_box_title h2, +.layout_box_title h3, +.layout_box_title h4 { + padding: 0; + margin: 0; + color: #fff; + font-size: 16px; + font-weight: bold; +} + +.layout_box_small { + width: 98%; + max-width: 450px; +} + +.layout_box_medium { + width: 98%; + max-width: 700px; +} + +.layout_box-child { + -webkit-box-shadow: var(--box-shadow--child); + box-shadow: var(--box-shadow--child); + border-radius: var(--radius-3); +} + +.layout_topBar { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 1000; + background-color: var(--backdrop-background); + -webkit-backdrop-filter: var(--backdrop-filter-value); + backdrop-filter: var(--backdrop-filter-value); + color: var(--backdrop-text_color); + -webkit-box-shadow: 0 0 40px 0 rgba(56, 55, 93, 0.3); + box-shadow: 0 0 40px 0 rgba(56, 55, 93, 0.3); + padding: 10px 0; +} + +/** + * Footer + */ +.footer { + background-color: var(--box--backgroundColor); + color: var(--theme-text); + width: 100%; +} + +.footer>.layout_container { + padding: 20px 15px; +} + +.footer a { + font-weight: bold; +} + +/** + * Buttons + */ +.button, +.ok { + display: block; + font-size: 14px; + font-weight: 400; + text-align: center; + font-family: inherit; + padding: 10px 20px; + border: none; + border-radius: 6px; + color: #fff !important; + position: relative; + z-index: 1; + overflow: hidden; + cursor: pointer; + border: 0; +} + +.button a, +.ok a { + color: inherit; +} + +.button a:hover, +.ok a:hover { + text-decoration: none; +} + +.button:hover, +.ok:hover { + text-decoration: none; +} + +.button::after, +.ok::after { + content: ''; + position: absolute; + z-index: -1; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: var(--button--background-hover); + -webkit-transform: scaleX(0); + transform: scaleX(0); + height: 100%; + -webkit-transition-property: -webkit-transform; + transition-property: -webkit-transform; + transition-property: transform; + transition-property: transform, -webkit-transform; + -webkit-transition-duration: 0.7s; + transition-duration: 0.7s; + -webkit-transition-timing-function: ease-out; + transition-timing-function: ease-out; + -webkit-transform-origin: left; + transform-origin: left; +} + +.button:hover::after, +.ok:hover::after { + -webkit-transform: scaleX(1); + transform: scaleX(1); + -webkit-transition-timing-function: cubic-bezier(0.52, 1.64, 0.37, 0.66); + transition-timing-function: cubic-bezier(0.52, 1.64, 0.37, 0.66); +} + +.button-success, +.ok-success { + background-color: var(--button-success); +} + +.button-infos, +.ok-infos { + background-color: var(--button-infos); +} + +.button-important, +.ok-important { + background-color: var(--button-important); +} + +.button-primary, +.ok-primary { + background-color: var(--layout_main--color); +} + +.button-light, +.ok-light { + background-color: var(--button-light); + color: var(--button-light-text) !important; +} + +.button\:line, +.ok\:line { + display: inline-block; +} + +.button\:full, +.ok\:full { + width: 100%; +} + +.kban-buttons { + display: inline-block; + order: 1; +} + +.kban-buttons button { + margin-top: 10px; + display: block; + width: 170px; + position: relative; + z-index: 1; + overflow: hidden; + font-size: 14px; + font-weight: 400; + text-align: center; + font-family: inherit; +} + +.kban-form-button { + width: 100%; + margin-bottom: 10px; + margin-top: 20px; +} + +/** + * Table + */ +.table { + width: 100%; + height: 100%; +} + +.table table { + width: 100%; + border-spacing: 0; +} + +.table table thead { + text-align: left; + background-color: var(--layout_main--color); + font-weight: bold; + color: #fff; +} + +.table table thead th { + padding: 5px; +} + +.table table thead th:first-child { + border-top-left-radius: 5px; +} + +.table table thead th:last-child { + border-top-right-radius: 5px; +} + +.table table tbody { + font-size: 13px; + text-align: left; + cursor: pointer; + -webkit-transition: background-color 0.2s ease; + transition: background-color 0.2s ease; +} + +.table table tbody td { + padding: 10px; + color: var(--theme-text); +} + +.table_hide>td { + padding: 0 !important; +} + +/** + * Row + */ +.row-expired .row-length { + color: rgba(var(--color-expired-)); + background-color: rgba(var(--color-expired-), 0.1); +} + +.row-expired:hover { + background-color: rgba(var(--color-expired-), 0.3); + transition: background 1s, box-shadow 0.2s; +} + +.row-permanent .row-length { + color: rgba(var(--color-permanent-)); + background-color: rgba(var(--color-permanent-), 0.1); +} + +.row-permanent:hover { + background-color: rgba(var(--color-permanent-), 0.3); + transition: background 1s, box-shadow 0.2s; +} + +.row-active .row-length { + color: rgba(var(--color-active-)); + background-color: rgba(var(--color-active-), 0.1); +} + +.row-active:hover { + background-color: rgba(var(--color-active-), 0.3); + transition: background 1s, box-shadow 0.2s; +} + +.row-expired:active, +.row-active:active, +.row-permanent:active { + background-color: #1d307c; +} + +.row-block { + display: none; + width: 100%; + height: auto; + padding-bottom: 10px; + justify-content: space-between; +} + +/** + * kban Details + */ +.kban_details { + margin-top: 5px; + margin-left: 10px; + list-style: none; + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; + order: 2; +} + +.kban_details li { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + padding: 5px 0; + -webkit-box-flex: 0; + -ms-flex: 0 1 100%; + flex: 0 1 100%; + overflow: hidden; +} + +.kban_details li>span { + display: block; +} + +.kban_details li>span:first-child { + color: white; + -webkit-box-flex: 0; + -ms-flex: 0 0 200px; + flex: 0 0 200px; +} + +.kban_details li>span:last-child { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; +} + +.kban_details li>span:last-child>span { + -webkit-box-flex: 0; + -ms-flex: 0 1 99%; + flex: 0 1 99%; +} + +/** + * Form + */ +form { + width: 100%; + height: 100%; +} + +.kban-form { + background-color: var(--theme-background); + margin-top: 50px; + margin-bottom: 20px; + margin-left: 30%; + width: 40%; + height: 90%; + display: block; + border-radius: 7px; + + align-items: center; +} + +.kban-form .header { + background-color: var(--button-background-color); + width: 100%; + height: 10%; + display: flex; + justify-content: center; + align-items: center; + + border-top-left-radius: 7px; + border-top-right-radius: 7px; +} + +.kban-form .header p { + margin-left: 5px; + color: var(--theme-text); + font-weight: bold; + font-size: 22px; +} + +.kban-form .border { + margin-top: 6px; + width: 100%; + height: 4px; + background-color: var(--theme-area_background_light); +} + +.kban-form .input-group { + margin-top: 20px; + display: block; + width: 80%; + margin-left: 10%; + height: auto; +} + +.kban-form label { + color: var(--theme-text_light); + font-weight: bold; + font-size: 15px; + display: block; +} + +form[action="index.php"] p { + -webkit-transition: color 0.2s ease; + transition: color 0.2s ease; + color: var(--theme-link); + text-decoration: none; +} + +form[action="index.php"] p:hover { + text-decoration: underline; +} + +/** + * Add - Edit kban + */ +input[disabled] { + background-color: var(--theme-background); + opacity: 1; + color: var(--input-disabled); + border: none; +} + +.kban-input { + display: block; + height: 35px; + width: 100%; +} + +.add-select { + height: 35px; + width: 300px; +} + +.edit-select { + height: 35px; + width: 100px; + display: inline-block; +} + +.select { + border: 2px solid var(--button-light); + ; + border-radius: 4px; + font-size: 15px; + padding: 5px; + color: var(--theme-text); + background-color: var(--box--backgroundColor); +} + +.select:focus, +.select:hover { + outline: none; + border-color: #008afc; + box-shadow: 0 0 15px #008afc; + transition: box-shadow 0.2s, border-color 0.2s; +} + +.error { + margin-top: 10px; + width: 100%; + text-align: center; +} + +.error p { + text-align: center; + color: red; + font-size: 15px; + font-weight: bold; +} + +/** + * Search pop-up + */ +.search-modal-body { + display: none; + position: fixed; + z-index: 1; + left: 0; + top: 0; + height: 100%; + width: 100%; + overflow: auto; + background-color: rgba(0, 0, 0, 0.5); + + transition: all 0.4s ease 0s; +} + +.search-modal { + overflow: hidden; + margin: 10% auto; + width: 40%; + height: 275px; + box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2), 0 7px 20px 0 rgba(0, 0, 0, 0.17); + animation-name: modalopen; + animation-duration: 1s; + + background-color: var(--theme-area_background_light); +} + +.search-modal .header { + width: 100%; + height: 15%; + + border-top-left-radius: 7px; + border-top-right-radius: 7px; + + display: flex; + justify-content: space-between; + align-items: center; + background-color: var(--button-background-color); +} + +.search-modal .input-group { + margin-top: 20px; + display: block; + width: 80%; + height: auto; + margin-left: 10%; + } + +.search-modal .header p { + order: 1; + margin-left: 2.5%; + font-size: 20px; + font-weight: bold; + color: var(--theme-text); +} + +.search-modal .search-modal-btn-close { + order: 2; + margin-right: 2.5%; + cursor: pointer; + transition: all 0.5s ease 0s; +} + +.search-modal .search-modal-btn-close:hover { + color: var(--button-important); +} + +.search-modal-input { + display: block; + height: 35px; + width: 100%; +} + +.search-modal label { + display: block; + color: var(--theme-text_light); + font-weight: bold; + font-size: 15px; +} + +@keyframes modalopen { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + +/** + * Fade Effect + */ +@-webkit-keyframes fadeIn { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@keyframes fadeIn { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +/** + * Scrollbar + */ +::-webkit-scrollbar { + width: 10px; +} + +::-webkit-scrollbar-track { + background-color: var(--theme-area_background_light); +} + +::-webkit-scrollbar-thumb { + background: var(--button-background-color); +} + +/** + * Social Icons + */ +#steam_group { + padding: 5px; + border-radius: 1cm; + background-color: #1b2838 !important; + color: white; + font-size: 20px; + cursor: pointer; + transition: all 0.3s ease 0s; +} +#steam_group i { + margin-left: 5px; +} + +#discord { + margin-left: 10px; + border-radius: 1cm; + padding: 5px 5px; + background-color: #7289da !important; + color: white; + font-size: 20px; + border: none; + border-radius: 50px; + cursor: pointer; + text-align: center; + transition: all 0.3s ease 0s; +} + +/* TODO: Allow the user to change the theme +#user_action_change_dark { + color: yellow; + font-size: 20px; +} +*/ + +/** + * Flex + */ +.flex { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: space-evenly; + -ms-flex-pack: space-evenly; + justify-content: space-evenly; +} + +.flex-jc\:left { + justify-content: left; +} + +.flex-jc\:center { + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} + +.flex-jc\:right { + justify-content: right; +} + +.flex-jc\:space-between { + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; +} + +.flex-jc\:end { + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; +} + +.flex-jc\:start { + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; +} + +.flex-ai\:center { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.flex-ai\:start { + -webkit-box-align: start; + -ms-flex-align: start; + align-items: flex-start; +} + +.flex-ai\:end { + -webkit-box-align: end; + -ms-flex-align: end; + align-items: flex-end; +} + +.flex-fd\:column { + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} + +.flex-wrap\:wrap { + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} + +.flex\:11 { + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; + width: 100%; +} + +/** + * Others - Misc + */ +div span.left, +div span.right { + display: inline-block; + width: 50%; +} + +span.left { + float: left; +} + +span.right { + float: right; + text-align: right; +} + +.text\:center { + text-align: center; +} + +.text\:left { + text-align: left; +} + +.text\:right { + text-align: right; +} + +.text\:italic { + font-style: italic; +} + +.text\:bold { + font-weight: bold; +} + +/* - Action Window - */ +.kban-action-window { + display: none; + position: fixed; + z-index: 1; + left: 0; + top: 1; + height: auto; + width: 30%; + margin-top: 60px; + margin-left: 35%; + overflow: hidden; + box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2), 0 7px 20px 0 rgba(0, 0, 0, 0.17); + animation-name: modalopen; + animation-duration: 1s; + background-color: var(--theme-area_background_light); + transition: all 0.4s ease 0s; +} + +.kban-action-window .header { + border-top-left-radius: 5px; + border-top-right-radius: 5px; + + width: 100%; + height: 18%; + background-color: var(--button-background-color); + display: block; + position: relative; + text-align: center; +} + +.kban-action-window .header p { + color: white; + font-size: 30px; +} + +.kban-action-window .info { + width: 100%; + height: auto; + display: block; + position: relative; +} + +.kban-action-window .info .kban_details span { + color: white; + font-weight: bold; +} + +.kban-action-window .info-footer { + width: 100%; + height: 30%; + background-color: var(--box--backgroundColor); + display: block; +} + +.kban-action-window .info-footer button { + float: right; + margin-right: 10px; +} diff --git a/footer.php b/footer.php new file mode 100644 index 0000000..8f5ac37 --- /dev/null +++ b/footer.php @@ -0,0 +1,13 @@ + + + diff --git a/functions_global.php b/functions_global.php new file mode 100644 index 0000000..3349d64 --- /dev/null +++ b/functions_global.php @@ -0,0 +1,917 @@ +", "<", "&", "%", "|", "^", "~", "(", ")"); + return str_replace($replacements, "", $input); + } + } + + class Admin { + public $adminID = -1; + public $adminGroupID = -1; + public $adminSteamID = ""; + public $adminUser = ""; + + public function IsLoginValid($steamID, $secret_key, $bInitialVerification) { + if (empty($steamID) || empty($secret_key) || $secret_key !== $GLOBALS['SECRET_KEY']) { + return false; + } + + $sql = "SELECT aid FROM sb_admins WHERE authid = ?"; + $stmt = $GLOBALS['SBPP']->prepare($sql); + $stmt->bind_param("s", $steamID); + $stmt->execute(); + $queryResult = $stmt->get_result(); + $stmt->close(); + + // Fetch the result from the query + $row = $queryResult->fetch_assoc(); + if ($row === null) { + return false; + } + $sbppaid = $row['aid']; + + // Compare the cookie 'aid' with the result from the query + if (!$bInitialVerification && !isset($_COOKIE['aid'])) { + return false; + } + + if (!$bInitialVerification && $sbppaid != $_COOKIE['aid']) { + return false; + } + + $sql = "SELECT * FROM `sb_admins` WHERE `authid`=?"; + $stmt = $GLOBALS['SBPP']->prepare($sql); + $stmt->bind_param("s", $steamID); + $stmt->execute(); + $queryResult = $stmt->get_result(); + $stmt->close(); + + if ($queryResult->num_rows <= 0) { + return false; + } + + $acceptableGroups = array_merge(GID_STAFF, GID_ADMIN); + $resultsAAA = $queryResult->fetch_all(MYSQLI_ASSOC); + foreach ($resultsAAA as $result) { + $gid = $result['gid']; + if (!in_array($gid, $acceptableGroups) || $gid == -1) { + return false; + } + } + + return true; + } + + public function UpdateAdminInfo($steamID) { + if (!isset($_COOKIE['secret_key'])) { + return false; + } + + $secret_key = $_COOKIE['secret_key']; + if (!$this->IsLoginValid($steamID, $secret_key, false)) { + return false; + } + + $sql = "SELECT `aid`, `gid`, `authid`, `user` FROM `sb_admins` WHERE `authid`=?"; + $stmt = $GLOBALS['SBPP']->prepare($sql); + $stmt->bind_param("s", $steamID); + $stmt->execute(); + $queryResult = $stmt->get_result(); + + if ($queryResult->num_rows <= 0) { + $stmt->close(); + return false; + } + + $result = $queryResult->fetch_assoc(); + $stmt->close(); + + $this->adminID = $result['aid']; + $this->adminGroupID = $result['gid']; + $this->adminSteamID = $result['authid']; + $this->adminUser = $result['user']; + + return true; + } + + public function GetAdminNameFromSteamID($steamID) { + $steamID = (string) ($steamID ?? ''); + if (!str_contains($steamID, "STEAM")) { + return "CONSOLE"; + } + + $sql = "SELECT * FROM `sb_admins` WHERE `authid`=?"; + $stmt = $GLOBALS['SBPP']->prepare($sql); + $stmt->bind_param("s", $steamID); + $stmt->execute(); + $queryResult = $stmt->get_result(); + $stmt->close(); + + $results = $queryResult->fetch_all(MYSQLI_ASSOC); + foreach ($results as $result) { + return $result['user']; + } + + return "Admin Deleted"; + } + + public function DoesHaveFullAccess() { + if (!isset($_COOKIE['steamID'])) { + return false; + } + + if (in_array($this->adminGroupID, GID_STAFF)) { + return true; + } + + return false; + } + + } + + class Kban { + public function UnbanByID($id, $reasonA) { + if (empty($reasonA)) { + $reasonA = "No Reason"; + } + + $reason = Utility::sanitizeInput($reasonA); + + if (!isset($_COOKIE['steamID'])) { + return false; // Should never happen but better be safe + } + + $admin = new Admin(); + if (!$admin->UpdateAdminInfo($_COOKIE['steamID'])) { + return false; + } + + $adminName = $admin->adminUser; + $adminSteamID = $admin->adminSteamID; + + $kban = new Kban(); + $resultsB = $kban->getKbanInfoFromID($id); + if ($resultsB === null) { + return false; + } + $length = $resultsB['length']; + + $time_removed = time(); + + $sql = "UPDATE `KbRestrict_CurrentBans` SET `is_expired`=1, `is_removed`=1, `web_unban_required`=1, + `admin_name_removed`=?, `admin_steamid_removed`=?, `reason_removed`=?, + `time_stamp_removed`=? WHERE `id`=?"; + $stmt = $GLOBALS['DB']->prepare($sql); + $stmt->bind_param("ssssi", $adminName, $adminSteamID, $reason, $time_removed, $id); + $stmt->execute(); + $stmt->close(); + + $results = $this->getKbanInfoFromID($id); + if ($results === null) { + return false; + } + $playerName = $results['client_name']; + $playerSteamID = $results['client_steamid']; + $message = "Kban Removed (was $length minutes. Reason: $reason)"; + $time_stamp_start = time(); + + GetRowInfo($id); + + $sql = "INSERT INTO `KbRestrict_weblogs` (`client_name`, `client_steamid`, `admin_name`, `admin_steamid`, `message`, `time_stamp`) "; + $sql .= "VALUES (?, ?, ?, ?, ?, ?)"; + + $stmt = $GLOBALS['DB']->prepare($sql); + $stmt->bind_param("sssssi", $playerName, $playerSteamID, $adminName, $adminSteamID, $message, $time_stamp_start); + $stmt->execute(); + $stmt->close(); + + //echo ""; + echo ""; + + return true; + } + + public function RemoveKbanFromDB($id) { + $admin = new Admin(); + $adminSteamID = isset($_COOKIE['steamID']) ? $_COOKIE['steamID'] : ""; + $admin->UpdateAdminInfo($adminSteamID); + if (!IsAdminLoggedIn() || !$admin->DoesHaveFullAccess()) { + return false; + } + + $resultsC = $this->getKbanInfoFromID($id); + if ($resultsC === null) { + return false; + } + $playerName = $resultsC['client_name']; + $playerSteamID = $resultsC['client_steamid']; + $length = $resultsC['length']; + $reason = $resultsC['reason']; + $isExpired = ($resultsC['is_expired'] == 1); + $isRemoved = ($resultsC['is_removed'] == 1); + $status = "Active"; + if ($isExpired && !$isRemoved) { + $status = "Expired"; + } + if ($isRemoved) { + $status = "Removed"; + } + + $message = "KBan Deleted (was $length minutes. Issued for: $reason. Kban was $status)"; + + $admin->UpdateAdminInfo($_COOKIE['steamID']); + $adminName = $admin->adminUser; + $adminSteamID = $admin->adminSteamID; + $time_stamp = time(); + + // No longer a hard DELETE — flag the row for the plugin to reconcile (pull the + // ban off disk if it's still active there) and delete once it's done. + $stmt = $GLOBALS['DB']->prepare("UPDATE `KbRestrict_CurrentBans` SET `web_ban_delete`=1 WHERE `id` = ?"); + $stmt->bind_param('i', $id); + $stmt->execute(); + $stmt->close(); + + $stmt = $GLOBALS['DB']->prepare("INSERT INTO `KbRestrict_weblogs` (`client_name`, `client_steamid`, `admin_name`, `admin_steamid`, `message`, `time_stamp`) VALUES (?, ?, ?, ?, ?, ?)"); + $stmt->bind_param('sssssi', $playerName, $playerSteamID, $adminName, $adminSteamID, $message, $time_stamp); + $stmt->execute(); + $stmt->close(); + + echo ""; + //echo ""; + return true; + } + + public function formatLength($seconds) { + /* if less than one minute */ + if ($seconds < 60) { + return "$seconds Seconds"; + } + + /* if one minute or more */ + if ($seconds >= 60 && $seconds < 3600) { + $minutes = ($seconds / 60); + $minutesPhrase = ($minutes > 1) ? "Minutes" : "Minute"; + return "$minutes $minutesPhrase"; + } + + /* If hour or more*/ + if ($seconds >= 3600 && $seconds < 86400) { + $hours = intval(($seconds / 3600)); + $minutes = intval((($seconds / 60) % 60)); + $hoursPhrase = ($hours > 1) ? "Hours" : "Hour"; + $minutesPhrase = ($minutes > 1) ? "Minutes" : "Minute"; + + if ($minutes <= 0) { + return "$hours $hoursPhrase"; + } + return "$hours $hoursPhrase, $minutes $minutesPhrase"; + } + + /* If day or more */ + if ($seconds >= 86400 && $seconds < 604800) { + $days = intval(($seconds / 86400)); + $hours = intval((($seconds / 3600) % 24)); + $daysPhrase = ($days > 1) ? "Days" : "Day"; + $hoursPhrase = ($hours > 1) ? "Hours" : "Hour"; + + if ($hours <= 0) { + return "$days $daysPhrase"; + } + return "$days $daysPhrase, $hours $hoursPhrase"; + } + + /* if week or more */ + if ($seconds >= 604800 && $seconds < 2592000) { + $weeks = intval(($seconds / 604800)); + $days = intval((($seconds / 86400) % 7)); + $weeksPhrase = ($weeks > 1) ? "Weeks" : "Week"; + $daysPhrase = ($days > 1) ? "Days" : "Day"; + + if ($days <= 0) { + return "$weeks $weeksPhrase"; + } + return "$weeks $weeksPhrase, $days $daysPhrase"; + } + + /* if month or more */ + if ($seconds >= 2592000) { + $months = intval(($seconds / 2592000)); + $days = intval((($seconds / 86400) % 30)); + $monthsPhrase = ($months > 1) ? "Months" : "Month"; + $daysPhrase = ($days > 1) ? "Days" : "Day"; + + if ($days <= 0) { + return "$months $monthsPhrase"; + } + return "$months $monthsPhrase, $days $daysPhrase"; + } + } + + public function formatPlaytime($minutes) { + $minutes = intval($minutes); + $hours = intval($minutes / 60); + $mins = $minutes % 60; + + $hoursPhrase = ($hours == 1) ? "Hour" : "Hours"; + $minsPhrase = ($mins == 1) ? "Minute" : "Minutes"; + + if ($hours <= 0) { + return "$mins $minsPhrase"; + } + if ($mins <= 0) { + return "$hours $hoursPhrase"; + } + return "$hours $hoursPhrase, $mins $minsPhrase"; + } + + // Looks up a player's total accumulated playtime (in minutes) from the + // separate playtime-stats database, so a web-created kban can be baselined + // against the same clock the sourcemod plugin uses. Returns 0 if the player + // has no playtime record (e.g. has never connected to the server). + public function GetPlaytimeMinutes($steamID) { + $stmt = $GLOBALS['DB_PLAYTIME']->prepare( + "SELECT SUM(ze_time) AS ze_time_total FROM player_time WHERE steam_id = ? GROUP BY steam_id ORDER BY ze_time_total DESC" + ); + $stmt->bind_param("s", $steamID); + $stmt->execute(); + $result = $stmt->get_result(); + $row = $result->fetch_assoc(); + $stmt->close(); + + return $row ? intval($row['ze_time_total']) : 0; + } + + public function getKbanInfoFromID($id) { + $stmt = $GLOBALS['DB']->prepare("SELECT * FROM `KbRestrict_CurrentBans` WHERE `id` = ? AND `web_ban_delete` = 0"); + $stmt->bind_param("i", $id); + $stmt->execute(); + $query = $stmt->get_result(); + $result = $query->fetch_assoc(); + $stmt->close(); + return $result ?: null; + } + + public function GetKbansNumber($steamID, $IP = "") { + $search = (empty($steamID)) ? $IP : $steamID; + $searchMethod = (empty($steamID)) ? "client_ip" : "client_steamid"; + + $stmt = $GLOBALS['DB']->prepare("SELECT COUNT(*) AS total FROM `KbRestrict_CurrentBans` WHERE `$searchMethod` = ? AND `web_ban_delete` = 0"); + $stmt->bind_param("s", $search); + $stmt->execute(); + $queryA = $stmt->get_result(); + $row = $queryA->fetch_assoc(); + $stmt->close(); + $rows = intval($row['total'] ?? 0); + return $rows; + } + + public function GetRealKbansNumber($steamID, $IP = "") { + $search = (empty($steamID)) ? $IP : $steamID; + $searchMethod = (empty($steamID)) ? "client_ip" : "client_steamid"; + + $stmt = $GLOBALS['DB']->prepare("SELECT COUNT(*) AS total FROM `KbRestrict_CurrentBans` WHERE `$searchMethod` = ? AND `is_removed` = 0 AND `web_ban_delete` = 0"); + $stmt->bind_param("s", $search); + $stmt->execute(); + $queryA = $stmt->get_result(); + $row = $queryA->fetch_assoc(); + $stmt->close(); + $rows = intval($row['total'] ?? 0); + return $rows; + } + + public function addNewKban($playerNameA, $playerSteamID, $length, $reasonA) { + $admin = new Admin(); + $admin->UpdateAdminInfo($_COOKIE['steamID']); + $adminName = $admin->adminUser; + $adminSteamID = $admin->adminSteamID; + + $playerName = Utility::sanitizeInput($playerNameA); + $reason = Utility::sanitizeInput($reasonA); + $lengthInMinutes = ($length / 60); + $time_stamp_start = time(); + $time_stamp_start_sql = date('Y-m-d H:i:s', $time_stamp_start); + + if ($length <= -1) { + $lengthInMinutes = 30; + } else if ($length == 0) { + $lengthInMinutes = 0; + } + + if ($this->IsSteamIDAlreadyBanned($playerSteamID)) { + die(); + } + + if ($lengthInMinutes == 0) { + // Permanent - no playtime baseline needed + $time_played_start = -1; + $time_played_end = -1; + } else { + $time_played_start = $this->GetPlaytimeMinutes($playerSteamID); + $time_played_end = ($time_played_start + $lengthInMinutes); + } + + // Use prepared statements for the insertion into `KbRestrict_CurrentBans` + $sql = "INSERT INTO `KbRestrict_CurrentBans` + (`client_name`, `client_steamid`, `client_ip`, `admin_name`, `admin_steamid`, `reason`, + `map`, `length`, `time_stamp_start`, `time_played_start`, `time_played_end`, `is_expired`, `is_removed`, + `admin_name_removed`, `admin_steamid_removed`, `time_stamp_removed`, `reason_removed`, `web_addban_required`) + VALUES (?, ?, 'Unknown', ?, ?, ?, 'Web Ban', ?, ?, ?, ?, 0, 0, 'null', 'null', '0', 'null', 1)"; + + $stmt = $GLOBALS['DB']->prepare($sql); + $stmt->bind_param("sssssisii", $playerName, $playerSteamID, $adminName, $adminSteamID, $reason, $lengthInMinutes, $time_stamp_start_sql, $time_played_start, $time_played_end); + $stmt->execute(); + $stmt->close(); + + $message = "Kban Added ("; + if ($lengthInMinutes >= 1) { + $message .= "$lengthInMinutes Minutes"; + } else if ($lengthInMinutes == 0) { + $message .= "Permanent"; + } else { + $message .= "Session"; + } + $message .= ")"; + + // Use prepared statements for the insertion into `KbRestrict_weblogs` + $sql = "INSERT INTO `KbRestrict_weblogs` + (`client_name`, `client_steamid`, `admin_name`, `admin_steamid`, `message`, `time_stamp`) + VALUES (?, ?, ?, ?, ?, ?)"; + + $stmt = $GLOBALS['DB']->prepare($sql); + $stmt->bind_param("sssssi", $playerName, $playerSteamID, $adminName, $adminSteamID, $message, $time_stamp_start); + $stmt->execute(); + $stmt->close(); + + echo ""; + //echo ""; + } + + public function EditKban($id, $playerNameA, $playerSteamID, $length, $reasonA) { + $admin = new Admin(); + $admin->UpdateAdminInfo($_COOKIE['steamID']); + $adminName = $admin->adminUser; + $adminSteamID = $admin->adminSteamID; + + $playerName = Utility::sanitizeInput($playerNameA); + $reason = Utility::sanitizeInput($reasonA); + $lengthInMinutes = ($length / 60); + + $info = $this->getKbanInfoFromID($id); + if ($info === null) { + return false; + } + + if ($length <= -1) { + $lengthInMinutes = -1; + } else if ($length == 0) { + $lengthInMinutes = 0; + } + + $time_played_start = intval($info['time_played_start']); + + if ($lengthInMinutes <= 0) { + // Permanent (or zero-length) - no expiry threshold + $time_played_end = -1; + } else if ($time_played_start == -1) { + // Not yet baselined by the plugin - leave as -1, the plugin computes a + // real end value once it establishes the player's actual playtime baseline. + $time_played_end = -1; + } else { + $time_played_end = ($time_played_start + $lengthInMinutes); + } + + // time_played_start is left untouched — it's the plugin's own baseline and + // must not be reset by an edit. Only the expiry threshold (time_played_end) + // is recalculated from it, along with is_expired being cleared so the ban + // becomes active again under its new duration. + $sql = "UPDATE `KbRestrict_CurrentBans` SET `client_name`=?, `client_steamid`=?, `reason`=?, `length`=?, `time_played_end`=?, `is_expired`=0, `web_edit_required`=1 WHERE `id`=?"; + $stmt = $GLOBALS['DB']->prepare($sql); + $stmt->bind_param("sssiii", $playerName, $playerSteamID, $reason, $lengthInMinutes, $time_played_end, $id); + $stmt->execute(); + $stmt->close(); + + $message = "Kban Edited ("; + if ($playerName != $info['client_name']) { + $message .= " New Name: $playerName"; + } + if ($playerSteamID != $info['client_steamid']) { + $message .= " New SteamID: $playerSteamID"; + } + if ($reason != $info['reason']) { + $message .= " New Reason: $reason"; + } + + if ($lengthInMinutes != $info['length']) { + if ($lengthInMinutes >= 1) { + $message .= " New Length: $lengthInMinutes Minutes"; + } else if ($lengthInMinutes == 0) { + $message .= " New Length: Permanent"; + } else { + $message .= " New Length: Session"; + } + } + + $message .= " )"; + + $playerNameOld = $info['client_name']; + $playerSteamIDOld = $info['client_steamid']; + $time = time(); + + // Use prepared statements for the INSERT query + $sql = "INSERT INTO `KbRestrict_weblogs` (`client_name`, `client_steamid`, `admin_name`, `admin_steamid`, `message`, `time_stamp`) VALUES (?, ?, ?, ?, ?, ?)"; + $stmt = $GLOBALS['DB']->prepare($sql); + $stmt->bind_param("sssssi", $playerNameOld, $playerSteamIDOld, $adminName, $adminSteamID, $message, $time); + $stmt->execute(); + $stmt->close(); + + echo ""; + //echo ""; + } + + public function IsSteamIDAlreadyBanned($steamID) { + $stmt = $GLOBALS['DB']->prepare("SELECT * FROM `KbRestrict_CurrentBans` WHERE `client_steamid` = ? AND `web_ban_delete` = 0"); + $stmt->bind_param("s", $steamID); + $stmt->execute(); + $query = $stmt->get_result(); + $results = $query->fetch_all(MYSQLI_ASSOC); + $stmt->close(); + + foreach ($results as $result) { + $isActive = ($result['is_expired'] == 0 && $result['is_removed'] == 0); + + if ($isActive) { + return true; // Early return when a matching active ban is found + } + } + + return false; + } + + } + + function IsAdminLoggedIn() { + if(!isset($_COOKIE['steamID']) || !isset($_COOKIE['secret_key'])) { + return false; + } + + $steamID = $_COOKIE['steamID']; + $secret_key = $_COOKIE['secret_key']; + + $admin = new Admin(); + if ($admin->IsLoginValid($steamID, $secret_key, false)) { + return true; + } + + return false; + } + + function EnsureCsrfToken() { + if (session_status() !== PHP_SESSION_ACTIVE) { + session_start(); + } + + if (empty($_SESSION['csrf_token'])) { + $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); + } + + return $_SESSION['csrf_token']; + } + + function ValidateCsrfToken($token) { + if (session_status() !== PHP_SESSION_ACTIVE) { + session_start(); + } + + $token = (string) ($token ?? ''); + + if (empty($_SESSION['csrf_token']) || empty($token)) { + return false; + } + + return hash_equals($_SESSION['csrf_token'], $token); + } + + function formatMethod(int $method) { + $methods = ["client_steamid", "client_name", "client_ip", "admin_name", "admin_steamid", "map", "length"]; + return $methods[$method-1] ?? $methods[0]; + } + + function GetRowInfo($id, $result2 = null) { + $admin = new Admin(); + $kban = new Kban(); + + if ($id != 0) { + $result2 = $kban->getKbanInfoFromID($id); + } else if ($result2 !== null) { + $id = $result2['id']; + } + + if ($result2 === null) { + return; + } + + $clientName = $result2['client_name']; + $clientSteamID = $result2['client_steamid']; + $clientIP = $result2['client_ip']; + $adminSteamID = $result2['admin_steamid']; + $reason = $result2['reason']; + $map = $result2['map']; + $time_stamp_start = strtotime($result2['time_stamp_start']); + $length_minutes = intval($result2['length']); + $time_played_start = intval($result2['time_played_start']); + $isExpired = ($result2['is_expired'] == 1); + $isRemoved = ($result2['is_removed'] == 1); + $adminNameRemoved = $result2['admin_name_removed']; + $time_stamp_removed = $result2['time_stamp_removed']; + $reason_removed = $result2['reason_removed']; + + $adminName = $admin->GetAdminNameFromSteamID($adminSteamID); + + $isPermanent = ($length_minutes == 0); + + if ($isPermanent) { + $length = "Permanent"; + $startedOn = "N/A"; + $expiresOn = "Never"; + } else { + $length = $kban->formatPlaytime($length_minutes); + $startedOn = $kban->formatPlaytime($time_played_start) . " played"; + $expiresOn = $kban->formatPlaytime($time_played_start + $length_minutes) . " played"; + } + + $status = "Kban Active"; + if ($isExpired && !$isRemoved) { + $status = "Kban Expired"; + } + + if ($isRemoved) { + $status = "Kban Removed"; + } + + echo "
"; + + $searchMethod = 1; + if (IsAdminLoggedIn()) { + if ($clientSteamID == "NO STEAMID") { + $href = "ViewPlayerHistory(\"$clientIP\", 3)"; + $searchMethod = 3; + } else { + $href = "ViewPlayerHistory(\"$clientSteamID\", 1);"; + $searchMethod = 1; + } + } else { + if ($clientSteamID != "NO STEAMID") { + $href = "ViewPlayerHistory(\"$clientSteamID\", 1);"; + $searchMethod = 1; + } else { + $searchMethod = 3; + } + } + + if (IsAdminLoggedIn() || ($searchMethod == 1 && !IsAdminLoggedIn())) { + echo ""; + } + + if (IsAdminLoggedIn()) { + $admin->UpdateAdminInfo($_COOKIE['steamID']); + + if ($isRemoved == false && $isExpired == false) { + + if ($admin->DoesHaveFullAccess() || $adminSteamID == $admin->adminSteamID) { + $editFunction = "EditFromID(\"$id\")"; + echo ""; + $unbanFunction = "ConfirmUnban($id, \"$clientName\", \"$clientSteamID\");"; + echo ""; + } + } else { + if ($clientSteamID != "NO STEAMID" && !$kban->IsSteamIDAlreadyBanned($clientSteamID)) { + $reBanFunction = "RebanFromID(\"$id\");"; + echo ""; + } + } + } + + if ($admin->DoesHaveFullAccess()) { + $deleteFunction = "RemoveKbanFromDBCheck($id);"; + echo ""; + } + + if (!IsAdminLoggedIn()) { + $href = "Login();"; + echo ""; + } + + echo "
"; + + $date = new DateTime("now", new DateTimeZone(DATE_TIME_ZONE)); + $date->setTimestamp($time_stamp_start); + $startDate = $date->format(DATE_TIME_FORMAT); + + echo "
    "; + + echo "
  • "; + echo " Player"; + echo "$clientName"; + echo "
  • "; + + $steam = new Steam(); + $clientSteamID3 = $steam->SteamID_To_SteamID3($clientSteamID); + $clientSteamID64 = $steam->SteamID_To_SteamID64($clientSteamID); + echo "
  • "; + echo " Steam ID"; + echo "$clientSteamID"; + echo "
  • "; + + echo "
  • "; + echo " Steam3 ID"; + echo "$clientSteamID3"; + echo "
  • "; + + echo "
  • "; + echo " Steam Community"; + echo "$clientSteamID64"; + echo "
  • "; + + if (IsAdminLoggedIn() && $admin->DoesHaveFullAccess()) { + echo "
  • "; + echo " IP address"; + if ($clientIP == "Unknown" || $clientIP == "unknown") { + echo "$clientIP"; + } else { + echo "$clientIP"; + } + echo "
  • "; + } + + echo "
  • "; + echo " Invoked on"; + echo "$startDate"; + echo "
  • "; + + echo "
  • "; + echo " KBan Duration"; + echo "$length"; + echo "
  • "; + + echo "
  • "; + echo " Started on"; + echo "$startedOn"; + echo "
  • "; + + echo "
  • "; + echo " Expires on"; + echo "$expiresOn"; + echo "
  • "; + + echo "
  • "; + echo " Reason"; + echo "$reason"; + echo "
  • "; + + echo "
  • "; + echo " Banned by Admin"; + echo "$adminName"; + echo "
  • "; + + echo "
  • "; + echo " KBan Status"; + echo "$status"; + echo "
  • "; + + if ($isRemoved) { + $date->setTimestamp($time_stamp_removed); + $removedDate = $date->format(DATE_TIME_FORMAT); + + echo "
  • "; + echo " Unbanned on"; + echo "$removedDate"; + echo "
  • "; + + echo "
  • "; + echo " Unbanned By Admin"; + echo "$adminNameRemoved"; + echo "
  • "; + + echo "
  • "; + echo " Unban Reason"; + echo "$reason_removed"; + echo "
  • "; + } + + echo "
  • "; + echo " Map"; + if ($map != "Web Ban" && $map != "From Web") { + $fastdl = $GLOBALS['SERVER_FASTDL']; + echo "$map"; + } else { + echo "$map"; + } + echo "
  • "; + + echo "
"; + + } + + function GetKbanLengths($addTag = true) { + if($addTag == true) { + echo ""; + } + } + + function GetKbanLengthTypes() { + echo ""; + } +?> diff --git a/functions_url.php b/functions_url.php new file mode 100644 index 0000000..0aaeff6 --- /dev/null +++ b/functions_url.php @@ -0,0 +1,236 @@ +", "<", "&", "%", "|", "^", "~", "(", ")"); + $sanitized = str_replace($replacements, "", $input); + return htmlspecialchars($sanitized, ENT_QUOTES, 'UTF-8'); // Escape HTML entities + } + + if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['id']) && !isset($_GET['reban']) && !isset($_GET['edit'])) { + $id = (int) filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT); + showKbanInfo($id); + } + + if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['oldid']) && !isset($_POST['reban']) && !isset($_POST['edit'])) { + if (!ValidateCsrfToken(filter_input(INPUT_POST, 'csrf_token', FILTER_UNSAFE_RAW))) { + http_response_code(403); + die(); + } + + if (!isset($_COOKIE['steamID'])) { + die(); + } + + $admin = new Admin(); + $admin->UpdateAdminInfo($_COOKIE['steamID']); + + $id = (int) filter_input(INPUT_POST, 'oldid', FILTER_SANITIZE_NUMBER_INT); + + $kban = new Kban(); + $info = $kban->getKbanInfoFromID($id); + if ($info === null || !IsAdminLoggedIn() || (!$admin->DoesHaveFullAccess() && $info['admin_steamid'] != $admin->adminSteamID)) { + die(); + } + + $reason = sanitizeString(filter_input(INPUT_POST, 'reason', FILTER_UNSAFE_RAW)); + + if (!$kban->UnbanByID($id, $reason)) { + die(); + } + + die(); + } + + function showKbanInfo(int $id) { + GetRowInfo($id); + } + + if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add']) && isset($_POST['playerName'])) { + if (!ValidateCsrfToken(filter_input(INPUT_POST, 'csrf_token', FILTER_UNSAFE_RAW))) { + http_response_code(403); + die(); + } + + if (!IsAdminLoggedIn()) { + die(); + } + + $playerName = sanitizeString(filter_input(INPUT_POST, 'playerName', FILTER_UNSAFE_RAW)); + $playerSteamID = sanitizeString(filter_input(INPUT_POST, 'playerSteamID', FILTER_UNSAFE_RAW)); + $length = (int) filter_input(INPUT_POST, 'length', FILTER_SANITIZE_NUMBER_INT); + $reason = sanitizeString(filter_input(INPUT_POST, 'reason', FILTER_UNSAFE_RAW)); + + $icon = " "; + if (empty($playerName)) { + echo "

$icon Player name cannot be empty!

"; + die(); + } + + if (empty($playerSteamID)) { + echo "

$icon Player SteamID cannot be empty!

"; + die(); + } + + if (!preg_match("/^STEAM_[0-5]:[01]:\d+$/", $playerSteamID)) { + echo "

$icon Invalid SteamID Format

"; + die(); + } + + if (empty($reason)) { + echo "

$icon Reason cannot be empty!

"; + die(); + } + + if (str_contains($playerName, "'") || str_contains($playerName, "\"")) { + echo "

$icon ' and \" characters cannot be used for Player Name!

"; + die(); + } + + if (str_contains($reason, "'") || str_contains($reason, "\"")) { + echo "

$icon ' and \" characters cannot be used for Reason!

"; + die(); + } + + $kban = new Kban(); + if ($kban->IsSteamIDAlreadyBanned($playerSteamID)) { + echo "

$icon $playerSteamID is already kbanned!

"; + die(); + } + + $kban->addNewKban($playerName, $playerSteamID, $length, $reason); + } + + if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['edit']) && isset($_POST['playerName'])) { + if (!ValidateCsrfToken(filter_input(INPUT_POST, 'csrf_token', FILTER_UNSAFE_RAW))) { + http_response_code(403); + echo "

Security token expired or invalid. Please refresh the page and try again.

"; + die(); + } + + if (!isset($_COOKIE['steamID'])) { + echo "

You are not logged in. Please log in again.

"; + die(); + } + + $id = (int) filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT); + $playerName = sanitizeString(filter_input(INPUT_POST, 'playerName', FILTER_UNSAFE_RAW)); + $playerSteamID = sanitizeString(filter_input(INPUT_POST, 'playerSteamID', FILTER_UNSAFE_RAW)); + $length = filter_input(INPUT_POST, 'length', FILTER_SANITIZE_NUMBER_INT); + $reason = sanitizeString(filter_input(INPUT_POST, 'reason', FILTER_UNSAFE_RAW)); + + $icon = " "; + if (empty($playerName)) { + echo "

$icon Player name cannot be empty!

"; + die(); + } + + if (empty($playerSteamID)) { + echo "

$icon Player SteamID cannot be empty!

"; + die(); + } + + if (!preg_match("/^STEAM_[0-5]:[01]:\d+$/", $playerSteamID)) { + echo "

$icon Invalid SteamID Format

"; + die(); + } + + if (empty($reason)) { + echo "

$icon Reason cannot be empty!

"; + die(); + } + + if (str_contains($playerName, "'") || str_contains($playerName, "\"")) { + echo "

$icon ' and \" characters cannot be used for Player Name!

"; + die(); + } + + if (str_contains($reason, "'") || str_contains($reason, "\"")) { + echo "

$icon ' and \" characters cannot be used for Reason!

"; + die(); + } + + $admin = new Admin(); + $admin->UpdateAdminInfo($_COOKIE['steamID']); + + if ($length === null && !$admin->DoesHaveFullAccess()) { + echo "

$icon You do not have permission for Permanent bans!

"; + die(); + } + + if (empty($reason)) { + $reason = "NO REASON"; + } + + if ($length === null) { + $length = 0; + } + $length = (int) $length; + + if ($length < 0) { + $length = 30; + } + + $kban = new Kban(); + + $info = $kban->getKbanInfoFromID($id); + + if ($info === null) { + echo "

$icon Kban not found (it may have already been removed or is pending deletion).

"; + die(); + } + + if (!IsAdminLoggedIn()) { + echo "

$icon You are not logged in.

"; + die(); + } + + if (!$admin->DoesHaveFullAccess() && $info['admin_steamid'] != $admin->adminSteamID) { + echo "

$icon You do not have permission to edit a kban issued by another admin.

"; + die(); + } + + if ($playerName == $info['client_name'] && $playerSteamID == $info['client_steamid'] && $reason == $info['reason'] && $length == ($info['length'] * 60)) { + echo "

$icon Cannot detect any changes to edit!

"; + die(); + } + + if (!$kban->IsSteamIDAlreadyBanned($playerSteamID)) { + echo "

$icon The edited steamid is already kbanned and cannot be edited from here

"; + die(); + } + + // Note: there's no longer a way to validate "is this duration already in the + // past" here — expiry is playtime-based and only the sourcemod plugin knows a + // player's current playtime, so that check has been removed rather than guessed at. + $kban->EditKban($id, $playerName, $playerSteamID, $length, $reason); + } + + if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete'])) { + if (!ValidateCsrfToken(filter_input(INPUT_POST, 'csrf_token', FILTER_UNSAFE_RAW))) { + http_response_code(403); + die(); + } + + if (!isset($_COOKIE['steamID'])) { + die(); + } + + $admin = new Admin(); + $admin->UpdateAdminInfo($_COOKIE['steamID']); + if (!IsAdminLoggedIn() || !$admin->DoesHaveFullAccess()) { + die(); + } + + $id = (int) filter_input(INPUT_POST, 'deleteid', FILTER_SANITIZE_NUMBER_INT); + $kban = new Kban(); + if (!$kban->RemoveKbanFromDB($id)) { + http_response_code(400); + echo "Delete failed"; + } + die(); + } +?> diff --git a/header.php b/header.php new file mode 100644 index 0000000..bd36e3d --- /dev/null +++ b/header.php @@ -0,0 +1,177 @@ +UpdateAdminInfo($_COOKIE['steamID']); + $adminName = $admin->adminUser; + + $steam = new Steam(); + $steamID64 = $steam->SteamID_To_SteamID64($GLOBALS['steamID']); + $adminURL = "https://steamcommunity.com/profiles/$steamID64"; + } else { + setcookie("steamID", "", 1, "/", $_SERVER['SERVER_NAME'], true, true); + setcookie("secret_key", "", 1, "/", $_SERVER['SERVER_NAME'], true, true); + setcookie("aid", "", 1, "/", $_SERVER['SERVER_NAME'], true, true); + } + + $csrfToken = EnsureCsrfToken(); +?> + + + KnockBack Bans + + + + + + + + + + + + + + +
+
+

+
+
+
    + +
+
+ +
+
+
+
+

Advanced Search

+

+
+
+ +
+ + +
+
+ + +
+ + +
+
+
+
+
+
+ ' + ?> + + + + + +
+ +
+
+ ' + ?> + logo + +
+
+ + + + +
+
+
+
+
+
+ +
+ + diff --git a/images/banner.png b/images/banner.png new file mode 100755 index 0000000..ceb4fb2 Binary files /dev/null and b/images/banner.png differ diff --git a/images/country/ad.jpg b/images/country/ad.jpg new file mode 100644 index 0000000..5478f59 Binary files /dev/null and b/images/country/ad.jpg differ diff --git a/images/country/ae.jpg b/images/country/ae.jpg new file mode 100644 index 0000000..055d833 Binary files /dev/null and b/images/country/ae.jpg differ diff --git a/images/country/af.jpg b/images/country/af.jpg new file mode 100644 index 0000000..5b84905 Binary files /dev/null and b/images/country/af.jpg differ diff --git a/images/country/ag.jpg b/images/country/ag.jpg new file mode 100644 index 0000000..8da6828 Binary files /dev/null and b/images/country/ag.jpg differ diff --git a/images/country/ai.jpg b/images/country/ai.jpg new file mode 100644 index 0000000..34ff2f3 Binary files /dev/null and b/images/country/ai.jpg differ diff --git a/images/country/al.jpg b/images/country/al.jpg new file mode 100644 index 0000000..f8f5743 Binary files /dev/null and b/images/country/al.jpg differ diff --git a/images/country/am.jpg b/images/country/am.jpg new file mode 100644 index 0000000..576d983 Binary files /dev/null and b/images/country/am.jpg differ diff --git a/images/country/an.jpg b/images/country/an.jpg new file mode 100644 index 0000000..2567e62 Binary files /dev/null and b/images/country/an.jpg differ diff --git a/images/country/ao.jpg b/images/country/ao.jpg new file mode 100644 index 0000000..ef4cec6 Binary files /dev/null and b/images/country/ao.jpg differ diff --git a/images/country/ar.jpg b/images/country/ar.jpg new file mode 100644 index 0000000..45ead78 Binary files /dev/null and b/images/country/ar.jpg differ diff --git a/images/country/as.jpg b/images/country/as.jpg new file mode 100644 index 0000000..e960bb6 Binary files /dev/null and b/images/country/as.jpg differ diff --git a/images/country/at.jpg b/images/country/at.jpg new file mode 100644 index 0000000..eac7d58 Binary files /dev/null and b/images/country/at.jpg differ diff --git a/images/country/au.jpg b/images/country/au.jpg new file mode 100644 index 0000000..595b2b1 Binary files /dev/null and b/images/country/au.jpg differ diff --git a/images/country/aw.jpg b/images/country/aw.jpg new file mode 100644 index 0000000..321883f Binary files /dev/null and b/images/country/aw.jpg differ diff --git a/images/country/ax.jpg b/images/country/ax.jpg new file mode 100644 index 0000000..58be385 Binary files /dev/null and b/images/country/ax.jpg differ diff --git a/images/country/az.jpg b/images/country/az.jpg new file mode 100644 index 0000000..7a791a4 Binary files /dev/null and b/images/country/az.jpg differ diff --git a/images/country/ba.jpg b/images/country/ba.jpg new file mode 100644 index 0000000..797fc18 Binary files /dev/null and b/images/country/ba.jpg differ diff --git a/images/country/bb.jpg b/images/country/bb.jpg new file mode 100644 index 0000000..6b8f247 Binary files /dev/null and b/images/country/bb.jpg differ diff --git a/images/country/bd.jpg b/images/country/bd.jpg new file mode 100644 index 0000000..58561dc Binary files /dev/null and b/images/country/bd.jpg differ diff --git a/images/country/be.jpg b/images/country/be.jpg new file mode 100644 index 0000000..d9db868 Binary files /dev/null and b/images/country/be.jpg differ diff --git a/images/country/bf.jpg b/images/country/bf.jpg new file mode 100644 index 0000000..61cc915 Binary files /dev/null and b/images/country/bf.jpg differ diff --git a/images/country/bg.jpg b/images/country/bg.jpg new file mode 100644 index 0000000..40dc5d5 Binary files /dev/null and b/images/country/bg.jpg differ diff --git a/images/country/bh.jpg b/images/country/bh.jpg new file mode 100644 index 0000000..c335d64 Binary files /dev/null and b/images/country/bh.jpg differ diff --git a/images/country/bi.jpg b/images/country/bi.jpg new file mode 100644 index 0000000..2c8bbfa Binary files /dev/null and b/images/country/bi.jpg differ diff --git a/images/country/bj.jpg b/images/country/bj.jpg new file mode 100644 index 0000000..b25820d Binary files /dev/null and b/images/country/bj.jpg differ diff --git a/images/country/bm.jpg b/images/country/bm.jpg new file mode 100644 index 0000000..5e13db7 Binary files /dev/null and b/images/country/bm.jpg differ diff --git a/images/country/bn.jpg b/images/country/bn.jpg new file mode 100644 index 0000000..c528ed1 Binary files /dev/null and b/images/country/bn.jpg differ diff --git a/images/country/bo.jpg b/images/country/bo.jpg new file mode 100644 index 0000000..6284991 Binary files /dev/null and b/images/country/bo.jpg differ diff --git a/images/country/br.jpg b/images/country/br.jpg new file mode 100644 index 0000000..cfd4f07 Binary files /dev/null and b/images/country/br.jpg differ diff --git a/images/country/bs.jpg b/images/country/bs.jpg new file mode 100644 index 0000000..ed1f105 Binary files /dev/null and b/images/country/bs.jpg differ diff --git a/images/country/bt.jpg b/images/country/bt.jpg new file mode 100644 index 0000000..980bb47 Binary files /dev/null and b/images/country/bt.jpg differ diff --git a/images/country/bv.jpg b/images/country/bv.jpg new file mode 100644 index 0000000..105b23a Binary files /dev/null and b/images/country/bv.jpg differ diff --git a/images/country/bw.jpg b/images/country/bw.jpg new file mode 100644 index 0000000..776b327 Binary files /dev/null and b/images/country/bw.jpg differ diff --git a/images/country/by.jpg b/images/country/by.jpg new file mode 100644 index 0000000..13630ad Binary files /dev/null and b/images/country/by.jpg differ diff --git a/images/country/bz.jpg b/images/country/bz.jpg new file mode 100644 index 0000000..3aef4da Binary files /dev/null and b/images/country/bz.jpg differ diff --git a/images/country/ca.jpg b/images/country/ca.jpg new file mode 100644 index 0000000..bb1fd53 Binary files /dev/null and b/images/country/ca.jpg differ diff --git a/images/country/catalonia.jpg b/images/country/catalonia.jpg new file mode 100644 index 0000000..4f85bbd Binary files /dev/null and b/images/country/catalonia.jpg differ diff --git a/images/country/cc.jpg b/images/country/cc.jpg new file mode 100644 index 0000000..86271f0 Binary files /dev/null and b/images/country/cc.jpg differ diff --git a/images/country/cd.jpg b/images/country/cd.jpg new file mode 100644 index 0000000..549ac98 Binary files /dev/null and b/images/country/cd.jpg differ diff --git a/images/country/cf.jpg b/images/country/cf.jpg new file mode 100644 index 0000000..7b01cb7 Binary files /dev/null and b/images/country/cf.jpg differ diff --git a/images/country/cg.jpg b/images/country/cg.jpg new file mode 100644 index 0000000..ba7e59c Binary files /dev/null and b/images/country/cg.jpg differ diff --git a/images/country/ch.jpg b/images/country/ch.jpg new file mode 100644 index 0000000..57b6c41 Binary files /dev/null and b/images/country/ch.jpg differ diff --git a/images/country/ci.jpg b/images/country/ci.jpg new file mode 100644 index 0000000..50374e9 Binary files /dev/null and b/images/country/ci.jpg differ diff --git a/images/country/ck.jpg b/images/country/ck.jpg new file mode 100644 index 0000000..127ac27 Binary files /dev/null and b/images/country/ck.jpg differ diff --git a/images/country/cl.jpg b/images/country/cl.jpg new file mode 100644 index 0000000..fae3579 Binary files /dev/null and b/images/country/cl.jpg differ diff --git a/images/country/cm.jpg b/images/country/cm.jpg new file mode 100644 index 0000000..a440a76 Binary files /dev/null and b/images/country/cm.jpg differ diff --git a/images/country/cn.jpg b/images/country/cn.jpg new file mode 100644 index 0000000..e3cc2cd Binary files /dev/null and b/images/country/cn.jpg differ diff --git a/images/country/co.jpg b/images/country/co.jpg new file mode 100644 index 0000000..0ac03e1 Binary files /dev/null and b/images/country/co.jpg differ diff --git a/images/country/cr.jpg b/images/country/cr.jpg new file mode 100644 index 0000000..584317d Binary files /dev/null and b/images/country/cr.jpg differ diff --git a/images/country/cs.jpg b/images/country/cs.jpg new file mode 100644 index 0000000..8ee11ff Binary files /dev/null and b/images/country/cs.jpg differ diff --git a/images/country/cu.jpg b/images/country/cu.jpg new file mode 100644 index 0000000..4281352 Binary files /dev/null and b/images/country/cu.jpg differ diff --git a/images/country/cv.jpg b/images/country/cv.jpg new file mode 100644 index 0000000..b44c5ac Binary files /dev/null and b/images/country/cv.jpg differ diff --git a/images/country/cx.jpg b/images/country/cx.jpg new file mode 100644 index 0000000..2832842 Binary files /dev/null and b/images/country/cx.jpg differ diff --git a/images/country/cy.jpg b/images/country/cy.jpg new file mode 100644 index 0000000..e0c07b4 Binary files /dev/null and b/images/country/cy.jpg differ diff --git a/images/country/cz.jpg b/images/country/cz.jpg new file mode 100644 index 0000000..9eca223 Binary files /dev/null and b/images/country/cz.jpg differ diff --git a/images/country/de.jpg b/images/country/de.jpg new file mode 100644 index 0000000..9108ae0 Binary files /dev/null and b/images/country/de.jpg differ diff --git a/images/country/dj.jpg b/images/country/dj.jpg new file mode 100644 index 0000000..3d2d8a8 Binary files /dev/null and b/images/country/dj.jpg differ diff --git a/images/country/dk.jpg b/images/country/dk.jpg new file mode 100644 index 0000000..42d38b6 Binary files /dev/null and b/images/country/dk.jpg differ diff --git a/images/country/dm.jpg b/images/country/dm.jpg new file mode 100644 index 0000000..a100fd5 Binary files /dev/null and b/images/country/dm.jpg differ diff --git a/images/country/do.jpg b/images/country/do.jpg new file mode 100644 index 0000000..4f44e55 Binary files /dev/null and b/images/country/do.jpg differ diff --git a/images/country/dz.jpg b/images/country/dz.jpg new file mode 100644 index 0000000..80d8b1a Binary files /dev/null and b/images/country/dz.jpg differ diff --git a/images/country/ec.jpg b/images/country/ec.jpg new file mode 100644 index 0000000..110ec06 Binary files /dev/null and b/images/country/ec.jpg differ diff --git a/images/country/ee.jpg b/images/country/ee.jpg new file mode 100644 index 0000000..a88ecb2 Binary files /dev/null and b/images/country/ee.jpg differ diff --git a/images/country/eg.jpg b/images/country/eg.jpg new file mode 100644 index 0000000..3374af0 Binary files /dev/null and b/images/country/eg.jpg differ diff --git a/images/country/eh.jpg b/images/country/eh.jpg new file mode 100644 index 0000000..3c5a79d Binary files /dev/null and b/images/country/eh.jpg differ diff --git a/images/country/england.jpg b/images/country/england.jpg new file mode 100644 index 0000000..3927c45 Binary files /dev/null and b/images/country/england.jpg differ diff --git a/images/country/er.jpg b/images/country/er.jpg new file mode 100644 index 0000000..cc56d6f Binary files /dev/null and b/images/country/er.jpg differ diff --git a/images/country/es.jpg b/images/country/es.jpg new file mode 100644 index 0000000..d5d6e3a Binary files /dev/null and b/images/country/es.jpg differ diff --git a/images/country/et.jpg b/images/country/et.jpg new file mode 100644 index 0000000..0233ad8 Binary files /dev/null and b/images/country/et.jpg differ diff --git a/images/country/europeanunion.jpg b/images/country/europeanunion.jpg new file mode 100644 index 0000000..78dea4c Binary files /dev/null and b/images/country/europeanunion.jpg differ diff --git a/images/country/fam.jpg b/images/country/fam.jpg new file mode 100644 index 0000000..0a39a8c Binary files /dev/null and b/images/country/fam.jpg differ diff --git a/images/country/fi.jpg b/images/country/fi.jpg new file mode 100644 index 0000000..ea41b9d Binary files /dev/null and b/images/country/fi.jpg differ diff --git a/images/country/fj.jpg b/images/country/fj.jpg new file mode 100644 index 0000000..9058a1c Binary files /dev/null and b/images/country/fj.jpg differ diff --git a/images/country/fk.jpg b/images/country/fk.jpg new file mode 100644 index 0000000..b79e3ea Binary files /dev/null and b/images/country/fk.jpg differ diff --git a/images/country/fm.jpg b/images/country/fm.jpg new file mode 100644 index 0000000..fa9598a Binary files /dev/null and b/images/country/fm.jpg differ diff --git a/images/country/fo.jpg b/images/country/fo.jpg new file mode 100644 index 0000000..0ffbb9f Binary files /dev/null and b/images/country/fo.jpg differ diff --git a/images/country/fr.jpg b/images/country/fr.jpg new file mode 100644 index 0000000..678a17a Binary files /dev/null and b/images/country/fr.jpg differ diff --git a/images/country/ga.jpg b/images/country/ga.jpg new file mode 100644 index 0000000..2717546 Binary files /dev/null and b/images/country/ga.jpg differ diff --git a/images/country/gb.jpg b/images/country/gb.jpg new file mode 100644 index 0000000..3ba8018 Binary files /dev/null and b/images/country/gb.jpg differ diff --git a/images/country/gd.jpg b/images/country/gd.jpg new file mode 100644 index 0000000..e0a7030 Binary files /dev/null and b/images/country/gd.jpg differ diff --git a/images/country/ge.jpg b/images/country/ge.jpg new file mode 100644 index 0000000..d59b632 Binary files /dev/null and b/images/country/ge.jpg differ diff --git a/images/country/gf.jpg b/images/country/gf.jpg new file mode 100644 index 0000000..678a17a Binary files /dev/null and b/images/country/gf.jpg differ diff --git a/images/country/gh.jpg b/images/country/gh.jpg new file mode 100644 index 0000000..883c2a5 Binary files /dev/null and b/images/country/gh.jpg differ diff --git a/images/country/gi.jpg b/images/country/gi.jpg new file mode 100644 index 0000000..f0eb8e9 Binary files /dev/null and b/images/country/gi.jpg differ diff --git a/images/country/gl.jpg b/images/country/gl.jpg new file mode 100644 index 0000000..f8f7d3d Binary files /dev/null and b/images/country/gl.jpg differ diff --git a/images/country/gm.jpg b/images/country/gm.jpg new file mode 100644 index 0000000..265510b Binary files /dev/null and b/images/country/gm.jpg differ diff --git a/images/country/gn.jpg b/images/country/gn.jpg new file mode 100644 index 0000000..d6ff40a Binary files /dev/null and b/images/country/gn.jpg differ diff --git a/images/country/gp.jpg b/images/country/gp.jpg new file mode 100644 index 0000000..3572154 Binary files /dev/null and b/images/country/gp.jpg differ diff --git a/images/country/gq.jpg b/images/country/gq.jpg new file mode 100644 index 0000000..ba42ceb Binary files /dev/null and b/images/country/gq.jpg differ diff --git a/images/country/gr.jpg b/images/country/gr.jpg new file mode 100644 index 0000000..8163bf0 Binary files /dev/null and b/images/country/gr.jpg differ diff --git a/images/country/gs.jpg b/images/country/gs.jpg new file mode 100644 index 0000000..cc2ac21 Binary files /dev/null and b/images/country/gs.jpg differ diff --git a/images/country/gt.jpg b/images/country/gt.jpg new file mode 100644 index 0000000..d61d45b Binary files /dev/null and b/images/country/gt.jpg differ diff --git a/images/country/gu.jpg b/images/country/gu.jpg new file mode 100644 index 0000000..9b04d91 Binary files /dev/null and b/images/country/gu.jpg differ diff --git a/images/country/gw.jpg b/images/country/gw.jpg new file mode 100644 index 0000000..752fcb7 Binary files /dev/null and b/images/country/gw.jpg differ diff --git a/images/country/gy.jpg b/images/country/gy.jpg new file mode 100644 index 0000000..3742a85 Binary files /dev/null and b/images/country/gy.jpg differ diff --git a/images/country/hk.jpg b/images/country/hk.jpg new file mode 100644 index 0000000..bc1aa67 Binary files /dev/null and b/images/country/hk.jpg differ diff --git a/images/country/hm.jpg b/images/country/hm.jpg new file mode 100644 index 0000000..595b2b1 Binary files /dev/null and b/images/country/hm.jpg differ diff --git a/images/country/hn.jpg b/images/country/hn.jpg new file mode 100644 index 0000000..56ca86b Binary files /dev/null and b/images/country/hn.jpg differ diff --git a/images/country/hr.jpg b/images/country/hr.jpg new file mode 100644 index 0000000..6803a7d Binary files /dev/null and b/images/country/hr.jpg differ diff --git a/images/country/ht.jpg b/images/country/ht.jpg new file mode 100644 index 0000000..d85b210 Binary files /dev/null and b/images/country/ht.jpg differ diff --git a/images/country/hu.jpg b/images/country/hu.jpg new file mode 100644 index 0000000..75e54d9 Binary files /dev/null and b/images/country/hu.jpg differ diff --git a/images/country/id.jpg b/images/country/id.jpg new file mode 100644 index 0000000..d2895b7 Binary files /dev/null and b/images/country/id.jpg differ diff --git a/images/country/ie.jpg b/images/country/ie.jpg new file mode 100644 index 0000000..0992bb9 Binary files /dev/null and b/images/country/ie.jpg differ diff --git a/images/country/il.jpg b/images/country/il.jpg new file mode 100644 index 0000000..815ebd8 Binary files /dev/null and b/images/country/il.jpg differ diff --git a/images/country/in.jpg b/images/country/in.jpg new file mode 100644 index 0000000..7e76490 Binary files /dev/null and b/images/country/in.jpg differ diff --git a/images/country/io.jpg b/images/country/io.jpg new file mode 100644 index 0000000..1ca94ef Binary files /dev/null and b/images/country/io.jpg differ diff --git a/images/country/iq.jpg b/images/country/iq.jpg new file mode 100644 index 0000000..ede5b83 Binary files /dev/null and b/images/country/iq.jpg differ diff --git a/images/country/ir.jpg b/images/country/ir.jpg new file mode 100644 index 0000000..875a198 Binary files /dev/null and b/images/country/ir.jpg differ diff --git a/images/country/is.jpg b/images/country/is.jpg new file mode 100644 index 0000000..e9c1def Binary files /dev/null and b/images/country/is.jpg differ diff --git a/images/country/it.jpg b/images/country/it.jpg new file mode 100644 index 0000000..eebbf56 Binary files /dev/null and b/images/country/it.jpg differ diff --git a/images/country/jm.jpg b/images/country/jm.jpg new file mode 100644 index 0000000..b5026cf Binary files /dev/null and b/images/country/jm.jpg differ diff --git a/images/country/jo.jpg b/images/country/jo.jpg new file mode 100644 index 0000000..eb28334 Binary files /dev/null and b/images/country/jo.jpg differ diff --git a/images/country/jp.jpg b/images/country/jp.jpg new file mode 100644 index 0000000..efc12b5 Binary files /dev/null and b/images/country/jp.jpg differ diff --git a/images/country/ke.jpg b/images/country/ke.jpg new file mode 100644 index 0000000..7449c72 Binary files /dev/null and b/images/country/ke.jpg differ diff --git a/images/country/kg.jpg b/images/country/kg.jpg new file mode 100644 index 0000000..91f6e68 Binary files /dev/null and b/images/country/kg.jpg differ diff --git a/images/country/kh.jpg b/images/country/kh.jpg new file mode 100644 index 0000000..482c2ce Binary files /dev/null and b/images/country/kh.jpg differ diff --git a/images/country/ki.jpg b/images/country/ki.jpg new file mode 100644 index 0000000..ce81b87 Binary files /dev/null and b/images/country/ki.jpg differ diff --git a/images/country/km.jpg b/images/country/km.jpg new file mode 100644 index 0000000..7d75778 Binary files /dev/null and b/images/country/km.jpg differ diff --git a/images/country/kn.jpg b/images/country/kn.jpg new file mode 100644 index 0000000..2ced709 Binary files /dev/null and b/images/country/kn.jpg differ diff --git a/images/country/kp.jpg b/images/country/kp.jpg new file mode 100644 index 0000000..55c5949 Binary files /dev/null and b/images/country/kp.jpg differ diff --git a/images/country/kr.jpg b/images/country/kr.jpg new file mode 100644 index 0000000..8be057f Binary files /dev/null and b/images/country/kr.jpg differ diff --git a/images/country/kw.jpg b/images/country/kw.jpg new file mode 100644 index 0000000..132b282 Binary files /dev/null and b/images/country/kw.jpg differ diff --git a/images/country/ky.jpg b/images/country/ky.jpg new file mode 100644 index 0000000..60a34dc Binary files /dev/null and b/images/country/ky.jpg differ diff --git a/images/country/kz.jpg b/images/country/kz.jpg new file mode 100644 index 0000000..70613ea Binary files /dev/null and b/images/country/kz.jpg differ diff --git a/images/country/la.jpg b/images/country/la.jpg new file mode 100644 index 0000000..0388388 Binary files /dev/null and b/images/country/la.jpg differ diff --git a/images/country/lb.jpg b/images/country/lb.jpg new file mode 100644 index 0000000..9cdc599 Binary files /dev/null and b/images/country/lb.jpg differ diff --git a/images/country/lc.jpg b/images/country/lc.jpg new file mode 100644 index 0000000..3be108a Binary files /dev/null and b/images/country/lc.jpg differ diff --git a/images/country/li.jpg b/images/country/li.jpg new file mode 100644 index 0000000..a42c85c Binary files /dev/null and b/images/country/li.jpg differ diff --git a/images/country/lk.jpg b/images/country/lk.jpg new file mode 100644 index 0000000..0948662 Binary files /dev/null and b/images/country/lk.jpg differ diff --git a/images/country/lr.jpg b/images/country/lr.jpg new file mode 100644 index 0000000..75674a6 Binary files /dev/null and b/images/country/lr.jpg differ diff --git a/images/country/ls.jpg b/images/country/ls.jpg new file mode 100644 index 0000000..e529a71 Binary files /dev/null and b/images/country/ls.jpg differ diff --git a/images/country/lt.jpg b/images/country/lt.jpg new file mode 100644 index 0000000..4b77a04 Binary files /dev/null and b/images/country/lt.jpg differ diff --git a/images/country/lu.jpg b/images/country/lu.jpg new file mode 100644 index 0000000..10e54cc Binary files /dev/null and b/images/country/lu.jpg differ diff --git a/images/country/lv.jpg b/images/country/lv.jpg new file mode 100644 index 0000000..a786190 Binary files /dev/null and b/images/country/lv.jpg differ diff --git a/images/country/ly.jpg b/images/country/ly.jpg new file mode 100644 index 0000000..9352195 Binary files /dev/null and b/images/country/ly.jpg differ diff --git a/images/country/ma.jpg b/images/country/ma.jpg new file mode 100644 index 0000000..a19bb66 Binary files /dev/null and b/images/country/ma.jpg differ diff --git a/images/country/mc.jpg b/images/country/mc.jpg new file mode 100644 index 0000000..6409ecd Binary files /dev/null and b/images/country/mc.jpg differ diff --git a/images/country/md.jpg b/images/country/md.jpg new file mode 100644 index 0000000..0b72c33 Binary files /dev/null and b/images/country/md.jpg differ diff --git a/images/country/me.jpg b/images/country/me.jpg new file mode 100644 index 0000000..fbaf883 Binary files /dev/null and b/images/country/me.jpg differ diff --git a/images/country/mg.jpg b/images/country/mg.jpg new file mode 100644 index 0000000..29440a2 Binary files /dev/null and b/images/country/mg.jpg differ diff --git a/images/country/mh.jpg b/images/country/mh.jpg new file mode 100644 index 0000000..9c973f5 Binary files /dev/null and b/images/country/mh.jpg differ diff --git a/images/country/mk.jpg b/images/country/mk.jpg new file mode 100644 index 0000000..e276257 Binary files /dev/null and b/images/country/mk.jpg differ diff --git a/images/country/ml.jpg b/images/country/ml.jpg new file mode 100644 index 0000000..1e4161c Binary files /dev/null and b/images/country/ml.jpg differ diff --git a/images/country/mm.jpg b/images/country/mm.jpg new file mode 100644 index 0000000..88c5757 Binary files /dev/null and b/images/country/mm.jpg differ diff --git a/images/country/mn.jpg b/images/country/mn.jpg new file mode 100644 index 0000000..dc801f3 Binary files /dev/null and b/images/country/mn.jpg differ diff --git a/images/country/mo.jpg b/images/country/mo.jpg new file mode 100644 index 0000000..d4d5cc4 Binary files /dev/null and b/images/country/mo.jpg differ diff --git a/images/country/mp.jpg b/images/country/mp.jpg new file mode 100644 index 0000000..df66f5b Binary files /dev/null and b/images/country/mp.jpg differ diff --git a/images/country/mq.jpg b/images/country/mq.jpg new file mode 100644 index 0000000..aa22d73 Binary files /dev/null and b/images/country/mq.jpg differ diff --git a/images/country/mr.jpg b/images/country/mr.jpg new file mode 100644 index 0000000..06b32e4 Binary files /dev/null and b/images/country/mr.jpg differ diff --git a/images/country/ms.jpg b/images/country/ms.jpg new file mode 100644 index 0000000..efb4e89 Binary files /dev/null and b/images/country/ms.jpg differ diff --git a/images/country/mt.jpg b/images/country/mt.jpg new file mode 100644 index 0000000..ebb0ec7 Binary files /dev/null and b/images/country/mt.jpg differ diff --git a/images/country/mu.jpg b/images/country/mu.jpg new file mode 100644 index 0000000..fcbf8a0 Binary files /dev/null and b/images/country/mu.jpg differ diff --git a/images/country/mv.jpg b/images/country/mv.jpg new file mode 100644 index 0000000..68f6751 Binary files /dev/null and b/images/country/mv.jpg differ diff --git a/images/country/mw.jpg b/images/country/mw.jpg new file mode 100644 index 0000000..297ef1f Binary files /dev/null and b/images/country/mw.jpg differ diff --git a/images/country/mx.jpg b/images/country/mx.jpg new file mode 100644 index 0000000..4b3e609 Binary files /dev/null and b/images/country/mx.jpg differ diff --git a/images/country/my.jpg b/images/country/my.jpg new file mode 100644 index 0000000..a8513b5 Binary files /dev/null and b/images/country/my.jpg differ diff --git a/images/country/mz.jpg b/images/country/mz.jpg new file mode 100644 index 0000000..2c12ee0 Binary files /dev/null and b/images/country/mz.jpg differ diff --git a/images/country/na.jpg b/images/country/na.jpg new file mode 100644 index 0000000..c90f978 Binary files /dev/null and b/images/country/na.jpg differ diff --git a/images/country/nc.jpg b/images/country/nc.jpg new file mode 100644 index 0000000..2916aba Binary files /dev/null and b/images/country/nc.jpg differ diff --git a/images/country/ne.jpg b/images/country/ne.jpg new file mode 100644 index 0000000..1ab4e6b Binary files /dev/null and b/images/country/ne.jpg differ diff --git a/images/country/nf.jpg b/images/country/nf.jpg new file mode 100644 index 0000000..b745249 Binary files /dev/null and b/images/country/nf.jpg differ diff --git a/images/country/ng.jpg b/images/country/ng.jpg new file mode 100644 index 0000000..a2724a4 Binary files /dev/null and b/images/country/ng.jpg differ diff --git a/images/country/ni.jpg b/images/country/ni.jpg new file mode 100644 index 0000000..1c0d75e Binary files /dev/null and b/images/country/ni.jpg differ diff --git a/images/country/nl.jpg b/images/country/nl.jpg new file mode 100644 index 0000000..4df2853 Binary files /dev/null and b/images/country/nl.jpg differ diff --git a/images/country/no.jpg b/images/country/no.jpg new file mode 100644 index 0000000..105b23a Binary files /dev/null and b/images/country/no.jpg differ diff --git a/images/country/np.jpg b/images/country/np.jpg new file mode 100644 index 0000000..8874396 Binary files /dev/null and b/images/country/np.jpg differ diff --git a/images/country/nr.jpg b/images/country/nr.jpg new file mode 100644 index 0000000..593f6b8 Binary files /dev/null and b/images/country/nr.jpg differ diff --git a/images/country/nu.jpg b/images/country/nu.jpg new file mode 100644 index 0000000..cd40245 Binary files /dev/null and b/images/country/nu.jpg differ diff --git a/images/country/nz.jpg b/images/country/nz.jpg new file mode 100644 index 0000000..3d3d827 Binary files /dev/null and b/images/country/nz.jpg differ diff --git a/images/country/om.jpg b/images/country/om.jpg new file mode 100644 index 0000000..d745eb3 Binary files /dev/null and b/images/country/om.jpg differ diff --git a/images/country/pa.jpg b/images/country/pa.jpg new file mode 100644 index 0000000..087ba36 Binary files /dev/null and b/images/country/pa.jpg differ diff --git a/images/country/pe.jpg b/images/country/pe.jpg new file mode 100644 index 0000000..f9f1aa9 Binary files /dev/null and b/images/country/pe.jpg differ diff --git a/images/country/pf.jpg b/images/country/pf.jpg new file mode 100644 index 0000000..f8b5233 Binary files /dev/null and b/images/country/pf.jpg differ diff --git a/images/country/pg.jpg b/images/country/pg.jpg new file mode 100644 index 0000000..9dc2d40 Binary files /dev/null and b/images/country/pg.jpg differ diff --git a/images/country/ph.jpg b/images/country/ph.jpg new file mode 100644 index 0000000..3c0f427 Binary files /dev/null and b/images/country/ph.jpg differ diff --git a/images/country/pk.jpg b/images/country/pk.jpg new file mode 100644 index 0000000..ed1c51d Binary files /dev/null and b/images/country/pk.jpg differ diff --git a/images/country/pl.jpg b/images/country/pl.jpg new file mode 100644 index 0000000..c07e33c Binary files /dev/null and b/images/country/pl.jpg differ diff --git a/images/country/pm.jpg b/images/country/pm.jpg new file mode 100644 index 0000000..caa7703 Binary files /dev/null and b/images/country/pm.jpg differ diff --git a/images/country/pn.jpg b/images/country/pn.jpg new file mode 100644 index 0000000..50f8e25 Binary files /dev/null and b/images/country/pn.jpg differ diff --git a/images/country/pr.jpg b/images/country/pr.jpg new file mode 100644 index 0000000..d55e41e Binary files /dev/null and b/images/country/pr.jpg differ diff --git a/images/country/ps.jpg b/images/country/ps.jpg new file mode 100644 index 0000000..13cf504 Binary files /dev/null and b/images/country/ps.jpg differ diff --git a/images/country/pt.jpg b/images/country/pt.jpg new file mode 100644 index 0000000..69ef123 Binary files /dev/null and b/images/country/pt.jpg differ diff --git a/images/country/pw.jpg b/images/country/pw.jpg new file mode 100644 index 0000000..e8c5857 Binary files /dev/null and b/images/country/pw.jpg differ diff --git a/images/country/py.jpg b/images/country/py.jpg new file mode 100644 index 0000000..098f563 Binary files /dev/null and b/images/country/py.jpg differ diff --git a/images/country/qa.jpg b/images/country/qa.jpg new file mode 100644 index 0000000..83b5984 Binary files /dev/null and b/images/country/qa.jpg differ diff --git a/images/country/re.jpg b/images/country/re.jpg new file mode 100644 index 0000000..678a17a Binary files /dev/null and b/images/country/re.jpg differ diff --git a/images/country/ro.jpg b/images/country/ro.jpg new file mode 100644 index 0000000..bedfbeb Binary files /dev/null and b/images/country/ro.jpg differ diff --git a/images/country/rs.jpg b/images/country/rs.jpg new file mode 100644 index 0000000..9391d71 Binary files /dev/null and b/images/country/rs.jpg differ diff --git a/images/country/ru.jpg b/images/country/ru.jpg new file mode 100644 index 0000000..3c228e1 Binary files /dev/null and b/images/country/ru.jpg differ diff --git a/images/country/rw.jpg b/images/country/rw.jpg new file mode 100644 index 0000000..d62c9b2 Binary files /dev/null and b/images/country/rw.jpg differ diff --git a/images/country/sa.jpg b/images/country/sa.jpg new file mode 100644 index 0000000..c582d76 Binary files /dev/null and b/images/country/sa.jpg differ diff --git a/images/country/sb.jpg b/images/country/sb.jpg new file mode 100644 index 0000000..9789f7b Binary files /dev/null and b/images/country/sb.jpg differ diff --git a/images/country/sc.jpg b/images/country/sc.jpg new file mode 100644 index 0000000..4961f00 Binary files /dev/null and b/images/country/sc.jpg differ diff --git a/images/country/scotland.jpg b/images/country/scotland.jpg new file mode 100644 index 0000000..35f55d2 Binary files /dev/null and b/images/country/scotland.jpg differ diff --git a/images/country/sd.jpg b/images/country/sd.jpg new file mode 100644 index 0000000..69ba399 Binary files /dev/null and b/images/country/sd.jpg differ diff --git a/images/country/se.jpg b/images/country/se.jpg new file mode 100644 index 0000000..d5861cc Binary files /dev/null and b/images/country/se.jpg differ diff --git a/images/country/sg.jpg b/images/country/sg.jpg new file mode 100644 index 0000000..bb5846e Binary files /dev/null and b/images/country/sg.jpg differ diff --git a/images/country/sh.jpg b/images/country/sh.jpg new file mode 100644 index 0000000..b136821 Binary files /dev/null and b/images/country/sh.jpg differ diff --git a/images/country/si.jpg b/images/country/si.jpg new file mode 100644 index 0000000..3a3e8d5 Binary files /dev/null and b/images/country/si.jpg differ diff --git a/images/country/sj.jpg b/images/country/sj.jpg new file mode 100644 index 0000000..105b23a Binary files /dev/null and b/images/country/sj.jpg differ diff --git a/images/country/sk.jpg b/images/country/sk.jpg new file mode 100644 index 0000000..e294871 Binary files /dev/null and b/images/country/sk.jpg differ diff --git a/images/country/sl.jpg b/images/country/sl.jpg new file mode 100644 index 0000000..26748ff Binary files /dev/null and b/images/country/sl.jpg differ diff --git a/images/country/sm.jpg b/images/country/sm.jpg new file mode 100644 index 0000000..fb9bffe Binary files /dev/null and b/images/country/sm.jpg differ diff --git a/images/country/sn.jpg b/images/country/sn.jpg new file mode 100644 index 0000000..debee73 Binary files /dev/null and b/images/country/sn.jpg differ diff --git a/images/country/so.jpg b/images/country/so.jpg new file mode 100644 index 0000000..93dd4c9 Binary files /dev/null and b/images/country/so.jpg differ diff --git a/images/country/sr.jpg b/images/country/sr.jpg new file mode 100644 index 0000000..b17af05 Binary files /dev/null and b/images/country/sr.jpg differ diff --git a/images/country/st.jpg b/images/country/st.jpg new file mode 100644 index 0000000..2dddf5b Binary files /dev/null and b/images/country/st.jpg differ diff --git a/images/country/sv.jpg b/images/country/sv.jpg new file mode 100644 index 0000000..27eff99 Binary files /dev/null and b/images/country/sv.jpg differ diff --git a/images/country/sy.jpg b/images/country/sy.jpg new file mode 100644 index 0000000..b07618f Binary files /dev/null and b/images/country/sy.jpg differ diff --git a/images/country/sz.jpg b/images/country/sz.jpg new file mode 100644 index 0000000..373009d Binary files /dev/null and b/images/country/sz.jpg differ diff --git a/images/country/tc.jpg b/images/country/tc.jpg new file mode 100644 index 0000000..eab4739 Binary files /dev/null and b/images/country/tc.jpg differ diff --git a/images/country/td.jpg b/images/country/td.jpg new file mode 100644 index 0000000..10bdc0d Binary files /dev/null and b/images/country/td.jpg differ diff --git a/images/country/tf.jpg b/images/country/tf.jpg new file mode 100644 index 0000000..e5177ce Binary files /dev/null and b/images/country/tf.jpg differ diff --git a/images/country/tg.jpg b/images/country/tg.jpg new file mode 100644 index 0000000..f3280f4 Binary files /dev/null and b/images/country/tg.jpg differ diff --git a/images/country/th.jpg b/images/country/th.jpg new file mode 100644 index 0000000..42a4202 Binary files /dev/null and b/images/country/th.jpg differ diff --git a/images/country/tj.jpg b/images/country/tj.jpg new file mode 100644 index 0000000..17d091d Binary files /dev/null and b/images/country/tj.jpg differ diff --git a/images/country/tk.jpg b/images/country/tk.jpg new file mode 100644 index 0000000..945cf73 Binary files /dev/null and b/images/country/tk.jpg differ diff --git a/images/country/tl.jpg b/images/country/tl.jpg new file mode 100644 index 0000000..a980f8a Binary files /dev/null and b/images/country/tl.jpg differ diff --git a/images/country/tm.jpg b/images/country/tm.jpg new file mode 100644 index 0000000..8fd8480 Binary files /dev/null and b/images/country/tm.jpg differ diff --git a/images/country/tn.jpg b/images/country/tn.jpg new file mode 100644 index 0000000..fe8679d Binary files /dev/null and b/images/country/tn.jpg differ diff --git a/images/country/to.jpg b/images/country/to.jpg new file mode 100644 index 0000000..d5fe182 Binary files /dev/null and b/images/country/to.jpg differ diff --git a/images/country/tr.jpg b/images/country/tr.jpg new file mode 100644 index 0000000..dcda21e Binary files /dev/null and b/images/country/tr.jpg differ diff --git a/images/country/tt.jpg b/images/country/tt.jpg new file mode 100644 index 0000000..f6eba6d Binary files /dev/null and b/images/country/tt.jpg differ diff --git a/images/country/tv.jpg b/images/country/tv.jpg new file mode 100644 index 0000000..24d2f7f Binary files /dev/null and b/images/country/tv.jpg differ diff --git a/images/country/tw.jpg b/images/country/tw.jpg new file mode 100644 index 0000000..83e9be2 Binary files /dev/null and b/images/country/tw.jpg differ diff --git a/images/country/tz.jpg b/images/country/tz.jpg new file mode 100644 index 0000000..f58c8a4 Binary files /dev/null and b/images/country/tz.jpg differ diff --git a/images/country/ua.jpg b/images/country/ua.jpg new file mode 100644 index 0000000..092a7fd Binary files /dev/null and b/images/country/ua.jpg differ diff --git a/images/country/ug.jpg b/images/country/ug.jpg new file mode 100644 index 0000000..1214af6 Binary files /dev/null and b/images/country/ug.jpg differ diff --git a/images/country/um.jpg b/images/country/um.jpg new file mode 100644 index 0000000..04b15ae Binary files /dev/null and b/images/country/um.jpg differ diff --git a/images/country/us.jpg b/images/country/us.jpg new file mode 100644 index 0000000..e23d0fb Binary files /dev/null and b/images/country/us.jpg differ diff --git a/images/country/uy.jpg b/images/country/uy.jpg new file mode 100644 index 0000000..21026a6 Binary files /dev/null and b/images/country/uy.jpg differ diff --git a/images/country/uz.jpg b/images/country/uz.jpg new file mode 100644 index 0000000..b15d735 Binary files /dev/null and b/images/country/uz.jpg differ diff --git a/images/country/va.jpg b/images/country/va.jpg new file mode 100644 index 0000000..3c58bef Binary files /dev/null and b/images/country/va.jpg differ diff --git a/images/country/vc.jpg b/images/country/vc.jpg new file mode 100644 index 0000000..131da6e Binary files /dev/null and b/images/country/vc.jpg differ diff --git a/images/country/ve.jpg b/images/country/ve.jpg new file mode 100644 index 0000000..9d9d8fd Binary files /dev/null and b/images/country/ve.jpg differ diff --git a/images/country/vg.jpg b/images/country/vg.jpg new file mode 100644 index 0000000..ff6093b Binary files /dev/null and b/images/country/vg.jpg differ diff --git a/images/country/vi.jpg b/images/country/vi.jpg new file mode 100644 index 0000000..0735909 Binary files /dev/null and b/images/country/vi.jpg differ diff --git a/images/country/vn.jpg b/images/country/vn.jpg new file mode 100644 index 0000000..26527b8 Binary files /dev/null and b/images/country/vn.jpg differ diff --git a/images/country/vu.jpg b/images/country/vu.jpg new file mode 100644 index 0000000..f3143bc Binary files /dev/null and b/images/country/vu.jpg differ diff --git a/images/country/wales.jpg b/images/country/wales.jpg new file mode 100644 index 0000000..b1eb814 Binary files /dev/null and b/images/country/wales.jpg differ diff --git a/images/country/wf.jpg b/images/country/wf.jpg new file mode 100644 index 0000000..731872a Binary files /dev/null and b/images/country/wf.jpg differ diff --git a/images/country/ws.jpg b/images/country/ws.jpg new file mode 100644 index 0000000..651ae71 Binary files /dev/null and b/images/country/ws.jpg differ diff --git a/images/country/ye.jpg b/images/country/ye.jpg new file mode 100644 index 0000000..57bbbc5 Binary files /dev/null and b/images/country/ye.jpg differ diff --git a/images/country/yt.jpg b/images/country/yt.jpg new file mode 100644 index 0000000..19f0aec Binary files /dev/null and b/images/country/yt.jpg differ diff --git a/images/country/za.jpg b/images/country/za.jpg new file mode 100644 index 0000000..15d81b4 Binary files /dev/null and b/images/country/za.jpg differ diff --git a/images/country/zm.jpg b/images/country/zm.jpg new file mode 100644 index 0000000..8f7fe3d Binary files /dev/null and b/images/country/zm.jpg differ diff --git a/images/country/zw.jpg b/images/country/zw.jpg new file mode 100644 index 0000000..527eb4b Binary files /dev/null and b/images/country/zw.jpg differ diff --git a/images/country/zz.jpg b/images/country/zz.jpg new file mode 100644 index 0000000..22b18ba Binary files /dev/null and b/images/country/zz.jpg differ diff --git a/images/favicon.ico b/images/favicon.ico new file mode 100644 index 0000000..e730e3f Binary files /dev/null and b/images/favicon.ico differ diff --git a/images/games/csource.png b/images/games/csource.png new file mode 100644 index 0000000..010f7a6 Binary files /dev/null and b/images/games/csource.png differ diff --git a/index.php b/index.php new file mode 100644 index 0000000..2cf58c6 --- /dev/null +++ b/index.php @@ -0,0 +1,315 @@ +window.location.replace('index.php?all');"; + die(); + } + + if(isset($_GET['page'])) { + $currentPage = max(1, (int) $_GET['page']); + } else { + $currentPage = 1; + } + + $resultsPerPage = 20; + $resultsStart = (($currentPage - 1) * $resultsPerPage); + + $sql = "SELECT * FROM `KbRestrict_CurrentBans` WHERE `web_ban_delete`=0"; + $pageType = "all"; + if(isset($_GET['active'])) { + $sql .= " AND `is_removed`=0 AND `is_expired`=0"; + $pageType = "active"; + } else if(isset($_GET['expired'])) { + $sql .= " AND `is_expired`=1"; + $pageType = "expired"; + } + + if(isset($_GET['m']) && (isset($_GET['s']) || isset($_GET['length']))) { + $input = isset($_GET['s']) ? trim($_GET['s']) : ""; + $queryComplete = ""; + $method = formatMethod(intval($_GET['m'])); + + if($method == "client_steamid" || $method == "admin_steamid") { + $steam = new Steam(); + $result = $steam->verifyAndConvertSteamID(str_replace(" ", "", $input)); + + if ($result['success']) { + $convertedSteamID = $result['steamID2']; + if(!empty($convertedSteamID)) { + $input = $convertedSteamID; + } + } else { + error_log("Error converting SteamID: " . $result['error']); + } + } else if ($method == "length" && isset($_GET['length'])) { + $lengthArray = is_array($_GET['length']) ? $_GET['length'] : []; + $lengthOperatorVal = intval($lengthArray[0] ?? 1); // like greater or less or shit like this + $lengthOperator = "="; + + if($lengthOperatorVal == 2) {$lengthOperator = ">";} + if($lengthOperatorVal == 3) {$lengthOperator = "<";} + if($lengthOperatorVal == 4) {$lengthOperator = ">=";} + if($lengthOperatorVal == 5) {$lengthOperator = "<=";} + + $length; + $lengthValue = intval($lengthArray[1] ?? 0); + if(isset($_GET['custom']) && $lengthValue == -2) { + $length = intval($_GET['custom']); // in minutes + } else { + $length = $lengthValue; + if($length != -1) { + $length = $length / 60; // we need to get length in minutes + } + } + + $queryComplete = $lengthOperator . " " . $length; + } + + if($queryComplete == "") { + $input = $GLOBALS['DB']->real_escape_string($input); + $queryComplete = "LIKE '%$input%'"; + } + + if(str_contains($sql, "WHERE")) { + $sql .= " AND "; + } else { + $sql .= " WHERE "; + } + + $sql .= " `$method` $queryComplete "; + } + + $sql_query = $GLOBALS['DB']->query($sql); + $resultsCount = $sql_query->num_rows; + $totalPages = ceil(($resultsCount / $resultsPerPage)); + + $sql_query->free(); + if($totalPages != 0 && $currentPage > $totalPages) { + $currentPage = $totalPages; + } + + $pageActiveNum = 2; + if($pageType == "all") { + $pageActiveNum = 0; + $pageName = "Kban List"; + $icon = ""; + } else if($pageType == "active") { + $pageActiveNum = 1; + $pageName = "Active Kban"; + $icon = ""; + } else if($pageType == "expired") { + $pageActiveNum = 2; + $pageName = "Expired Kban"; + $icon = ""; + } + + echo ""; + +?> + + + + query($sql . " ORDER BY time_stamp_start DESC LIMIT $resultsStart, $resultsPerPage"); + $results1 = $query->fetch_all(MYSQLI_ASSOC); + $resultsRealCount = $query->num_rows; + $query->free(); + + $url = $_SERVER['REQUEST_URI']; + if(str_contains($url, '&page')) { + $url = substr($url, 0, strpos($url, '&page')); + } + ?> +
+
+

+
+ + +
+
+

>  Total Kbans:

+
+
+ +

totalresults=>displaying of results | + 0) { + $href = $url . "&page=$previousPage"; + echo " previous |"; + } + + if($nextPage > 0 && $nextPage <= $totalPages) { + $href = $url . "&page=$nextPage"; + echo " next "; + } + + echo " "; + ?> +

+
+
+
+
+
+ + + + + + + + + + + + + + "; + } else { + foreach($results1 as $result1) { + $id = $result1['id']; + $clientName = $result1['client_name']; + $clientSteamID = $result1['client_steamid']; + $clientIP = $result1['client_ip']; + $adminSteamID = $result1['admin_steamid']; + $reason = $result1['reason']; + $time_stamp_start = strtotime($result1['time_stamp_start']); + $length_minutes = intval($result1['length']); + $isExpired = ($result1['is_expired'] == 1) ? true : false; + $isRemoved = ($result1['is_removed'] == 1) ? true : false; + $map = $result1['map']; + + $adminName = $admin->GetAdminNameFromSteamID($adminSteamID); + + $isPermanent = ($length_minutes == 0); + $length = $isPermanent ? "Permanent" : $kban->formatPlaytime($length_minutes); + + if($isExpired == true && $isRemoved == false) { + $length .= ' (Expired)'; + if(isset($_GET['active'])) { + continue; + } + } + + if($isRemoved == true) { + $length .= ' (Removed)'; + } + + $class = "row-expired"; + if(!$isExpired && !$isRemoved) { + $class = "row-active"; + } + + if($isPermanent) { + $class = "row-permanent"; + } + + if($isRemoved) { + $class = "row-expired"; + } + + $count = 0; + $realcount = 0; + if($clientSteamID == "NO STEAMID") { + $count = $kban->GetKbansNumber("", $clientIP); + $realcount = $kban->GetRealKbansNumber($clientIP); + } else { + $count = $kban->GetKbansNumber($clientSteamID); + $realcount = $kban->GetRealKbansNumber($clientSteamID); + } + + $dateA->setTimestamp($time_stamp_start); + $dateB = $dateA->format(DATE_TIME_FORMAT); + + echo ""; + if ($map != "Web Ban" && $map != "From Web") { + echo ""; + } else { + echo ""; + } + echo ""; + echo ""; + if($count >= 2) { + if ($count == $realcount) { + echo ""; + } else { + echo ""; + } + } else { + echo ""; + } + echo ""; + echo ""; + echo ""; + + echo ""; + + echo ""; + echo ""; + echo ""; + } + } + ?> + +
GameDatePlayerReasonAdminDuration

No Kban was found!

cssWeb Ban$dateB$clientName $realcount $realcount ($count)$reason$adminName$length
+
+
+
+
+ +
+ + diff --git a/js/kbans.js b/js/kbans.js new file mode 100644 index 0000000..aeec6ca --- /dev/null +++ b/js/kbans.js @@ -0,0 +1,369 @@ +function showKbanInfo(button) { + let id = $(button).attr('id-data'); + let diva = '#diva-' + id; + $(diva + '-tr').slideToggle(); + if ($(diva).attr('is_slided') == 0) { + $(diva).attr('is_slided', 1); + $(diva).slideDown(); + $(diva).css('display', 'flex'); + } else { + $(diva).attr('is_slided', 0); + $(diva).slideUp(); + } +} + +function getCsrfToken() { + if (window.CSRF_TOKEN) { + return window.CSRF_TOKEN; + } + + const meta = document.querySelector('meta[name="csrf-token"]'); + return meta ? meta.getAttribute('content') : ''; +} + +function GoTop() { + if (document.documentElement.scrollTop > 450 || document.body.scrollTop > 450) { + document.body.scrollTop = 200; + document.documentElement.scrollTop = 200; + } +} + +function ConfirmUnban(id, name, steamid) { + let reason = prompt('Please type the reason why you would Kunban ' + name + '[' + steamid + ']'); + let confirmMessage = 'Are you sure you want to Kunban ' + name + '[' + steamid + ']'; + let confirmHandler = confirm(confirmMessage); + if (confirmHandler == true) { + UnBanByID(encodeURIComponent(id), encodeURIComponent(reason)); + } +} + +function UnBanByID(id, reason) { + var xmlResponse1 = new XMLHttpRequest(); + xmlResponse1.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + $('#diva-' + id).html(this.responseText); + + let trDiva = document.getElementById('diva-tr-' + id); + trDiva.className = "row-expired"; + let oldHtml = $('#length-' + id).html(); + let newHtml = (oldHtml + ' (Removed)'); + $('#length-' + id).html(newHtml); + } + }; + + xmlResponse1.open("POST", "functions_url.php", true); + xmlResponse1.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + xmlResponse1.send( + "oldid=" + encodeURIComponent(id) + + "&reason=" + encodeURIComponent(reason) + + "&csrf_token=" + encodeURIComponent(getCsrfToken()) + ); + + var xmlResponse2 = new XMLHttpRequest(); + xmlResponse2.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + // Process xmlResponse2.responseText here + } + }; + + xmlResponse2.open("GET", "functions_url.php?id=" + encodeURIComponent(id), true); + xmlResponse2.send(); +} + +function ViewPlayerHistory(steamid, method) { + let url = "index.php?all=true&s=" + encodeURIComponent(steamid) + "&m=" + encodeURIComponent(method); + window.location.replace(url); +} + +function RebanFromID(id) { + let url = "manage.php?reban&oldid=" + encodeURIComponent(id); + window.location.replace(url); +} + +function EditFromID(id) { + let url = "manage.php?edit&oldid=" + encodeURIComponent(id); + window.location.replace(url); +} + +function addNewKban(playerName, playerSteamID, length, reason) { + var xmlResponse = new XMLHttpRequest(); + xmlResponse.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + $('.error').html(xmlResponse.responseText); + } + }; + + xmlResponse.open("POST", "functions_url.php", true); + xmlResponse.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + xmlResponse.send( + "add=1" + + "&playerName=" + encodeURIComponent(playerName) + + "&playerSteamID=" + encodeURIComponent(playerSteamID) + + "&length=" + encodeURIComponent(length) + + "&reason=" + encodeURIComponent(reason) + + "&csrf_token=" + encodeURIComponent(getCsrfToken()) + ); +} + +function EditKban(id, playerName, playerSteamID, length, reason) { + var xmlResponse1 = new XMLHttpRequest(); + xmlResponse1.onreadystatechange = function() { + if (this.readyState == 4) { + if (this.status == 200) { + $('.error').html(xmlResponse1.responseText); + } else { + $('.error').html("

Request failed (HTTP " + this.status + "). " + xmlResponse1.responseText + "

"); + } + } + }; + + xmlResponse1.open("POST", "functions_url.php", true); + xmlResponse1.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + xmlResponse1.send( + "edit=1" + + "&id=" + encodeURIComponent(id) + + "&playerName=" + encodeURIComponent(playerName) + + "&playerSteamID=" + encodeURIComponent(playerSteamID) + + "&length=" + encodeURIComponent(length) + + "&reason=" + encodeURIComponent(reason) + + "&csrf_token=" + encodeURIComponent(getCsrfToken()) + ); +} + +function RemoveKbanFromDBCheck(id) { + let confirmMessage = "Are you sure you want to delete this kban from DB?"; + let confirmHandler = confirm(confirmMessage); + if (confirmHandler == true) { + RemoveKbanFromDB(id); + } +} + +function RemoveKbanFromDB(id) { + var xmlResponse1 = new XMLHttpRequest(); + xmlResponse1.onreadystatechange = function() { + if (this.readyState !== 4) { + return; + } + + if (this.status !== 200) { + alert('Delete request failed (HTTP ' + this.status + ').'); + return; + } + + const response = (xmlResponse1.responseText || '').trim(); + if (!response) { + alert('Delete request returned an empty response.'); + return; + } + + // Keep backwards compatibility with PHP handlers returning . + const scriptMatch = response.match(/]*>([\s\S]*?)<\/script>/i); + if (scriptMatch && scriptMatch[1]) { + $.globalEval(scriptMatch[1]); + } else { + $('.hide').html(response); + } + }; + + xmlResponse1.open("POST", "functions_url.php", true); + xmlResponse1.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + xmlResponse1.send( + "delete=1" + + "&deleteid=" + encodeURIComponent(id) + + "&csrf_token=" + encodeURIComponent(getCsrfToken()) + ); +} + +function setActive(num) { + /* 0 = All Kbans, 1 = Active Kbans, 2 = Expired Kbans, 3 = Add Kban, 4 = Web Logs, 5 = Server Logs */ + if (num == 0) { + const bar = document.getElementById("allKbans"); + bar.className = "active"; + } else if (num == 1) { + const bar = document.getElementById("activeKbans"); + bar.className = "active"; + } else if (num == 2) { + const bar = document.getElementById("expiredKbans"); + bar.className = "active"; + } else if (num == 4) { + const bar = document.getElementById("weblogs"); + bar.className = "active"; + } else if (num == 5) { + const bar = document.getElementById("srvlogs"); + bar.className = "active"; + } else { + const bar = document.getElementById("addkban"); + bar.className = "active"; + } +} + +function Login() { + window.location.replace('login-init.php'); +} + +$(function() { + $('.search-modal-btn-open').on('click', function(evt) { + if ($(this).attr('id') == "main-search") { + setModalSearch("all"); + } else { + let type = $(this).attr('data-page'); + setModalSearch(type); + } + + $('.search-modal-body').toggle(); + }); + + $('.search-modal-btn-close').on('click', function() { + $('.search-modal-body').toggle(); + }); +}); + +window.addEventListener('click', function(e) { + if (e.target.className == "search-modal-body") { + $('.search-modal-body').toggle(); + } +}); + +function setModalSearch(type) { + $('#hideInput').attr('name', type); +} + +function showKbanWindowInfo(type, playerName = "", playerSteamID = "", reason = "", length = "", id = 0) { + /* type values: 0 = Add Kban, 1 = Edit Kban, 2 = Unban Kban, 3 = Delete Kban */ + const titles = [ + "Kban Added", + "Kban Edited", + "Kban Unbanned", + "Kban Deleted" + ]; + + const title = titles[type]; + $('#action-header-text').html(title + " "); + + let html = ""; + if (playerName[0]) { + html += "
  • "; + html += ""; + html += " Player"; + html += ""; + html += ""; + html += playerName; + html += ""; + html += "
  • "; + } + + if (playerSteamID[0]) { + html += "
  • "; + html += ""; + html += " Steam ID"; + html += ""; + html += ""; + html += playerSteamID; + html += ""; + html += "
  • "; + } + + if (reason[0]) { + html += "
  • "; + html += ""; + html += " Reason"; + html += ""; + html += ""; + html += reason; + html += ""; + html += "
  • "; + } + + if (length[0]) { + html += "
  • "; + html += ""; + html += " Duration"; + html += ""; + html += ""; + html += length; + html += ""; + html += "
  • "; + } + + if (type == 3) { + let diva1 = '#diva-' + encodeURIComponent(id); + $(diva1 + '-tr').hide(); + + let diva2 = '#diva-tr-' + encodeURIComponent(id); + $(diva2).hide(); + + let totalResults = $('#totalText').attr('results'); + let totalHtml = $('#totalText').html(); + + let totalResultsAfter = totalResults - 1; + let totalResultsString = totalResults.toString(); + let totalResultsAfterString = totalResultsAfter.toString(); + + let newTotalHtml = totalHtml.replace(totalResultsString, totalResultsAfterString); + $('#totalText').attr('results', totalResultsAfter); + $('#totalText').html(newTotalHtml); + + let startResults = $('#displaying-text').attr('results'); + let endResults = $('#displaying-text').attr('totalresults'); + let displayHtml = $('#displaying-text').html(); + + let startResultsString = startResults.toString(); + let startResultsAfter = 0; + + if (startResults != 0) { + startResultsAfter = startResults - 1; + } + + let startResultsAfterString = startResultsAfter.toString(); + + let endResultsString = endResults.toString(); + let endResultsAfter = endResults - 1; + let endResultsAfterString = endResultsAfter.toString(); + + $('#displaying-text').attr('results', startResultsAfter); + $('#displaying-text').attr('totalresults', endResultsAfter); + + let newDisplayHtml = ""; + if (startResults == endResults) { + let first = displayHtml.replace('-' + ' ' + totalResultsString, '-' + ' ' + totalResultsAfterString); + newDisplayHtml = first.replace(startResultsString, startResultsAfterString); + } else { + let first = displayHtml.replace(startResultsString, startResultsAfterString); + let second = first.replace('-' + ' ' + totalResultsString, '-' + ' ' + totalResultsAfterString); + newDisplayHtml = second.replace(endResultsString, endResultsAfterString); + } + + $('#displaying-text').html(newDisplayHtml); + + let count = $('#' + encodeURIComponent(id) + '-count').attr('count'); + let newCountHtml = count ? (count - 1) : 0; + + var allCounts = document.getElementsByClassName('count'); + for (var i = 0; i < allCounts.length; i++) { + let steamID = $('#' + allCounts[i].id).attr('steamid'); + if (steamID == playerSteamID) { + $('#' + allCounts[i].id).attr('count', newCountHtml); + let Html = $('#' + allCounts[i].id).html(); + if (count) { + let newHtml = Html.replace(count.toString(), newCountHtml.toString()); + $('#' + allCounts[i].id).html(newHtml); + } + } + } + } + + $('.kban-action-window .info .kban_details').html(html); + + $('.kban-action-window').css('display', 'block'); + + let sec = 3; + setTimeout(CloseWindow, (sec * 1000)); +} + +function CloseWindow() { + $('.kban-action-window').css('display', 'none'); +} + +function GoHome() { + window.location.href = 'index.php?all'; +} diff --git a/login-init.php b/login-init.php new file mode 100644 index 0000000..3a3970c --- /dev/null +++ b/login-init.php @@ -0,0 +1,16 @@ + 'http://specs.openid.net/auth/2.0', + 'openid.mode' => 'checkid_setup', + 'openid.return_to' => $server_host_url . '/login-process.php', + 'openid.realm' => $server_host_url, + 'openid.identity' => 'http://specs.openid.net/auth/2.0/identifier_select', + 'openid.claimed_id' => 'http://specs.openid.net/auth/2.0/identifier_select', + ]; + + $steam_login_url = 'https://steamcommunity.com/openid/login'.'?'.http_build_query($login_url_params, '', '&'); + + header("location: $steam_login_url"); + exit(); +?> diff --git a/login-process.php b/login-process.php new file mode 100644 index 0000000..ca49213 --- /dev/null +++ b/login-process.php @@ -0,0 +1,111 @@ + $_GET['openid_assoc_handle'], + 'openid.signed' => $_GET['openid_signed'], + 'openid.sig' => $_GET['openid_sig'], + 'openid.ns' => 'http://specs.openid.net/auth/2.0', + 'openid.mode' => 'check_authentication', + ]; + + $signed = explode(',', $_GET['openid_signed']); + + foreach ($signed as $item) { + $key = 'openid_'.str_replace('.', '_', $item); + if (!isset($_GET[$key])) { + echo 'error: invalid openid response'; + exit(); + } + + $val = $_GET[$key]; + $params['openid.'.$item] = stripslashes($val); + } + + $data = http_build_query($params); + //data prep + $context = stream_context_create([ + 'http' => [ + 'method' => 'POST', + 'header' => "Accept-language: en\r\n". + "Content-type: application/x-www-form-urlencoded\r\n". + 'Content-Length: '.strlen($data)."\r\n", + 'content' => $data, + ], + ]); + + //get the data + $result = file_get_contents('https://steamcommunity.com/openid/login', false, $context); + + if($result !== false && preg_match("#is_valid\s*:\s*true#i", $result)){ + preg_match('#^https://steamcommunity.com/openid/id/([0-9]{17,25})#', $_GET['openid_claimed_id'], $matches); + $steamID64 = isset($matches[1]) && is_numeric($matches[1]) ? $matches[1] : 0; + } else { + echo 'error: unable to validate your request'; + exit(); + } + + $steam_api_key = $GLOBALS['STEAM_API_KEY']; + $secret_key = $GLOBALS['SECRET_KEY']; + + $response = file_get_contents('https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key='.$steam_api_key.'&steamids='.$steamID64); + if ($response === false) { + echo 'error: unable to fetch steam profile'; + exit(); + } + + $response = json_decode($response,true); + if (!is_array($response) || empty($response['response']['players'][0])) { + echo 'error: invalid steam profile response'; + exit(); + } + + + $userData = $response['response']['players'][0]; + + $steamID64 = $userData['steamid']; + $steam = new Steam(); + $steamID32 = $steam->SteamID64_To_SteamID($steamID64); + + $admin = new Admin(); + if($admin->IsLoginValid($steamID32, $secret_key, true)) { + setcookie('steamID', $steamID32, (time() * 30), "/", $_SERVER['SERVER_NAME'], true, true); + setcookie("secret_key", $secret_key, (time() * 30), "/", $_SERVER['SERVER_NAME'], true, true); + + // Create an unique cookie based on sbpp aid for each user + // Aid is the safer option to use as a cookie since it does not have any personal information + $sql = "SELECT aid FROM sb_admins WHERE authid = ?"; + $stmt = $GLOBALS['SBPP']->prepare($sql); + $stmt->bind_param("s", $steamID32); + $stmt->execute(); + $queryResult = $stmt->get_result(); + $stmt->close(); + + $row = $queryResult->fetch_assoc(); + $aid = $row['aid'] ?? ''; + + setcookie("aid", $aid, (time() * 30), "/", $_SERVER['SERVER_NAME'], true, true); + } else { + echo 'error: your Steam account is not registered as a SourceBans admin, so you cannot log in to this panel'; + exit(); + } + + $server_host_url = (!empty($_SERVER['HTTPS']) ? 'https' : 'http').'://'.$_SERVER['HTTP_HOST']; + header("Location: ". $server_host_url); + die(); +?> diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..ba69044 --- /dev/null +++ b/logout.php @@ -0,0 +1,10 @@ + diff --git a/logs.php b/logs.php new file mode 100644 index 0000000..bd5da24 --- /dev/null +++ b/logs.php @@ -0,0 +1,200 @@ + +
    +

    You do not have access to this page.

    +
    + + "; + die(); + } + + $admin = new Admin(); + $admin->UpdateAdminInfo($_COOKIE['steamID']); + if(!$admin->DoesHaveFullAccess()) { + echo "
    +
    +

    You do not have access to this page.

    +
    +
    + "; + die(); + } + + if(isset($_GET['page'])) { + $currentPage = max(1, (int) $_GET['page']); + } else { + $currentPage = 1; + } + + $isWeb = false; + $isSrv = false; + if(isset($_GET['web'])) { + $isWeb = true; + } + + if(isset($_GET['srv'])) { + $isSrv = true; + } + + + $resultsPerPage = 20; + $resultsStart = (($currentPage - 1) * $resultsPerPage); + + $sql = "SELECT * FROM "; + $sql .= ($isWeb) ? "`KbRestrict_weblogs`" : "`KbRestrict_srvlogs`"; + + if(isset($_GET['s']) && isset($_GET['m'])) { + $input = trim($_GET['s']); + $method = formatMethod(intval($_GET['m'])); + + if($method == "client_steamid" || $method == "admin_steamid") { + $steamInput = str_replace(" ", "", $input); + $steam = new Steam(); + $result = $steam->verifyAndConvertSteamID($steamInput); + + if ($result['success'] && !empty($result['steamID2'])) { + $input = $result['steamID2']; + } else { + error_log("Error converting SteamID: " . $result['error']); + } + } + + $input = $GLOBALS['DB']->real_escape_string($input); + $sql .= " WHERE `$method` LIKE '%$input%'"; + } + + $sql_query = $GLOBALS['DB']->query($sql); + $resultsCount = $sql_query->num_rows; + $totalPages = ceil(($resultsCount / $resultsPerPage)); + + $sql_query->free(); + if($totalPages != 0 && $currentPage > $totalPages) { + $currentPage = $totalPages; + } + + $num = ($isWeb) ? 4 : 5; + $pageType = ($isWeb) ? "web" : "srv"; + echo ""; +?> + + + + query($sql . " ORDER BY time_stamp DESC LIMIT $resultsStart, $resultsPerPage"); + $results1 = $query->fetch_all(MYSQLI_ASSOC); + $resultsRealCount = $query->num_rows; + $query->free(); + + $url = $_SERVER['REQUEST_URI']; + if(str_contains($url, '&page')) { + $url = substr($url, 0, strpos($url, '&page')); + } + ?> +
    +
    +

    Logs

    +
    + + +
    +
    +   Total Logs: +
    +
    + +

    displaying of results | + 0) { + $href = $url . "&page=$previousPage"; + echo " previous |"; + } + + if($nextPage > 0 && $nextPage <= $totalPages) { + $href = $url . "&page=$nextPage"; + echo " next "; + } + + echo " "; + ?> +

    +
    +
    +
    +
    +
    + + + + + + + + + + + GetAdminNameFromSteamID($adminSteamID); + + + $date->setTimestamp($time_stamp); + $dateFormated = $date->format(DATE_TIME_FORMAT); + + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + } + ?> + +
    DatePlayerAdminAction
    $dateFormated$clientName ($clientSteamID)$adminName$message
    +
    +
    +
    +
    + + + diff --git a/manage.php b/manage.php new file mode 100644 index 0000000..aeacc69 --- /dev/null +++ b/manage.php @@ -0,0 +1,234 @@ + +
    +

    You do not have access to this page.

    +
    + + "; + die(); + } + + $reban = false; + $edit = false; + $add = false; + + if(isset($_GET['reban'])) { + $reban = true; + $oldid = $_GET['oldid'] ?? 0; + $kban = new Kban(); + $info = $kban->getKbanInfoFromID(intval($oldid)); + if ($info === null) { + echo "

    Kban not found!

    "; + die(); + } + } + + if(isset($_GET['edit'])) { + $edit = true; + $oldid = $_GET['oldid'] ?? 0; + $kban = new Kban(); + $info = $kban->getKbanInfoFromID(intval($oldid)); + if ($info === null) { + echo "

    Kban not found!

    "; + die(); + } + + if ($info['is_expired'] == 1) { + echo "

    Cannot edit an old kban!

    "; + die(); + } + } + + if(isset($_GET['add'])) { + $add = true; + + echo ""; + } + +?> + + + + + " : ""; + $formHeader .= " $text"; + $icon = ($edit == false) ? "" : ""; + ?> +
    +
    +

    + +
    +
    +
    +
    +

    +
    + +
    + +
    + + + +
    + + > +
    + + + +
    + + + + + title="Why the f*ck do you want to edit the SteamID? Just add a new Kban nigger" disabled> + +
    + + + +
    + + > +
    + + +
    + + +
    + + + +
    + +

    Enter 0 minutes for a permanent ban

    + style="width: 110px; display: inline-block;"> + +
    + + + $buttonTextValidate"; + ?> +
    +
    +
    + + + + diff --git a/steam.php b/steam.php new file mode 100644 index 0000000..c97344d --- /dev/null +++ b/steam.php @@ -0,0 +1,154 @@ +getMessage()); + throw $e; + } + } + + public static function SteamID_To_SteamID3($steamid32) + { + $steamid32 = (string) $steamid32; + + if (preg_match('/^STEAM_[01]\:[01]\:(.*)$/', $steamid32, $res)) { + $st = '[U:1:'; + $st .= $res[1] * 2 + intval(substr($steamid32, 8, 1)); + $st .= ']'; + return $st; + } + + return false; + } + + public static function SteamID3_To_SteamID($steamid3) + { + $steamid3 = (string) $steamid3; + + if (preg_match("/U:1:(\d+)/", $steamid3, $matches)) { + $steam3 = intval($matches[1]); + $A = $steam3 % 2; + $B = intval($steam3 / 2); + return "STEAM_0:" . $A . ":" . $B; + } + return false; + } + + public static function SteamID_To_SteamID64($steamid32) + { + $steamid32 = (string) $steamid32; + self::assertSixtyFourBit(); + + if (preg_match('/^STEAM_[01]:([01]):(\d+)$/', $steamid32, $res)) { + $steamID64 = 76561197960265728 + ((int) $res[2] * 2) + (int) $res[1]; + return (string) $steamID64; + } + + return false; + } + + public static function SteamID64_To_SteamID($steamid64) + { + $steamid64 = (string) $steamid64; + self::assertSixtyFourBit(); + $pattern = "/^(7656119)([0-9]{10})$/"; + if (preg_match($pattern, $steamid64, $match)) { + $const1 = 7960265728; + $const2 = "STEAM_0:"; + $steam32 = ''; + if ($const1 <= $match[2]) { + $a = ($match[2] - $const1) % 2; + $b = ($match[2] - $const1 - $a) / 2; + $steam32 = $const2 . $a . ':' . $b; + } + + return $steam32; + } + + return false; + } + + public static function GetSteamProfile($steamid64, $attribute) + { + $steamid64 = (string) $steamid64; + $attribute = (string) $attribute; + $previousLibxml = libxml_use_internal_errors(true); + + if (preg_match('/^\d+$/', $steamid64)) { + $xml = @simplexml_load_file("https://steamcommunity.com/profiles/".$steamid64."?xml=1"); + } else { + $xml = @simplexml_load_file("https://steamcommunity.com/id/".$steamid64."?xml=1"); + } + libxml_clear_errors(); + libxml_use_internal_errors($previousLibxml); + + if ($xml === false) { + return array(); + } + + $SteamProfileAttribute = array(); + + $attributes = explode(', ', $attribute); + + foreach ($attributes as $key => $attr_key) { + $SteamProfileAttribute += [$attr_key => $xml->$attr_key]; + } + + return $SteamProfileAttribute; + } + + function verifyAndConvertSteamID($steamid) { + try { + $steamID2 = Steam::convertSteamID($steamid); + return ['success' => true, 'steamID2' => $steamID2]; + } catch (Exception $e) { + return ['success' => false, 'error' => $e->getMessage()]; + } + } + +} +?> diff --git a/verify_steamid.php b/verify_steamid.php new file mode 100644 index 0000000..42b78b7 --- /dev/null +++ b/verify_steamid.php @@ -0,0 +1,10 @@ +verifyAndConvertSteamID($steamid); + echo json_encode($result); +} +?>