initial repo creation
477
.gitignore
vendored
Normal file
@ -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 <path>/<filename>
|
||||||
|
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=<directory_path>
|
||||||
|
csrc/
|
||||||
|
|
||||||
|
# Log file - the following switch allows to specify the file that will be
|
||||||
|
# used to write all messages from simulation: -l <filename>
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Coverage results (generated with urg) and database location. The
|
||||||
|
# following switch can also be used: urg -dir <coverage_directory>.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
|
||||||
33
config.example.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
define('SERVER_FORUM_NAME', 'mywebsite');
|
||||||
|
define('SERVER_FORUM_URL', 'https://mywebsite.com');
|
||||||
|
define('SERVER_NAME', 'My server');
|
||||||
|
define('SERVER_FASTDL', 'https://fastdl.mywebsite.com');
|
||||||
|
define('STEAM_GROUP', 'https://steamcommunity.com/groups/mysteamgroup');
|
||||||
|
define('DISCORD', 'https://discord.gg/example');
|
||||||
|
define('STEAM_API_KEY', 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
|
||||||
|
define('SECRET_KEY', ''); // this is very important, don't leave it empty or your website wll be insecure
|
||||||
|
|
||||||
|
define('SBPP_DB_HOST', 'example'); // The host/ip to your SQL server
|
||||||
|
define('SBPP_DB_USER', 'example'); // The username to connect with
|
||||||
|
define('SBPP_DB_PASSWORD', 'example'); // The password
|
||||||
|
define('SBPP_DB_NAME', 'example'); // Database name
|
||||||
|
|
||||||
|
define('GID_STAFF', [1, 3, 4]); // gid of staff in sb_groups
|
||||||
|
define('GID_ADMIN', [5]); // gid of server admins in sb_groups
|
||||||
|
|
||||||
|
define('DATE_TIME_ZONE', 'GMT+2');
|
||||||
|
define('DATE_TIME_FORMAT', 'Y-m-d H:i:s');
|
||||||
|
|
||||||
|
define('DB_HOST', '127.0.0.1'); // The host/ip to your SQL server
|
||||||
|
define('DB_USER', 'example'); // The username to connect with
|
||||||
|
define('DB_PASSWORD', 'example'); // The password
|
||||||
|
define('DB_NAME', 'example'); // Database name
|
||||||
|
|
||||||
|
define('DB_HOST_PLAYTIME', 'localhost');
|
||||||
|
define('DB_USER_PLAYTIME', '');
|
||||||
|
define('DB_PASSWORD_PLAYTIME', '');
|
||||||
|
define('DB_NAME_PLAYTIME', '');
|
||||||
|
|
||||||
|
?>
|
||||||
54
connect.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// Directories
|
||||||
|
// ---------------------------------------------------
|
||||||
|
define('ROOT', dirname(__FILE__) . "/");
|
||||||
|
|
||||||
|
if (!file_exists(ROOT.'/config.php')) {
|
||||||
|
die('Missing config.php.');
|
||||||
|
}
|
||||||
|
require_once(ROOT.'/config.php');
|
||||||
|
|
||||||
|
$GLOBALS['DB'] = mysqli_connect(DB_HOST,
|
||||||
|
DB_USER,
|
||||||
|
DB_PASSWORD,
|
||||||
|
DB_NAME
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check Kban DB connection
|
||||||
|
if (!$GLOBALS['DB']) {
|
||||||
|
die('Main Database Connection error: ' . mysqli_connect_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
$GLOBALS['SBPP'] = mysqli_connect( SBPP_DB_HOST,
|
||||||
|
SBPP_DB_USER,
|
||||||
|
SBPP_DB_PASSWORD,
|
||||||
|
SBPP_DB_NAME);
|
||||||
|
|
||||||
|
// Check SBPP DB connection
|
||||||
|
if (!$GLOBALS['SBPP']) {
|
||||||
|
die('SBPP Database Connection error: ' . mysqli_connect_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
$GLOBALS['DB_PLAYTIME'] = mysqli_connect( DB_HOST_PLAYTIME,
|
||||||
|
DB_USER_PLAYTIME,
|
||||||
|
DB_PASSWORD_PLAYTIME,
|
||||||
|
DB_NAME_PLAYTIME);
|
||||||
|
|
||||||
|
// Check Playtime DB connection
|
||||||
|
if (!$GLOBALS['DB_PLAYTIME']) {
|
||||||
|
die('Playtime Database Connection error: ' . mysqli_connect_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
$GLOBALS['SERVER_FORUM_NAME'] = SERVER_FORUM_NAME;
|
||||||
|
$GLOBALS['SERVER_FORUM_URL'] = SERVER_FORUM_URL;
|
||||||
|
$GLOBALS['SERVER_NAME'] = SERVER_NAME;
|
||||||
|
$GLOBALS['SERVER_FASTDL'] = SERVER_FASTDL;
|
||||||
|
$GLOBALS['STEAM_API_KEY'] = STEAM_API_KEY;
|
||||||
|
$GLOBALS['STEAM_GROUP'] = STEAM_GROUP;
|
||||||
|
$GLOBALS['DISCORD'] = DISCORD;
|
||||||
|
$GLOBALS['SECRET_KEY'] = SECRET_KEY;
|
||||||
|
|
||||||
|
/* TIME ZONE */
|
||||||
|
date_default_timezone_set('UTC');
|
||||||
|
?>
|
||||||
1274
css/style.css
Normal file
13
footer.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
<footer class="footer">
|
||||||
|
<div class="layout_container flex flex-jc:space-between flex-ai:center">
|
||||||
|
<div class="flex flex-fd:column text:left">
|
||||||
|
<span><i class="fas fa-code"></i> Original code by <a href="https://github.com/Dolly132" title="Dolly's GitHub Profile" target="_blank" rel="noopener">Dolly</a> and <a href="https://github.com/Rushaway/" title="Rushaway's GitHub Profile" target="_blank" rel="noopener">Rushaway</a></span>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-fd:column text:right">
|
||||||
|
<p>Powered by <a href="https://github.com/srcdslab/sm-plugin-KnockbackRestrict/tree/main" title="KnockbackRestrict Repository" target="_blank" rel="noopener">KnockbackRestrict</a></p>
|
||||||
|
<p>This Website is open source, check it out <a href="https://github.com/srcdslab/kbans-web" title="Kbans website Repository" target="_blank" rel="noopener">here</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
917
functions_global.php
Normal file
@ -0,0 +1,917 @@
|
|||||||
|
<?php
|
||||||
|
include_once('steam.php');
|
||||||
|
class Utility {
|
||||||
|
public static function sanitizeInput($input) {
|
||||||
|
$input = (string) ($input ?? '');
|
||||||
|
$replacements = array("'", '"', "\\", ";", "`", "--", "#", "=", ">", "<", "&", "%", "|", "^", "~", "(", ")");
|
||||||
|
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 "<i>Admin Deleted</i>";
|
||||||
|
}
|
||||||
|
|
||||||
|
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 "<script>showKbanWindowInfo(2, \"$playerName\", \"$playerSteamID\", \"$reason\", \"$length minutes\");</script>";
|
||||||
|
echo "<script>showKbanWindowInfo(2, \"$playerName\", \"$playerSteamID\", \"$reason\", \"$length minutes\", $id);</script>";
|
||||||
|
|
||||||
|
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 "<script>showKbanWindowInfo(3, \"$playerName\", \"$playerSteamID\", \"$reason\", \"$length minutes\", $id);</script>";
|
||||||
|
//echo "<script>window.location.replace('index.php?all');</script>";
|
||||||
|
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 "<script>showKbanWindowInfo(0, \"$playerName\", \"$playerSteamID\", \"$reason\", \"$lengthInMinutes minutes\");</script>";
|
||||||
|
//echo "<script>window.location.replace('index.php?all');</script>";
|
||||||
|
}
|
||||||
|
|
||||||
|
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 "<script>showKbanWindowInfo(1, \"$playerName\", \"$playerSteamID\", \"$reason\", \"$lengthInMinutes minutes\");</script>";
|
||||||
|
//echo "<script>window.location.replace('index.php?all');</script>";
|
||||||
|
}
|
||||||
|
|
||||||
|
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 "<div class='kban-buttons'>";
|
||||||
|
|
||||||
|
$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 "<button onclick='$href' class='button button-light' title='View History'><i class='fa-solid fa-clock-rotate-left'></i> View History</button>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsAdminLoggedIn()) {
|
||||||
|
$admin->UpdateAdminInfo($_COOKIE['steamID']);
|
||||||
|
|
||||||
|
if ($isRemoved == false && $isExpired == false) {
|
||||||
|
|
||||||
|
if ($admin->DoesHaveFullAccess() || $adminSteamID == $admin->adminSteamID) {
|
||||||
|
$editFunction = "EditFromID(\"$id\")";
|
||||||
|
echo "<button class='button button-primary' title='Edit' onclick='$editFunction'><i class='fa-regular fa-pen-to-square'></i> Edit Details</button>";
|
||||||
|
$unbanFunction = "ConfirmUnban($id, \"$clientName\", \"$clientSteamID\");";
|
||||||
|
echo "<button class='button button-important' title='Unban' onclick='$unbanFunction'><i class='fas fa-undo fa-lg'></i> Unban</button>";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($clientSteamID != "NO STEAMID" && !$kban->IsSteamIDAlreadyBanned($clientSteamID)) {
|
||||||
|
$reBanFunction = "RebanFromID(\"$id\");";
|
||||||
|
echo "<button class='button button-important' title='Reban' onclick='$reBanFunction'><i class='fas fa-redo fa-lg'></i> Reban</button>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($admin->DoesHaveFullAccess()) {
|
||||||
|
$deleteFunction = "RemoveKbanFromDBCheck($id);";
|
||||||
|
echo "<button class='button button-important' title='Delete' onclick='$deleteFunction'><i class='fa-solid fa-trash'></i> Delete KBan</button>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsAdminLoggedIn()) {
|
||||||
|
$href = "Login();";
|
||||||
|
echo "<button onclick='$href' class='button button-success' title='Sign in'>Admin? Sign in</button>";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "</div>";
|
||||||
|
|
||||||
|
$date = new DateTime("now", new DateTimeZone(DATE_TIME_ZONE));
|
||||||
|
$date->setTimestamp($time_stamp_start);
|
||||||
|
$startDate = $date->format(DATE_TIME_FORMAT);
|
||||||
|
|
||||||
|
echo "<ul class='kban_details'>";
|
||||||
|
|
||||||
|
echo "<li>";
|
||||||
|
echo "<span><i class='fas fa-user'></i> Player</span>";
|
||||||
|
echo "<span>$clientName</span>";
|
||||||
|
echo "</li>";
|
||||||
|
|
||||||
|
$steam = new Steam();
|
||||||
|
$clientSteamID3 = $steam->SteamID_To_SteamID3($clientSteamID);
|
||||||
|
$clientSteamID64 = $steam->SteamID_To_SteamID64($clientSteamID);
|
||||||
|
echo "<li>";
|
||||||
|
echo "<span><i class='fab fa-steam-symbol'></i> Steam ID</span>";
|
||||||
|
echo "<span>$clientSteamID</span>";
|
||||||
|
echo "</li>";
|
||||||
|
|
||||||
|
echo "<li>";
|
||||||
|
echo "<span><i class='fab fa-steam-symbol'></i> Steam3 ID</span>";
|
||||||
|
echo "<span><a href='https://steamcommunity.com/profiles/$clientSteamID64' target='_blank'>$clientSteamID3</a></span>";
|
||||||
|
echo "</li>";
|
||||||
|
|
||||||
|
echo "<li>";
|
||||||
|
echo "<span><i class='fab fa-steam-symbol'></i> Steam Community</span>";
|
||||||
|
echo "<span><a href='https://steamcommunity.com/profiles/$clientSteamID64' target='_blank'>$clientSteamID64</a></span>";
|
||||||
|
echo "</li>";
|
||||||
|
|
||||||
|
if (IsAdminLoggedIn() && $admin->DoesHaveFullAccess()) {
|
||||||
|
echo "<li>";
|
||||||
|
echo "<span><i class='fas fa-network-wired'></i> IP address</span>";
|
||||||
|
if ($clientIP == "Unknown" || $clientIP == "unknown") {
|
||||||
|
echo "<span>$clientIP</span>";
|
||||||
|
} else {
|
||||||
|
echo "<span><a href='https://www.infobyip.com/ip-$clientIP.html' target='_blank'>$clientIP</a></span>";
|
||||||
|
}
|
||||||
|
echo "</li>";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "<li>";
|
||||||
|
echo "<span><i class='fas fa-play'></i> Invoked on</span>";
|
||||||
|
echo "<span>$startDate</span>";
|
||||||
|
echo "</li>";
|
||||||
|
|
||||||
|
echo "<li>";
|
||||||
|
echo "<span><i class='fas fa-hourglass-half'></i> KBan Duration</span>";
|
||||||
|
echo "<span>$length</span>";
|
||||||
|
echo "</li>";
|
||||||
|
|
||||||
|
echo "<li>";
|
||||||
|
echo "<span><i class='fas fa-clock'></i> Started on</span>";
|
||||||
|
echo "<span>$startedOn</span>";
|
||||||
|
echo "</li>";
|
||||||
|
|
||||||
|
echo "<li>";
|
||||||
|
echo "<span><i class='fas fa-clock'></i> Expires on</span>";
|
||||||
|
echo "<span>$expiresOn</span>";
|
||||||
|
echo "</li>";
|
||||||
|
|
||||||
|
echo "<li>";
|
||||||
|
echo "<span><i class='fas fa-question'></i> Reason</span>";
|
||||||
|
echo "<span>$reason</span>";
|
||||||
|
echo "</li>";
|
||||||
|
|
||||||
|
echo "<li>";
|
||||||
|
echo "<span><i class='fas fa-ban'></i> Banned by Admin</span>";
|
||||||
|
echo "<span>$adminName</span>";
|
||||||
|
echo "</li>";
|
||||||
|
|
||||||
|
echo "<li>";
|
||||||
|
echo "<span><i class='fa-solid fa-circle-exclamation'></i> KBan Status</span>";
|
||||||
|
echo "<span>$status</span>";
|
||||||
|
echo "</li>";
|
||||||
|
|
||||||
|
if ($isRemoved) {
|
||||||
|
$date->setTimestamp($time_stamp_removed);
|
||||||
|
$removedDate = $date->format(DATE_TIME_FORMAT);
|
||||||
|
|
||||||
|
echo "<li>";
|
||||||
|
echo "<span><i class='fas fa-play'></i> Unbanned on</span>";
|
||||||
|
echo "<span>$removedDate</span>";
|
||||||
|
echo "</li>";
|
||||||
|
|
||||||
|
echo "<li>";
|
||||||
|
echo "<span><i class='fas fa-ban'></i> Unbanned By Admin</span>";
|
||||||
|
echo "<span>$adminNameRemoved</span>";
|
||||||
|
echo "</li>";
|
||||||
|
|
||||||
|
echo "<li>";
|
||||||
|
echo "<span><i class='fas fa-question'></i> Unban Reason</span>";
|
||||||
|
echo "<span>$reason_removed</span>";
|
||||||
|
echo "</li>";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "<li>";
|
||||||
|
echo "<span><i class='fa-solid fa-gamepad'></i> Map</span>";
|
||||||
|
if ($map != "Web Ban" && $map != "From Web") {
|
||||||
|
$fastdl = $GLOBALS['SERVER_FASTDL'];
|
||||||
|
echo "<span><a href='$fastdl/maps/$map.bsp.bz2'>$map</a></span>";
|
||||||
|
} else {
|
||||||
|
echo "<span>$map</span>";
|
||||||
|
}
|
||||||
|
echo "</li>";
|
||||||
|
|
||||||
|
echo "</ul>";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetKbanLengths($addTag = true) {
|
||||||
|
if($addTag == true) {
|
||||||
|
echo "<select id='add-select' class='select add-select'>";
|
||||||
|
}
|
||||||
|
echo "<optgroup label='Minutes'>";
|
||||||
|
for($second = 1; $second < 3600; $second++) {
|
||||||
|
/* we want 10, 30, and 50 minutes */
|
||||||
|
if ($second == (10*60) || $second == (30*60) || $second == (50*60)) {
|
||||||
|
$minutes = ($second / 60);
|
||||||
|
$minutesToSeconds = ($minutes * 60);
|
||||||
|
if ($second == $minutesToSeconds) { //
|
||||||
|
echo "<option value='$second'>$minutes Minutes</option>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "</optgroup>";
|
||||||
|
echo "<optgroup label='Hours'>";
|
||||||
|
for($second = 1; $second < (3600 * 24); $second++) {
|
||||||
|
/* we want 1, 2, 4, 8, and 16 hours */
|
||||||
|
if ($second == (1*60*60) || $second == (2*60*60) || $second == (4*60*60) ||
|
||||||
|
$second == (8*60*60) || $second == (16*60*60)) {
|
||||||
|
$hours = ($second / (60 * 60));
|
||||||
|
$hoursToSeconds = ($hours * (60 * 60));
|
||||||
|
if ($second == $hoursToSeconds) { //
|
||||||
|
echo "<option value='$second'>$hours Hours</option>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "</optgroup>";
|
||||||
|
echo "<optgroup label='Days'>";
|
||||||
|
|
||||||
|
for($second = 1; $second <= (3600 * 24 * 3); $second++) {
|
||||||
|
/* we want 1, 2, 3 days */
|
||||||
|
if ($second == (1*60*60*24) || $second == (2*60*60*24) || $second == (3*60*60*24)) {
|
||||||
|
$days = ($second / (60 * 60 * 24));
|
||||||
|
$daysToSeconds = ($days * (60 * 60 * 24));
|
||||||
|
if ($second == $daysToSeconds) { //
|
||||||
|
echo "<option value='$second'>$days Days</option>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "</optgroup>";
|
||||||
|
echo "<optgroup label='Weeks'>";
|
||||||
|
|
||||||
|
for($second = 1; $second <= (3600 * 24 * 7 * 3); $second++) {
|
||||||
|
/* we want 1, 2, 3 weeks */
|
||||||
|
if ($second == (1*60*60*24*7) || $second == (2*60*60*24*7) || $second == (3*60*60*24*7)) {
|
||||||
|
$weeks = ($second / (60 * 60 * 24 * 7));
|
||||||
|
$weeksToSeconds = ($weeks * (60 * 60 * 24 * 7));
|
||||||
|
if ($second == $weeksToSeconds) { //
|
||||||
|
echo "<option value='$second'>$weeks Weeks</option>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "</optgroup>";
|
||||||
|
echo "<optgroup label='Months'>";
|
||||||
|
for($second = 1; $second <= (3600 * 24 * 30 * 3); $second++) {
|
||||||
|
/* we want 1, 2, 3 months */
|
||||||
|
if ($second == (1*60*60*24*30) || $second == (2*60*60*24*30) || $second == (3*60*60*24*30)) {
|
||||||
|
$months = ($second / (60 * 60 * 24 * 30));
|
||||||
|
$monthsToSeconds = ($months * (60 * 60 * 24 * 30));
|
||||||
|
if ($second == $monthsToSeconds) { //
|
||||||
|
echo "<option value='$second'>$months Months</option>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "</optgroup>";
|
||||||
|
$admin = new Admin();
|
||||||
|
$admin->UpdateAdminInfo($GLOBALS['steamID']);
|
||||||
|
if ($addTag == false || $admin->DoesHaveFullAccess()) {
|
||||||
|
echo "<optgroup label='Others'>";
|
||||||
|
echo "<option value='0'>Permanent</option>";
|
||||||
|
if($addTag == false) {
|
||||||
|
echo "<option value='-1'>Session</option>";
|
||||||
|
echo "<option value='-2'>Custom (in Minutes)</option>";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "</optgroup>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if($addTag == true) {
|
||||||
|
echo "</select>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetKbanLengthTypes() {
|
||||||
|
echo "<select id='edit-select' class='select edit-select'>";
|
||||||
|
echo "<option value='2' selected>Minutes</option>";
|
||||||
|
echo "<option value='3'>Hours</option>";
|
||||||
|
echo "<option value='4'>Days</option>";
|
||||||
|
echo "<option value='5'>Weeks</option>";
|
||||||
|
echo "<option value='6'>Months</option>";
|
||||||
|
echo "</select>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
236
functions_url.php
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
<?php
|
||||||
|
include_once('connect.php');
|
||||||
|
include_once('functions_global.php');
|
||||||
|
|
||||||
|
function sanitizeString($input) {
|
||||||
|
$input = (string) ($input ?? '');
|
||||||
|
// Replace problematic characters with an empty string
|
||||||
|
$replacements = array("'", '"', "\\", ";", "`", "--", "#", "=", ">", "<", "&", "%", "|", "^", "~", "(", ")");
|
||||||
|
$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 = "<i class='fa-solid fa-xmark'></i> ";
|
||||||
|
if (empty($playerName)) {
|
||||||
|
echo "<p>$icon Player name cannot be empty!</p>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($playerSteamID)) {
|
||||||
|
echo "<p>$icon Player SteamID cannot be empty!</p>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preg_match("/^STEAM_[0-5]:[01]:\d+$/", $playerSteamID)) {
|
||||||
|
echo "<p>$icon Invalid SteamID Format</p>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($reason)) {
|
||||||
|
echo "<p>$icon Reason cannot be empty!</p>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_contains($playerName, "'") || str_contains($playerName, "\"")) {
|
||||||
|
echo "<p>$icon ' and \" characters cannot be used for Player Name!</p>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_contains($reason, "'") || str_contains($reason, "\"")) {
|
||||||
|
echo "<p>$icon ' and \" characters cannot be used for Reason!</p>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
$kban = new Kban();
|
||||||
|
if ($kban->IsSteamIDAlreadyBanned($playerSteamID)) {
|
||||||
|
echo "<p>$icon $playerSteamID is already kbanned!</p>";
|
||||||
|
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 "<p>Security token expired or invalid. Please refresh the page and try again.</p>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_COOKIE['steamID'])) {
|
||||||
|
echo "<p>You are not logged in. Please log in again.</p>";
|
||||||
|
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 = "<i class='fa-solid fa-xmark'></i> ";
|
||||||
|
if (empty($playerName)) {
|
||||||
|
echo "<p>$icon Player name cannot be empty!</p>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($playerSteamID)) {
|
||||||
|
echo "<p>$icon Player SteamID cannot be empty!</p>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preg_match("/^STEAM_[0-5]:[01]:\d+$/", $playerSteamID)) {
|
||||||
|
echo "<p>$icon Invalid SteamID Format</p>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($reason)) {
|
||||||
|
echo "<p>$icon Reason cannot be empty!</p>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_contains($playerName, "'") || str_contains($playerName, "\"")) {
|
||||||
|
echo "<p>$icon ' and \" characters cannot be used for Player Name!</p>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_contains($reason, "'") || str_contains($reason, "\"")) {
|
||||||
|
echo "<p>$icon ' and \" characters cannot be used for Reason!</p>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
$admin = new Admin();
|
||||||
|
$admin->UpdateAdminInfo($_COOKIE['steamID']);
|
||||||
|
|
||||||
|
if ($length === null && !$admin->DoesHaveFullAccess()) {
|
||||||
|
echo "<p>$icon You do not have permission for Permanent bans!</p>";
|
||||||
|
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 "<p>$icon Kban not found (it may have already been removed or is pending deletion).</p>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsAdminLoggedIn()) {
|
||||||
|
echo "<p>$icon You are not logged in.</p>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$admin->DoesHaveFullAccess() && $info['admin_steamid'] != $admin->adminSteamID) {
|
||||||
|
echo "<p>$icon You do not have permission to edit a kban issued by another admin.</p>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($playerName == $info['client_name'] && $playerSteamID == $info['client_steamid'] && $reason == $info['reason'] && $length == ($info['length'] * 60)) {
|
||||||
|
echo "<p>$icon Cannot detect any changes to edit!</p>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$kban->IsSteamIDAlreadyBanned($playerSteamID)) {
|
||||||
|
echo "<p>$icon The edited steamid is already kbanned and cannot be edited from here</p>";
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
?>
|
||||||
177
header.php
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
<?php
|
||||||
|
include_once('connect.php');
|
||||||
|
include_once('functions_global.php');
|
||||||
|
|
||||||
|
$ip = filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP) ? $_SERVER['REMOTE_ADDR'] : '';
|
||||||
|
|
||||||
|
$GLOBALS['steamID'] = "";
|
||||||
|
if(isset($_COOKIE['steamID']) && isset($_COOKIE['secret_key']) && $_COOKIE['secret_key'] === $GLOBALS['SECRET_KEY']) {
|
||||||
|
$GLOBALS['steamID'] = $_COOKIE['steamID'];
|
||||||
|
$admin = new Admin();
|
||||||
|
$admin->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();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>KnockBack Bans</title>
|
||||||
|
<link rel="icon" href="./images/favicon.ico" />
|
||||||
|
<link rel="stylesheet" href="css/style.css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,500,700,700i" rel="stylesheet" referrerpolicy="origin">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
|
||||||
|
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/4.2.0/mustache.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
|
||||||
|
<meta name="csrf-token" content="<?php echo htmlspecialchars($csrfToken, ENT_QUOTES, 'UTF-8'); ?>">
|
||||||
|
<script>window.CSRF_TOKEN = "<?php echo htmlspecialchars($csrfToken, ENT_QUOTES, 'UTF-8'); ?>";</script>
|
||||||
|
<script src="js/kbans.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="hide" style="display: none;"></div>
|
||||||
|
<div class="kban-action-window">
|
||||||
|
<div class="header">
|
||||||
|
<p id="action-header-text"></p>
|
||||||
|
</div>
|
||||||
|
<div class="info">
|
||||||
|
<ul class="kban_details">
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="info-footer">
|
||||||
|
<button class="button button-important" onclick="CloseWindow();">Close <i class='fa-solid fa-xmark'></i></button>
|
||||||
|
<button class="button button-success" onclick="GoHome();">Go To Kban List <i class='fa-solid fa-house'></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="search-modal-body">
|
||||||
|
<div class='search-modal'>
|
||||||
|
<div class='header'>
|
||||||
|
<p><i class='fa-solid fa-magnifying-glass'></i> Advanced Search</p>
|
||||||
|
<p class='search-modal-btn-close'><i class='fa-solid fa-xmark'></i></p>
|
||||||
|
</div>
|
||||||
|
<form method="GET">
|
||||||
|
<input id='hideInput' type='text' style='display: none;' name='' value='true'>
|
||||||
|
<div class='input-group' id='search-input-div'>
|
||||||
|
<label for='s'>Input</label>
|
||||||
|
<input class='input search-modal-input' type='text' name='s'>
|
||||||
|
</div>
|
||||||
|
<div class='input-group'>
|
||||||
|
<label for='m'>Method</label>
|
||||||
|
<select name='m' id='search-modal-select' class='select search-modal-input'>
|
||||||
|
<option value='1'>Player SteamID</option>
|
||||||
|
<option value='2'>Player Name</option>
|
||||||
|
<?php if(IsAdminLoggedIn() && $admin->DoesHaveFullAccess()) { ?>
|
||||||
|
<option value='3'>Player IP</option>
|
||||||
|
<?php } ?>
|
||||||
|
<option value='4'>Admin Name</option>
|
||||||
|
<option value='5'>Admin SteamID</option>
|
||||||
|
<?php if(str_contains($_SERVER['REQUEST_URI'], 'logs') == false) { ?>
|
||||||
|
<option value='6'>Map</option>
|
||||||
|
<option value="7">Length</option>
|
||||||
|
<?php } ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="length-group" style="display: none;">
|
||||||
|
<div class="input-group" style="display: flex !important; justify-content: center;">
|
||||||
|
<select name="length[]" class="select" style="float: right; order: 1; width: 50% !important;">
|
||||||
|
<option value="1">= (Equal to)</option>
|
||||||
|
<option value="2">> (Greater)</option>
|
||||||
|
<option value="3">< (Smaller)</option>
|
||||||
|
<option value="4">>= (Greater or equal to)</option>
|
||||||
|
<option value="5"><= (Smaller or equal to)</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select name="length[]" id="length-select" class="select" style="order: 2; float: left; width: 80%; margin-left: 10px;">
|
||||||
|
<?php GetKbanLengths(false); ?>
|
||||||
|
</select>
|
||||||
|
<input style="order: 3; width: 20%; display: none; margin-left: 10px;" type="number" class="input" name="custom" id="custom-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type='submit' class='button button-primary kban-form-button' style='width: 90%; margin-left: 5%;'><i class='fa-solid fa-magnifying-glass'></i> Search</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<header>
|
||||||
|
<div class="header1">
|
||||||
|
<div class="header1-icons">
|
||||||
|
<?php
|
||||||
|
echo '<a id="steam_group" target="_blank" href="'. $GLOBALS['STEAM_GROUP'] .'" rel="noopener" title="Our Steam Group">'
|
||||||
|
?>
|
||||||
|
<i class="fab fa-steam-symbol"></i>
|
||||||
|
</a>
|
||||||
|
<a id="discord" target="_blank" href="<?php echo $GLOBALS['DISCORD']; ?>" rel="noopener" data-ipstooltip="" _title="Join us on Discord">
|
||||||
|
<i class="fab fa-discord"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="login">
|
||||||
|
<?php
|
||||||
|
if(IsAdminLoggedIn()) {
|
||||||
|
?>
|
||||||
|
<p>Welcome, <a href=<?php echo "\"$adminURL\""; ?> target="_blank"><i class='fa-solid fa-user'></i> <?php echo $adminName; ?></a>
|
||||||
|
<a class="button button-important" href='logout.php'><i class='fas fa-sign-out-alt'></i>
|
||||||
|
Logout</a></p>
|
||||||
|
<?php } else { ?>
|
||||||
|
<a class="button button-success" href='login-init.php'>Existing user? Sign In</a>
|
||||||
|
<?php } ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="header2">
|
||||||
|
<?php
|
||||||
|
echo '<a class="logo" href="'. $GLOBALS['SERVER_FORUM_URL'] .'">'
|
||||||
|
?>
|
||||||
|
<img src="./images/kbans.png" alt="logo">
|
||||||
|
</a>
|
||||||
|
<div class="search_input">
|
||||||
|
<form method="GET" action="index.php">
|
||||||
|
<input type='text' style='display: none;' name='all' value='true'>
|
||||||
|
<input type="text" class="input input-header-search" placeholder="Search SteamID..." name='s' required>
|
||||||
|
<input type='text' style='display: none;' name='m' value='1'>
|
||||||
|
<button id="search_icon"><i class="fa-solid fa-magnifying-glass"></i></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div class="body_content">
|
||||||
|
<div class="header3">
|
||||||
|
<ul>
|
||||||
|
<li><a class="not-active" id="allKbans" href="index.php?all"><i class="fa-solid fa-house"></i>  All Kbans</a></li>
|
||||||
|
<li><a class="not-active" id="activeKbans" href="index.php?active"><i class="fa-solid fa-hourglass-half"></i>  Active Kbans</a></li>
|
||||||
|
<li><a class="not-active" id="expiredKbans" href="index.php?expired"><i class="fa-solid fa-hourglass-end"></i>  Expired Kbans</a></li>
|
||||||
|
<?php
|
||||||
|
if(IsAdminLoggedIn()) {
|
||||||
|
echo "<li><a id='addkban' class='not-active' id='add' href='manage.php?add'><i class='fas fa-user-times'></i>  Add Kban</a></li>";
|
||||||
|
$admin = new Admin();
|
||||||
|
$admin->UpdateAdminInfo($_COOKIE['steamID']);
|
||||||
|
if($admin->DoesHaveFullAccess()) {
|
||||||
|
?>
|
||||||
|
<li><a class="not-active" id="weblogs" href="logs.php?web"><i class='far fa-hdd'></i>  Web Logs</a></li>
|
||||||
|
<li><a class="not-active" id="srvlogs" href="logs.php?srv"><i class="fa-solid fa-server"></i>  Server Logs</a></li>
|
||||||
|
<?php } ?>
|
||||||
|
<?php } ?>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
$('#search-modal-select').on('change', ()=>{
|
||||||
|
let val = $('#search-modal-select').val();
|
||||||
|
$('#length-group').css('display', (val == 7)?"block":"none");
|
||||||
|
$('#search-input-div').css('display', (val == 7)?"none":"block");
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#length-select').on('change', ()=>{
|
||||||
|
let val = $('#length-select').val();
|
||||||
|
$('#custom-input').css('display', (val == -2)?"block":"none");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
BIN
images/banner.png
Executable file
|
After Width: | Height: | Size: 50 KiB |
BIN
images/country/ad.jpg
Normal file
|
After Width: | Height: | Size: 504 B |
BIN
images/country/ae.jpg
Normal file
|
After Width: | Height: | Size: 491 B |
BIN
images/country/af.jpg
Normal file
|
After Width: | Height: | Size: 509 B |
BIN
images/country/ag.jpg
Normal file
|
After Width: | Height: | Size: 522 B |
BIN
images/country/ai.jpg
Normal file
|
After Width: | Height: | Size: 520 B |
BIN
images/country/al.jpg
Normal file
|
After Width: | Height: | Size: 489 B |
BIN
images/country/am.jpg
Normal file
|
After Width: | Height: | Size: 489 B |
BIN
images/country/an.jpg
Normal file
|
After Width: | Height: | Size: 519 B |
BIN
images/country/ao.jpg
Normal file
|
After Width: | Height: | Size: 492 B |
BIN
images/country/ar.jpg
Normal file
|
After Width: | Height: | Size: 481 B |
BIN
images/country/as.jpg
Normal file
|
After Width: | Height: | Size: 530 B |
BIN
images/country/at.jpg
Normal file
|
After Width: | Height: | Size: 478 B |
BIN
images/country/au.jpg
Normal file
|
After Width: | Height: | Size: 521 B |
BIN
images/country/aw.jpg
Normal file
|
After Width: | Height: | Size: 487 B |
BIN
images/country/ax.jpg
Normal file
|
After Width: | Height: | Size: 520 B |
BIN
images/country/az.jpg
Normal file
|
After Width: | Height: | Size: 499 B |
BIN
images/country/ba.jpg
Normal file
|
After Width: | Height: | Size: 529 B |
BIN
images/country/bb.jpg
Normal file
|
After Width: | Height: | Size: 513 B |
BIN
images/country/bd.jpg
Normal file
|
After Width: | Height: | Size: 506 B |
BIN
images/country/be.jpg
Normal file
|
After Width: | Height: | Size: 492 B |
BIN
images/country/bf.jpg
Normal file
|
After Width: | Height: | Size: 488 B |
BIN
images/country/bg.jpg
Normal file
|
After Width: | Height: | Size: 479 B |
BIN
images/country/bh.jpg
Normal file
|
After Width: | Height: | Size: 484 B |
BIN
images/country/bi.jpg
Normal file
|
After Width: | Height: | Size: 535 B |
BIN
images/country/bj.jpg
Normal file
|
After Width: | Height: | Size: 487 B |
BIN
images/country/bm.jpg
Normal file
|
After Width: | Height: | Size: 502 B |
BIN
images/country/bn.jpg
Normal file
|
After Width: | Height: | Size: 511 B |
BIN
images/country/bo.jpg
Normal file
|
After Width: | Height: | Size: 480 B |
BIN
images/country/br.jpg
Normal file
|
After Width: | Height: | Size: 535 B |
BIN
images/country/bs.jpg
Normal file
|
After Width: | Height: | Size: 504 B |
BIN
images/country/bt.jpg
Normal file
|
After Width: | Height: | Size: 502 B |
BIN
images/country/bv.jpg
Normal file
|
After Width: | Height: | Size: 515 B |
BIN
images/country/bw.jpg
Normal file
|
After Width: | Height: | Size: 482 B |
BIN
images/country/by.jpg
Normal file
|
After Width: | Height: | Size: 502 B |
BIN
images/country/bz.jpg
Normal file
|
After Width: | Height: | Size: 521 B |
BIN
images/country/ca.jpg
Normal file
|
After Width: | Height: | Size: 504 B |
BIN
images/country/catalonia.jpg
Normal file
|
After Width: | Height: | Size: 455 B |
BIN
images/country/cc.jpg
Normal file
|
After Width: | Height: | Size: 507 B |
BIN
images/country/cd.jpg
Normal file
|
After Width: | Height: | Size: 549 B |
BIN
images/country/cf.jpg
Normal file
|
After Width: | Height: | Size: 513 B |
BIN
images/country/cg.jpg
Normal file
|
After Width: | Height: | Size: 505 B |
BIN
images/country/ch.jpg
Normal file
|
After Width: | Height: | Size: 508 B |
BIN
images/country/ci.jpg
Normal file
|
After Width: | Height: | Size: 481 B |
BIN
images/country/ck.jpg
Normal file
|
After Width: | Height: | Size: 516 B |
BIN
images/country/cl.jpg
Normal file
|
After Width: | Height: | Size: 497 B |
BIN
images/country/cm.jpg
Normal file
|
After Width: | Height: | Size: 488 B |
BIN
images/country/cn.jpg
Normal file
|
After Width: | Height: | Size: 479 B |
BIN
images/country/co.jpg
Normal file
|
After Width: | Height: | Size: 484 B |
BIN
images/country/cr.jpg
Normal file
|
After Width: | Height: | Size: 497 B |
BIN
images/country/cs.jpg
Normal file
|
After Width: | Height: | Size: 488 B |
BIN
images/country/cu.jpg
Normal file
|
After Width: | Height: | Size: 520 B |
BIN
images/country/cv.jpg
Normal file
|
After Width: | Height: | Size: 512 B |
BIN
images/country/cx.jpg
Normal file
|
After Width: | Height: | Size: 523 B |
BIN
images/country/cy.jpg
Normal file
|
After Width: | Height: | Size: 446 B |
BIN
images/country/cz.jpg
Normal file
|
After Width: | Height: | Size: 497 B |
BIN
images/country/de.jpg
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
images/country/dj.jpg
Normal file
|
After Width: | Height: | Size: 499 B |
BIN
images/country/dk.jpg
Normal file
|
After Width: | Height: | Size: 489 B |
BIN
images/country/dm.jpg
Normal file
|
After Width: | Height: | Size: 528 B |
BIN
images/country/do.jpg
Normal file
|
After Width: | Height: | Size: 524 B |
BIN
images/country/dz.jpg
Normal file
|
After Width: | Height: | Size: 482 B |
BIN
images/country/ec.jpg
Normal file
|
After Width: | Height: | Size: 493 B |
BIN
images/country/ee.jpg
Normal file
|
After Width: | Height: | Size: 480 B |
BIN
images/country/eg.jpg
Normal file
|
After Width: | Height: | Size: 491 B |
BIN
images/country/eh.jpg
Normal file
|
After Width: | Height: | Size: 517 B |
BIN
images/country/england.jpg
Normal file
|
After Width: | Height: | Size: 493 B |
BIN
images/country/er.jpg
Normal file
|
After Width: | Height: | Size: 520 B |
BIN
images/country/es.jpg
Normal file
|
After Width: | Height: | Size: 489 B |
BIN
images/country/et.jpg
Normal file
|
After Width: | Height: | Size: 505 B |
BIN
images/country/europeanunion.jpg
Normal file
|
After Width: | Height: | Size: 462 B |
BIN
images/country/fam.jpg
Normal file
|
After Width: | Height: | Size: 481 B |
BIN
images/country/fi.jpg
Normal file
|
After Width: | Height: | Size: 500 B |
BIN
images/country/fj.jpg
Normal file
|
After Width: | Height: | Size: 529 B |
BIN
images/country/fk.jpg
Normal file
|
After Width: | Height: | Size: 507 B |
BIN
images/country/fm.jpg
Normal file
|
After Width: | Height: | Size: 492 B |
BIN
images/country/fo.jpg
Normal file
|
After Width: | Height: | Size: 502 B |
BIN
images/country/fr.jpg
Normal file
|
After Width: | Height: | Size: 485 B |
BIN
images/country/ga.jpg
Normal file
|
After Width: | Height: | Size: 501 B |
BIN
images/country/gb.jpg
Normal file
|
After Width: | Height: | Size: 546 B |
BIN
images/country/gd.jpg
Normal file
|
After Width: | Height: | Size: 515 B |
BIN
images/country/ge.jpg
Normal file
|
After Width: | Height: | Size: 499 B |
BIN
images/country/gf.jpg
Normal file
|
After Width: | Height: | Size: 485 B |
BIN
images/country/gh.jpg
Normal file
|
After Width: | Height: | Size: 508 B |
BIN
images/country/gi.jpg
Normal file
|
After Width: | Height: | Size: 491 B |
BIN
images/country/gl.jpg
Normal file
|
After Width: | Height: | Size: 496 B |
BIN
images/country/gm.jpg
Normal file
|
After Width: | Height: | Size: 496 B |
BIN
images/country/gn.jpg
Normal file
|
After Width: | Height: | Size: 490 B |
BIN
images/country/gp.jpg
Normal file
|
After Width: | Height: | Size: 483 B |
BIN
images/country/gq.jpg
Normal file
|
After Width: | Height: | Size: 507 B |
BIN
images/country/gr.jpg
Normal file
|
After Width: | Height: | Size: 498 B |