initial comit of repository

This commit is contained in:
jenz
2026-08-12 15:35:36 +02:00
commit 8ede019d8f
21 changed files with 4392 additions and 0 deletions
+477
View 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
+9
View File
@@ -0,0 +1,9 @@
# Features
- Displays EntWatch database records on a website.
- Supports desktop and mobile layouts.
- Supports SteamID search.
- Includes multilingual support.
- Supports SourceBans login.
- Keeps logs for eban removal.
- Allows eban duration editing.
- Supports multiple themes.
+43
View File
@@ -0,0 +1,43 @@
<?php
define('SERVER_FORUM_NAME', 'mywebsite');
define('SERVER_FORUM_URL', 'https://mywebsite.com');
define('SERVER_NAME', 'My server');
define('STEAM_GROUP', 'https://steamcommunity.com/groups/mysteamgroup');
define('STEAM_API_KEY', 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
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('SBPP_DB_PREFIX', 'sb'); // The table prefix for SourceBans
define('SBPP_DB_PORT', '3306'); // The SQL port (Default: 3306)
define('SBPP_DB_CHARSET', 'utf8mb4'); // The Database charset (Default: utf8)
define('SB_NEW_SALT', '$5$'); //Salt for passwords
define('SECRET_KEY', 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'); // Used to prevent cookies injection
define('DATE_TIME_ZONE', 'GMT+2');
define('DATE_TIME_FORMAT', 'Y-m-d H:i:s');
define('GID_STAFF', [2, 5, 7]); // Group ID of staff in sb_groups
define('GID_ADMIN', [11]); // Group ID of server admins in sb_groups
define('EBAN_DB_HOST', '127.0.0.1'); // The host/ip to your SQL server
define('EBAN_DB_USER', 'example'); // The username to connect with
define('EBAN_DB_PASSWORD', 'example'); // The password
define('EBAN_DB_NAME', 'example'); // Database name
define('EBAN_DB_PORT', '3306'); // The SQL port (Default: 3306)
define('EBAN_DB_CHARSET', 'utf8'); // The Database charset (Default: utf8)
define('EBAN_DB_PREFIX', ''); // The table prefix for EBans
define('DB_HOST_sqlite_cookies', '');
define('DB_USER_sqlite_cookies', '');
define('DB_PASSWORD_sqlite_cookies', '');
define('DB_NAME_sqlite_cookies', '');
define('DB_HOST_PLAYTIME', '');
define('DB_USER_PLAYTIME', '');
define('DB_PASSWORD_PLAYTIME', '');
define('DB_NAME_PLAYTIME', '');
?>
+73
View File
@@ -0,0 +1,73 @@
<?php
// ---------------------------------------------------
// Directories
// ---------------------------------------------------
define('ROOT', dirname(__FILE__) . "/");
if (!file_exists(ROOT.'/config.php')) {
die('Missing config.php.');
}
require_once(ROOT.'/config.php');
// PHP 8.1+ makes mysqli throw an exception on connection failure instead of
// returning false - restore the old behavior so the die() checks below
// actually get a chance to run and show a real error instead of a blank 500.
mysqli_report(MYSQLI_REPORT_OFF);
$GLOBALS['DB'] = mysqli_connect(
EBAN_DB_HOST,
EBAN_DB_USER,
EBAN_DB_PASSWORD,
EBAN_DB_NAME
);
// Check Eban 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['DB_COOKIES'] = mysqli_connect(
DB_HOST_sqlite_cookies,
DB_USER_sqlite_cookies,
DB_PASSWORD_sqlite_cookies,
DB_NAME_sqlite_cookies);
// Check Cookie Cache DB connection
if (!$GLOBALS['DB_COOKIES']) {
die('Cookie Cache 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['STEAM_API_KEY'] = STEAM_API_KEY;
$GLOBALS['STEAM_GROUP'] = STEAM_GROUP;
$GLOBALS['SECRET_KEY'] = SECRET_KEY;
/* TIME ZONE */
date_default_timezone_set('UTC');
?>
+1272
View File
File diff suppressed because it is too large Load Diff
+13
View 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-EntWatch" title="EntWatch Repository" target="_blank" rel="noopener">EntWatch</a></p>
<p>This Website is open source, check it out <a href="https://github.com/srcdslab/ebans-web" title="Ebans website Repository" target="_blank" rel="noopener">here</a></p>
</div>
</div>
</footer>
+894
View File
@@ -0,0 +1,894 @@
<?php
include_once('steam.php');
class Utility {
public static function sanitizeInput($input) {
$replacements = array("'", '"', "\\", ";", "`", "--", "#", "=", ">", "<", "&", "%", "|", "^", "~", "(", ")");
return str_replace($replacements, "", $input);
}
}
class Admin {
public $adminID = -1;
public $adminGroupID = -1;
public $adminSteamID = "";
public $adminUser = "";
public function getAdminIDFromName($name) {
$name = $GLOBALS['SBPP']->real_escape_string($name);
$query = "SELECT `aid` FROM `sb_admins` WHERE `user` LIKE '%$name%'";
$queryHndl = $GLOBALS['SBPP']->query($query);
if ($queryHndl) {
$result = $queryHndl->fetch_assoc();
$queryHndl->free_result();
if ($result) {
return $result['aid'];
}
} else {
die(); // Database error
}
return -1; // No matching admin found
}
public function GetAdminNameFromSteamID($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 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();
$sbppaid = $row['aid'];
// Compare the cookie 'aid' with the result from the query
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) {
$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 DoesHaveFullAccess() {
if (!isset($_COOKIE['steamID'])) {
return false;
}
// acceptatable group ids
$groups = array(1, 3, 4);
if (in_array($this->adminGroupID, $groups)) {
return true;
}
return false;
}
}
class Eban {
public function UnbanByID($id, $reasonA) {
if (!isset($_COOKIE['steamID'])) { // This should never happen, but just to be safe
return false;
}
if (empty($reasonA)) {
$reasonA = "No Reason";
}
$reason = Utility::sanitizeInput($reasonA);
$admin = new Admin();
$admin->UpdateAdminInfo($_COOKIE['steamID']);
$adminName = $admin->adminUser;
$adminSteamID = $admin->adminSteamID;
$Eban = new Eban();
$resultsB = $Eban->getEbanInfoFromID($id);
$playerName = $resultsB['client_name'];
$playerSteamID = $resultsB['client_steamid'];
$length = $resultsB['duration'];
// Single UPDATE: record who unbanned it, mark it inactive. No more
// moving rows between tables - EntWatch_Old_Eban is retired.
$sql = "UPDATE `EntWatch_Current_Eban` SET `admin_name_unban` = ?, `admin_steamid_unban` = ?, `reason_unban` = ?, `timestamp_unban` = ?, `is_expired` = 1 WHERE `id` = ?";
$stmt = $GLOBALS['DB']->prepare($sql);
$time_unban = time();
$stmt->bind_param("sssii", $adminName, $adminSteamID, $reason, $time_unban, $id);
$stmt->execute();
$stmt->close();
// Lift the restriction in-game immediately, matching what the
// plugin's own ClientUnrestrict() does when it processes this.
$this->ZeroRestrictCookies($playerSteamID);
$time = time();
// Log the action, but don't let a logging failure block the unban
// itself from completing successfully - just record it and move on.
$sql = "INSERT INTO `web_logs` (`message`, `admin_name`, `admin_steamid`, `client_name`, `client_steamid`, `time_stamp`)
VALUES (?, ?, ?, ?, ?, ?)";
$message = "Eban Removed (was $length minutes. Reason: $reason)";
if ($stmt = $GLOBALS['DB']->prepare($sql)) {
$stmt->bind_param("sssssi", $message, $adminName, $adminSteamID, $playerName, $playerSteamID, $time);
$stmt->execute();
$stmt->close();
} else {
error_log("web_logs prepare error: " . $GLOBALS['DB']->error);
}
echo "<script>showEbanWindowInfo(2, \"$playerName\", \"$playerSteamID\", \"$reason\");</script>";
return true;
}
public function RemoveEbanFromDB($id) {
$admin = new Admin();
$adminSteamID = (isset($_COOKIE['steamID']) ? $_COOKIE['steamID'] : "");
$admin->UpdateAdminInfo($adminSteamID);
if (!IsAdminLoggedIn() || !$admin->DoesHaveFullAccess()) {
return false;
}
$resultsC = $this->getEbanInfoFromID($id);
$playerName = $resultsC['client_name'];
$playerSteamID = $resultsC['client_steamid'];
$length = $resultsC['duration'];
$reason = $resultsC['reason'];
$isExpired = ($resultsC['is_expired'] == 1) ? true : false;
$isRemoved = ($resultsC['admin_steamid_unban'] != "" && $resultsC['admin_steamid_unban'] != "SERVER") ? true : false;
$status = "Active";
if ($isExpired && !$isRemoved) {
$status = "Expired";
}
if ($isRemoved) {
$status = "Removed";
}
$message = "Eban Deleted (Player Name: $playerName, Player SteamID: $playerSteamID, was $length minutes. Issued for: $reason. Eban was $status)";
// Use prepared statement for DELETE - only one table now
$sql = "DELETE FROM `EntWatch_Current_Eban` WHERE `id` = ?";
$stmt = $GLOBALS['DB']->prepare($sql);
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
// Only touch the cookie cache if this row was actually the player's
// current active restriction. A client can only have one active ban
// at a time - deleting an already-expired/unbanned historical row
// must not zero out cookies that may belong to a newer, still-active
// restriction for the same player.
if (!$isExpired && !$isRemoved) {
$this->ZeroRestrictCookies($playerSteamID);
}
$adminName = $admin->adminUser;
$time = time();
// Log the action, but don't let a logging failure block the delete
// itself from completing successfully - just record it and move on.
$sql = "INSERT INTO `web_logs` (`message`, `admin_name`, `admin_steamid`, `client_name`, `client_steamid`, `time_stamp`)
VALUES (?, ?, ?, ?, ?, ?)";
if ($stmt = $GLOBALS['DB']->prepare($sql)) {
$stmt->bind_param("sssssi", $message, $adminName, $adminSteamID, $playerName, $playerSteamID, $time);
$stmt->execute();
$stmt->close();
} else {
error_log("web_logs prepare error: " . $GLOBALS['DB']->error);
}
echo "<script>showEbanWindowInfo(3, \"$playerName\", \"$playerSteamID\", \"$reason\", \"$length minutes\", $id);</script>";
}
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, same source kbans uses. Returns 0
// if the player has no playtime record (e.g. has never connected).
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();
// ze_time is stored in seconds in this table - convert to minutes
// here so every caller can keep working in flat minutes.
return $row ? intval($row['ze_time_total'] / 60) : 0;
}
// Pushes Issued/Expire/Length into the sourcemod plugin's own cookie
// cache, so the in-game restriction actually reflects what was set via
// the web panel. Uses INSERT ... ON DUPLICATE KEY UPDATE since a brand
// new player may have none of these cookie rows cached yet at all - a
// plain UPDATE would silently touch zero rows in that case. Requires
// sm_cookie_cache's standard (player, cookie_id) unique/primary key.
public function SyncRestrictCookies($steamID, $lengthInMinutes, $time_played_start, $time_played_end) {
$time = time();
if ($lengthInMinutes == 0) {
// Permanent - mirrors the plugin's own permanent-ban cookie
// behavior: Issued just needs to be a truthy value, and
// Expire=0 is the sentinel ClientRestricted() checks for.
$issued_hours = $time;
$issued_minutes = 0;
$expire_hours = 0;
$expire_minutes = 0;
$length_hours = 0;
$length_minutes = 0;
} else {
$issued_hours = intdiv($time_played_start, 60);
$issued_minutes = $time_played_start % 60;
$expire_hours = intdiv($time_played_end, 60);
$expire_minutes = $time_played_end % 60;
$length_hours = intdiv($lengthInMinutes, 60);
$length_minutes = $lengthInMinutes % 60;
}
$cookies = [
2 => $issued_hours, // EW_RestrictIssued
195721 => $issued_minutes, // EW_RestrictIssued_minutes
3 => $expire_hours, // EW_RestrictExpire
195723 => $expire_minutes, // EW_RestrictExpire_minutes
4 => $length_hours, // EW_RestrictLength
195725 => $length_minutes, // EW_RestrictLength_minutes
];
$sql = "INSERT INTO `sm_cookie_cache` (`player`, `cookie_id`, `value`, `timestamp`)
VALUES (?, ?, ?, ?)
ON DUPLICATE KEY UPDATE `value` = VALUES(`value`), `timestamp` = VALUES(`timestamp`)";
$stmt = $GLOBALS['DB_COOKIES']->prepare($sql);
foreach ($cookies as $cookieID => $value) {
$valueStr = strval($value);
$stmt->bind_param("sisi", $steamID, $cookieID, $valueStr, $time);
$stmt->execute();
}
$stmt->close();
}
// Zeroes out all six EW_Restrict* cookies for a player, matching exactly
// what the sourcemod plugin's own ClientUnrestrict() does. Used by
// UnbanByID() and RemoveEbanFromDB() so the in-game restriction lifts
// immediately, rather than waiting for the plugin's own polling.
public function ZeroRestrictCookies($steamID) {
$time = time();
$cookieIDs = [2, 195721, 3, 195723, 4, 195725];
$sql = "INSERT INTO `sm_cookie_cache` (`player`, `cookie_id`, `value`, `timestamp`)
VALUES (?, ?, '0', ?)
ON DUPLICATE KEY UPDATE `value` = '0', `timestamp` = VALUES(`timestamp`)";
$stmt = $GLOBALS['DB_COOKIES']->prepare($sql);
foreach ($cookieIDs as $cookieID) {
$stmt->bind_param("sii", $steamID, $cookieID, $time);
$stmt->execute();
}
$stmt->close();
}
public function formatLength($seconds) {
/* if less than one minute */
if ($seconds == 0) {
return "Permanent";
}
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 getEbanInfoFromID($id) {
$sql = "SELECT * FROM `EntWatch_Current_Eban` WHERE `id`=?";
$stmt = $GLOBALS['DB']->prepare($sql);
$stmt->bind_param("i", $id);
$stmt->execute();
$query = $stmt->get_result();
$results = $query->fetch_all(MYSQLI_ASSOC);
$query->free();
foreach ($results as $result) {
return $result;
}
}
public function GetEbansNumber($steamID) {
$search = $steamID;
$searchMethod = "client_steamid";
$sql = "SELECT * FROM `EntWatch_Current_Eban` WHERE `$searchMethod`=?";
$stmt = $GLOBALS['DB']->prepare($sql);
$stmt->bind_param("s", $search);
$stmt->execute();
$queryA = $stmt->get_result();
$rows = $queryA->num_rows;
$queryA->free();
return $rows;
}
public function GetRealEbansNumber($steamID) {
$search = $steamID;
$searchMethod = "client_steamid";
// "Real" ebans = still active, auto-expired, or expired-and-archived -
// excludes bans an admin manually removed for a non-expiry reason
// (e.g. pardons), same distinction the old two-table version made.
$sql = "SELECT * FROM `EntWatch_Current_Eban` WHERE `$searchMethod`=? AND (`admin_steamid_unban` IS NULL OR `admin_steamid_unban` = '' OR `admin_steamid_unban` = 'SERVER' OR `reason_unban` = 'Expired')";
$stmt = $GLOBALS['DB']->prepare($sql);
$stmt->bind_param("s", $search);
$stmt->execute();
$queryA = $stmt->get_result();
$rows = $queryA->num_rows;
$queryA->free();
return $rows;
}
public function addNewEban($playerNameA, $playerSteamID, $length, $reasonA) {
$admin = new Admin();
$admin->UpdateAdminInfo($_COOKIE['steamID']);
$adminName = $admin->adminUser;
$adminSteamID = $admin->adminSteamID;
$adminID = $admin->adminID;
$playerName = Utility::sanitizeInput($playerNameA);
$reason = Utility::sanitizeInput($reasonA);
$lengthInMinutes = ($length / 60);
if ($length <= -1) {
$lengthInMinutes = 30;
} elseif ($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);
}
// Prepare and execute INSERT INTO EntWatch_Current_Eban
// time_stamp_start uses the column's own DEFAULT current_timestamp().
// server is hardcoded here since the column no longer exists on this table.
$sql = "INSERT INTO `EntWatch_Current_Eban`
(`client_name`, `client_steamid`, `admin_name`, `admin_steamid`, `reason`, `duration`, `time_played_start`, `time_played_end`, `is_expired`)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0)";
if ($stmt = $GLOBALS['DB']->prepare($sql)) {
$stmt->bind_param("sssssiii", $playerName, $playerSteamID, $adminName, $adminSteamID, $reason, $lengthInMinutes, $time_played_start, $time_played_end);
if (!$stmt->execute()) {
error_log("Database error: " . $stmt->error);
die("Database error occurred.");
}
$stmt->close();
} else {
error_log("Database prepare error: " . $GLOBALS['DB']->error);
die("Database prepare error occurred.");
}
// Push the same Issued/Expire/Length values into the sourcemod
// plugin's own cookie cache, so the in-game restriction matches
// what was just written to EntWatch_Current_Eban.
$this->SyncRestrictCookies($playerSteamID, $lengthInMinutes, $time_played_start, $time_played_end);
echo "<script>showEbanWindowInfo(0, \"" . htmlspecialchars($playerName, ENT_QUOTES, 'UTF-8') . "\", \"" . htmlspecialchars($playerSteamID, ENT_QUOTES, 'UTF-8') . "\", \"" . htmlspecialchars($reason, ENT_QUOTES, 'UTF-8') . "\", \"$lengthInMinutes minutes\");</script>";
}
public function EditEban($id, $playerNameA, $playerSteamID, $length, $reasonA) {
$admin = new Admin();
$admin->UpdateAdminInfo($_COOKIE['steamID']);
$adminName = $admin->adminUser;
$adminSteamID = $admin->adminSteamID;
// Escape single quotes by removing them
$playerName = Utility::sanitizeInput($playerNameA);
$reason = Utility::sanitizeInput($reasonA);
$lengthInMinutes = ($length / 60);
$info = $this->getEbanInfoFromID($id);
if ($length <= -1) {
$lengthInMinutes = 30;
} elseif ($length == 0) {
$lengthInMinutes = 0;
}
$time_played_start = intval($info['time_played_start']);
if ($lengthInMinutes <= 0) {
// Permanent (or zero-length) - no baseline, no expiry threshold
$time_played_start = -1;
$time_played_end = -1;
} else if ($time_played_start == -1) {
// Converting from permanent/unbaselined to temporary - there's no
// existing baseline to build on, so establish a fresh one now,
// the same way a brand new eban does.
$time_played_start = $this->GetPlaytimeMinutes($playerSteamID);
$time_played_end = ($time_played_start + $lengthInMinutes);
} else {
$time_played_end = ($time_played_start + $lengthInMinutes);
}
// time_played_start is normally left untouched on an edit - it's the
// plugin's own baseline. The one exception (handled above) is
// converting a permanent/unbaselined ban into a temporary one, where
// there was never a real baseline to preserve in the first place.
$sql = "UPDATE `EntWatch_Current_Eban` SET `client_name` = ?, `client_steamid` = ?, `reason` = ?, `duration` = ?, `time_played_start` = ?, `time_played_end` = ?, `is_expired` = 0 WHERE `id` = ?";
$stmt = $GLOBALS['DB']->prepare($sql);
$stmt->bind_param("sssiiii", $playerName, $playerSteamID, $reason, $lengthInMinutes, $time_played_start, $time_played_end, $id);
$stmt->execute();
$stmt->close();
// Push the updated duration/expiry into the plugin's cookie cache
// too, otherwise the new duration set here has no effect in-game.
$this->SyncRestrictCookies($playerSteamID, $lengthInMinutes, $time_played_start, $time_played_end);
echo "<script>showEbanWindowInfo(1, \"$playerName\", \"$playerSteamID\", \"$reason\", \"$lengthInMinutes minutes\");</script>";
//echo "<script>window.location.replace('index.php?all');</script>";
}
public function IsSteamIDAlreadyBanned($steamID) {
$sql = "SELECT * FROM `EntWatch_Current_Eban` WHERE `client_steamid`=?";
$stmt = $GLOBALS['DB']->prepare($sql);
$stmt->bind_param("s", $steamID);
$stmt->execute();
$query = $stmt->get_result();
$results = $query->fetch_all(MYSQLI_ASSOC);
$query->free();
foreach ($results as $result) {
$isActive = ($result['is_expired'] == 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 formatMethod(int $method) {
$methods = ["", "client_steamid", "client_name", "", "admin_name", "admin_steamid"];
return $methods[$method];
}
function GetRowInfo($id, $result2 = null) {
$admin = new Admin();
$Eban = new Eban();
if ($id != 0) {
$result2 = $Eban->getEbanInfoFromID($id);
} else {
$id = $result2['id'];
}
$clientName = $result2['client_name'];
$clientSteamID = $result2['client_steamid'];
$adminSteamID = $result2['admin_steamid'];
$reason = $result2['reason'];
$time_stamp_start = strtotime($result2['time_stamp_start']);
$duration = $result2['duration'];
$time_played_start = intval($result2['time_played_start']);
$isExpired = ($result2['is_expired'] == 1) ? true : false;
$timestamp_unban = $result2['timestamp_unban'];
$adminNameRemoved = $result2['admin_name_unban'];
$adminSteamIDRemoved = $result2['admin_steamid_unban'];
$timestamp_unban = $result2['timestamp_unban'];
$reason_unban = $result2['reason_unban'];
$adminName = $admin->GetAdminNameFromSteamID($adminSteamID);
$isRemoved = ($adminSteamIDRemoved != "" && $adminSteamIDRemoved != "SERVER") ? true : false;
$isPermanent = ($duration == 0);
if ($isPermanent) {
$length = "Permanent";
$startedOn = "N/A";
$expiresOn = "Never";
} else {
$length = $Eban->formatPlaytime($duration);
$startedOn = $Eban->formatPlaytime($time_played_start) . " played";
$expiresOn = $Eban->formatPlaytime($time_played_start + $duration) . " played";
}
$status = "Eban Active";
if ($isExpired && !$isRemoved) {
$status = "Eban Expired";
}
if ($isRemoved) {
$status = "Eban Removed";
}
echo "<div class='Eban-buttons'>";
$href = "ViewPlayerHistory(\"$clientSteamID\", 1);";
echo "<button onclick='$href' class='button button-light' title='View History'><i class='fa-solid fa-clock-rotate-left'></i>&nbspView 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>&nbspEdit 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>&nbspUnban</button>";
}
} else {
if (!$Eban->IsSteamIDAlreadyBanned($clientSteamID)) {
$reBanFunction = "RebanFromID(\"$id\");";
echo "<button class='button button-important' title='Reban' onclick='$reBanFunction'><i class='fas fa-redo fa-lg'></i>&nbspReban</button>";
}
}
}
if ($admin->DoesHaveFullAccess()) {
$deleteFunction = "RemoveEbanFromDBCheck($id);";
echo "<button class='button button-important' title='Delete' onclick='$deleteFunction'><i class='fa-solid fa-trash'></i>&nbspDelete Eban</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='Eban_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>";
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> Eban 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> Eban Status</span>";
echo "<span>$status</span>";
echo "</li>";
if ($isRemoved) {
$date->setTimestamp($timestamp_unban);
$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_unban</span>";
echo "</li>";
}
echo "</ul>";
}
function GetEbanLengths() {
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>";
echo "<optgroup label='Others'>";
echo "<option value='0'>Permanent</option>";
echo "</optgroup>";
echo "</select>";
}
function GetEbanLengthTypes() {
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>";
}
?>
+215
View File
@@ -0,0 +1,215 @@
<?php
include_once('connect.php');
include_once('functions_global.php');
function sanitizeString($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 (isset($_GET['id']) && !isset($_GET['reban']) && !isset($_GET['edit'])) {
$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT);
showEbanInfo($id);
}
if (isset($_GET['oldid']) && !isset($_GET['reban']) && !isset($_GET['edit'])) {
$icon = "<i class='fa-solid fa-xmark'></i>&nbsp";
if (!isset($_COOKIE['steamID'])) {
echo "<p>$icon You are not logged in. Please log in again.</p>";
die();
}
$admin = new Admin();
$admin->UpdateAdminInfo($_COOKIE['steamID']);
$id = filter_input(INPUT_GET, 'oldid', FILTER_SANITIZE_NUMBER_INT);
$Eban = new Eban();
$info = $Eban->getEbanInfoFromID($id);
if ($info === null) {
echo "<p>$icon Eban not found.</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 unban an eban issued by another admin.</p>";
die();
}
$reason = sanitizeString($reason);
$Eban = new Eban();
if (!$Eban->UnbanByID($id, $reason)) {
echo "<p>$icon Failed to unban.</p>";
die();
}
die();
}
function showEbanInfo(int $id) {
GetRowInfo($id);
}
if (isset($_GET['add']) && isset($_GET['playerName'])) {
if (!IsAdminLoggedIn()) {
echo "<p><i class='fa-solid fa-xmark'></i>&nbsp You are not logged in.</p>";
die();
}
// Sanitize input
$playerName = sanitizeString(filter_input(INPUT_GET, 'playerName', FILTER_SANITIZE_STRING));
$playerSteamID = filter_input(INPUT_GET, 'playerSteamID', FILTER_SANITIZE_STRING);
$length = filter_input(INPUT_GET, 'length', FILTER_SANITIZE_NUMBER_INT);
$reason = sanitizeString(filter_input(INPUT_GET, 'reason', FILTER_SANITIZE_STRING));
$icon = "<i class='fa-solid fa-xmark'></i>&nbsp";
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();
}
$Eban = new Eban();
if ($Eban->IsSteamIDAlreadyBanned($playerSteamID)) {
echo "<p>$icon $playerSteamID is already Ebanned!</p>";
die();
}
$Eban->addNewEban($playerName, $playerSteamID, $length, $reason);
}
if (isset($_GET['edit']) && isset($_GET['playerName'])) {
if (!isset($_COOKIE['steamID'])) {
echo "<p><i class='fa-solid fa-xmark'></i>&nbsp You are not logged in.</p>";
die();
}
$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT);
$playerName = sanitizeString(filter_input(INPUT_GET, 'playerName', FILTER_SANITIZE_STRING));
$playerSteamID = filter_input(INPUT_GET, 'playerSteamID', FILTER_SANITIZE_STRING);
$length = filter_input(INPUT_GET, 'length', FILTER_SANITIZE_NUMBER_INT);
$reason = sanitizeString(filter_input(INPUT_GET, 'reason', FILTER_SANITIZE_STRING));
$icon = "<i class='fa-solid fa-xmark'></i>&nbsp";
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();
}
$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;
}
if ($length < 0) {
$length = 60;
}
$Eban = new Eban();
$info = $Eban->getEbanInfoFromID($id);
if ($info === null) {
echo "<p>$icon Eban not found.</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 an eban issued by another admin.</p>";
die();
}
if ($playerName == $info['client_name'] && $playerSteamID == $info['client_steamid'] && $reason == $info['reason'] && $length == ($info['duration'] * 60)) {
echo "<p>$icon Cannot detect any changes to edit!</p>";
die();
}
if (!$Eban->IsSteamIDAlreadyBanned($playerSteamID)) {
echo "<p>$icon The edited steamid is already Eunbanned 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.
$Eban->EditEban($id, $playerName, $playerSteamID, $length, $reason);
}
if (isset($_GET['delete'])) {
$icon = "<i class='fa-solid fa-xmark'></i>&nbsp";
if (!isset($_COOKIE['steamID'])) {
echo "<p>$icon You are not logged in.</p>";
die();
}
$admin = new Admin();
$admin->UpdateAdminInfo($_COOKIE['steamID']);
if (!IsAdminLoggedIn()) {
echo "<p>$icon You are not logged in.</p>";
die();
}
if (!$admin->DoesHaveFullAccess()) {
echo "<p>$icon You do not have permission to delete an eban.</p>";
die();
}
$id = filter_input(INPUT_GET, 'deleteid', FILTER_SANITIZE_NUMBER_INT);
$Eban = new Eban();
$Eban->RemoveEbanFromDB($id);
die();
}
?>
+132
View File
@@ -0,0 +1,132 @@
<?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);
}
?>
<head>
<title>EntWatch 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>
<script src="js/ebans.js"></script>
</head>
<body>
<div class="hide" style="display: none;"></div>
<div class="Eban-action-window">
<div class="header">
<p id="action-header-text"></p>
</div>
<div class="info">
<ul class="Eban_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 Eban 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'>
<label for='s'>Input</label>
<input class='input search-modal-input' type='text' name='s' required>
</div>
<div class='input-group'>
<label for='m'>Method</label>
<select name='m' class='select search-modal-input'>
<option value='1'>Player SteamID</option>
<option value='2'>Player Name</option>
<option value='4'>Admin Name</option>
<option value='5'>Admin SteamID</option>
</select>
</div>
<button type='submit' class='button button-primary Eban-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="https://discord.gg/XhByCBg" 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, &nbsp;<a href=<?php echo "\"$adminURL\""; ?> target="_blank"><i class='fa-solid fa-user'></i> <?php echo $adminName; ?></a>&nbsp; &nbsp;
<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/banner.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="allEbans" href="index.php?all"><i class="fa-solid fa-house"></i> &nbspAll Ebans</a></li>
<li><a class="not-active" id="activeEbans" href="index.php?active"><i class="fa-solid fa-hourglass-half"></i> &nbspActive Ebans</a></li>
<li><a class="not-active" id="expiredEbans" href="index.php?expired"><i class="fa-solid fa-hourglass-end"></i> &nbspExpired Ebans</a></li>
<?php
if (IsAdminLoggedIn()) {
echo "<li><a id='addEban' class='not-active' id='add' href='manage.php?add'><i class='fas fa-user-times'></i> &nbspAdd Eban</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> &nbspWeb Logs</a></li>
<?php } ?>
<?php } ?>
</ul>
</div>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

+281
View File
@@ -0,0 +1,281 @@
<?php
include('header.php');
if (!isset($_GET['all']) && !isset($_GET['active']) && !isset($_GET['expired'])) {
echo "<script>window.location.replace('index.php?all');</script>";
die();
}
if (isset($_GET['page'])) {
$currentPage = ($_GET['page'] <= 0) ? 1 : $_GET['page'];
} else {
$currentPage = 1;
}
$resultsPerPage = 20;
$resultsStart = (($currentPage - 1) * $resultsPerPage);
$pageType = "all";
$sql = 'SELECT * FROM `EntWatch_Current_Eban` ';
if (isset($_GET['active'])) {
$sql = 'SELECT * FROM `EntWatch_Current_Eban` WHERE `is_expired` = 0 ';
$pageType = "active";
} elseif (isset($_GET['expired'])) {
$pageType = "expired";
$sql = 'SELECT * FROM `EntWatch_Current_Eban` WHERE `is_expired` = 1 ';
}
if (isset($_GET['s'])) {
$input = $_GET['s'];
$method = formatMethod(intval($_GET['m']));
if ($method == "client_steamid" || $method == "admin_steamid") {
if (!str_contains($input, "STEAMID")) {
if (str_contains($input, " ")) {
$input = str_replace(" ", "", $input);
}
}
$steam = new Steam();
$result = $steam->verifyAndConvertSteamID($input);
if ($result['success']) {
$convertedSteamID = $result['steamID2'];
$input = $convertedSteamID;
} else {
error_log("Error converting SteamID: " . $result['error']);
}
}
if ($pageType == "all") {
$sql = "SELECT * FROM `EntWatch_Current_Eban` WHERE `$method` LIKE '%$input%' ";
} else {
$sql .= "AND `$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;
}
$pageActiveNum = 2;
if ($pageType == "all") {
$pageActiveNum = 0;
$pageName = "Eban List";
$icon = "<i class='fa-solid fa-house'></i>";
} elseif ($pageType == "active") {
$pageActiveNum = 1;
$pageName = "Active Eban";
$icon = "<i class='fa-solid fa-hourglass-half'></i>";
} elseif ($pageType == "expired") {
$pageActiveNum = 2;
$pageName = "Expired Eban";
$icon = "<i class='fa-solid fa-hourglass-end'></i>";
}
echo "<script>setActive($pageActiveNum); setModalSearch(\"$pageType\");</script>";
?>
<!DOCTYPE html>
<html lang="en">
<?php
$query = $GLOBALS['DB']->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'));
}
?>
<div class="container">
<div class="container-header">
<h1><?php echo "$icon $pageName"; ?></h1>
</div>
<div class="breadcrumb">
<i class="fas fa-angle-right"></i> <a href="index.php?all">Home</a>
<i class="fas fa-angle-right"></i> <a href="index.php?all"><?php echo "$pageName"; ?></a>
</div>
<div class="container-search">
<div class="search-button search-modal-btn-open" id="search-button" data-page=<?php echo "\"$pageType\""; ?>>
<p><strong>Advanced Search (Click)</strong></p>
</div>
</div>
<div class="container-box1">
<div class="order1">
<p id="totalText" results=<?php echo "$resultsCount";?>>&nbsp Total Ebans: <?php echo $resultsCount; ?></p>
</div>
<div class="order2">
<?php
$resultsEnd = $resultsStart + $resultsRealCount;
?>
<p id="displaying-text" results=<?php echo "$resultsStart"; ?> totalresults=<?php echo "$resultsEnd" ?>>displaying <?php echo "$resultsStart - $resultsEnd"; ?> of <?php echo $resultsCount; ?> results |
<?php
$nextPage = $currentPage + 1;
$previousPage = $currentPage - 1;
if ($previousPage > 0) {
$href = $url . "&page=$previousPage";
echo "<a href='$href'><i class='fa fa-arrow-circle-left'></i> previous</a> |";
}
if ($nextPage > 0 && $nextPage <= $totalPages) {
$href = $url . "&page=$nextPage";
echo "&nbsp;<a href='$href'>next <i class='fa fa-arrow-circle-right'></i></a>";
}
echo "&nbsp;<select class='select_' style='width: 60px;' data-href='$url'>";
for ($i = 1; $i <= $totalPages; $i++) {
if ($currentPage == $i) {
echo "<option value='$i' selected>$i</option>";
} else {
echo "<option value='$i'>$i</option>";
}
}
echo "</select>";
?>
</p>
</div>
</div>
<div class="container-box2">
<div class="container-box2-table">
<div class="table">
<table>
<thead>
<tr>
<th style="width: 3%;">Game</th>
<th style="width: 20%;">Date</th>
<th style="width: 15%;">Player</th>
<th style="width: 5%; padding: 0;"></th>
<th style="width: 25%;">Reason</th>
<th style="width: 15%;">Admin</th>
<th style="width: 20%;">Duration</th>
</tr>
</thead>
<tbody>
<?php
$Eban = new Eban();
$admin = new Admin();
$dateA = new DateTime("now", new DateTimeZone(DATE_TIME_ZONE));
foreach ($results1 as $result1) {
$id = $result1['id'];
$clientName = $result1['client_name'];
$clientSteamID = $result1['client_steamid'];
$adminSteamID = $result1['admin_steamid'];
$reason = $result1['reason'];
$duration = $result1['duration'];
$time_stamp_start = strtotime($result1['time_stamp_start']);
$isExpired = ($result1['is_expired'] == 1) ? true : false;
$timestamp_unban = $result1['timestamp_unban'];
$adminNameRemoved = $result1['admin_name_unban'];
$adminSteamIDRemoved = $result1['admin_steamid_unban'];
$isRemoved = ($adminSteamIDRemoved != "" && $adminSteamIDRemoved != "SERVER") ? true : false;
$adminName = $admin->GetAdminNameFromSteamID($adminSteamID);
$isPermanent = ($duration == 0);
$length = $isPermanent ? "Permanent" : $Eban->formatPlaytime($duration);
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;
$count = $Eban->GetEbansNumber($clientSteamID);
$realcount = $Eban->GetRealEbansNumber($clientSteamID);
$dateA->setTimestamp($time_stamp_start);
$dateB = $dateA->format(DATE_TIME_FORMAT);
echo "<tr class='$class' id-data='$id' id='diva-tr-$id'>";
echo "<td style='background-color: transparent; align-items: center;'><img src='./images/games/csource.png' border='0' align='absmiddle' alt='css'></td>";
echo "<td>$dateB</td>";
if (empty($clientName)) {
echo "<td><i>No nickname present</i></td>";
} else {
echo "<td>$clientName</td>";
}
if ($count >= 2) {
if ($count == $realcount) {
echo "<td style='color: var(--theme-text); padding: 0;' class='count' id='$id-count' count='$count' steamid='$clientSteamID'><i class='fa-solid fa-ban'></i> <b>$realcount</b></td>";
} else {
echo "<td style='color: var(--theme-text); padding: 0;' class='count' id='$id-count' count='$count' steamid='$clientSteamID'><i class='fa-solid fa-ban'></i> <b>$realcount</b> ($count)</td>";
}
} else {
echo "<td></td>";
}
echo "<td>$reason</td>";
echo "<td>$adminName</td>";
echo "<td class='row-length' id='length-$id'>$length</td>";
echo "</tr>";
echo "<tr id='diva-$id-tr' style='display: none; width: 100%; height: 100%;'>";
echo "<td colspan='15'>";
echo "<div id='diva-$id' class='row-block' is_slided='0'>";
GetRowInfo(0, $result1);
echo "</div>";
echo "</td>";
echo "</tr>";
}
?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<?php include('footer.php'); ?>
</div>
</body>
<script>
$(function() {
var allRows = [
".row-expired",
".row-permanent",
".row-active"
];
for (var i = 0; i < allRows.length; i++) {
$(allRows[i]).on('click', function() {
showEbanInfo(this);
});
}
$('.select_').on('change', function() {
let value = $(this).val();
let href = $(this).attr('data-href');
href += '&page='+value;
window.location.replace(href);
});
});
</script>
+327
View File
@@ -0,0 +1,327 @@
function showEbanInfo(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 GoTop() {
if(document.documentElement.scrollTop > 450 || document.body.scrollTop > 450) {
document.body.scrollTop = 200;
document.documentElement.scrollTop = 200;
}
}
function GoHome() {
window.location.replace('index.php?all');
}
function ConfirmUnban(id, name, steamid) {
let reason = prompt('Please type the reason why you would Eunban ' + name + '[' + steamid + ']');
let confirmMessage = 'Are you sure you want to Eunban ' + 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("GET", "functions_url.php?oldid="+id+'&reason='+reason, true);
xmlResponse1.send();
var xmlResponse2 = new XMLHttpRequest();
xmlResponse2.onreadystatechange = function() {
if(this.readyState == 4 && this.status == 200) {
}
};
xmlResponse2.open("GET", "functions_url.php?id="+id, true);
xmlResponse2.send();
}
function ViewPlayerHistory(steamid, method) {
let url = "index.php?all=true&s="+steamid+"&m="+method;
window.location.replace(url);
}
function RebanFromID(id) {
let url = "manage.php?reban&oldid="+id;
window.location.replace(url);
}
function EditFromID(id) {
let url = "manage.php?edit&oldid="+id;
window.location.replace(url);
}
function addNewEban(playerName, playerSteamID, length, reason) {
var xmlResponse = new XMLHttpRequest();
xmlResponse.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {
$('.error').html(xmlResponse.responseText);
} else {
$('.error').html("<p>Request failed (HTTP " + this.status + "). " + xmlResponse.responseText + "</p>");
}
}
};
let url = "functions_url.php?add=1&playerName=" + encodeURIComponent(playerName) +
'&playerSteamID=' + encodeURIComponent(playerSteamID) +
'&length=' + encodeURIComponent(length) +
'&reason=' + encodeURIComponent(reason);
xmlResponse.open("GET", url, true);
xmlResponse.send();
}
function EditEban(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("<p>Request failed (HTTP " + this.status + "). " + xmlResponse1.responseText + "</p>");
}
}
};
let url = "functions_url.php?edit=1&id=" + encodeURIComponent(id) +
'&playerName=' + encodeURIComponent(playerName) +
'&playerSteamID=' + encodeURIComponent(playerSteamID) +
'&length=' + encodeURIComponent(length) +
'&reason=' + encodeURIComponent(reason);
xmlResponse1.open("GET", url, true);
xmlResponse1.send();
}
function RemoveEbanFromDBCheck(id) {
let confirmMessage = "Are you sure you want to delete this Eban from DB? ID: "+id;
let confirmHandler = confirm(confirmMessage);
if(confirmHandler == true) {
RemoveEbanFromDB(id);
}
}
function RemoveEbanFromDB(id) {
var xmlResponse1 = new XMLHttpRequest();
xmlResponse1.onreadystatechange = function() {
if(this.readyState == 4 && this.status == 200) {
$('.hide').html(xmlResponse1.responseText);
}
};
xmlResponse1.open("GET", "functions_url.php?delete=1&deleteid="+id, true);
xmlResponse1.send();
}
function setActive(num) {
/* 0 = All Ebans, 1 = Active Ebans, 2 = Expired Ebans, 3 = Add Eban, 4 = Web Logs, 5 = Server Logs */
if(num == 0) {
const bar = document.getElementById("allEbans");
bar.className = "active";
} else if(num == 1) {
const bar = document.getElementById("activeEbans");
bar.className = "active";
} else if(num == 2) {
const bar = document.getElementById("expiredEbans");
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("addEban");
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();
});
});
function setModalSearch(type) {
$('#hideInput').attr('name', type);
}
window.addEventListener('click', function(e) {
if(e.target.className == "search-modal-body") {
$('.search-modal-body').toggle();
}
});
function showEbanWindowInfo(type, playerName = "", playerSteamID = "", reason = "", length = "", id = 0) {
/* type values: 0 = Add Eban, 1 = Edit Eban, 2 = Unban Eban, 3 = Delete Eban */
const titles = [
"Eban Added",
"Eban Edited",
"Eban Unbanned",
"Eban Deleted"
];
const title = titles[type];
$('#action-header-text').html(title+" <i class='fa-solid fa-check' style='color: var(--button-success);'></i>");
let html = "";
if(playerName[0]) {
html += "<li>";
html += "<span>";
html += "<i class='fas fa-user'></i> Player";
html += "</span>";
html += "<span>";
html += playerName;
html += "</span>";
html += "</li>";
}
if(playerSteamID[0]) {
html += "<li>";
html += "<span>";
html += "<i class='fab fa-steam-symbol'></i> Steam ID";
html += "</span>";
html += "<span>";
html += playerSteamID;
html += "</span>";
html += "</li>";
}
if(reason[0]) {
html += "<li>";
html += "<span>";
html += "<i class='fas fa-question'></i> Reason";
html += "</span>";
html += "<span>";
html += reason;
html += "</span>";
html += "</li>";
}
if(length[0]) {
html += "<li>";
html += "<span>";
html += "<i class='fas fa-hourglass-half'></i> Duration";
html += "</span>";
html += "<span>";
html += length;
html += "</span>";
html += "</li>";
}
if(type == 3) {
let diva1 = '#diva-'+id;
$(diva1+'-tr').hide();
let diva2 = '#diva-tr-'+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 = $('#'+id+'-count').attr('count');
let newCountHtml = count - 1;
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();
let newHtml = Html.replace(count.toString(), newCountHtml.toString());
$('#'+allCounts[i].id).html(newHtml);
}
}
}
$('.Eban-action-window .info .Eban_details').html(html);
$('.Eban-action-window').css('display', 'block');
let sec = 3;
setTimeout(CloseWindow, (sec * 1000));
}
function CloseWindow() {
$('.Eban-action-window').css('display', 'none');
}
+16
View File
@@ -0,0 +1,16 @@
<?php
$server_host_url = (!empty($_SERVER['HTTPS']) ? 'https' : 'http').'://'.$_SERVER['HTTP_HOST'];
$login_url_params = [
'openid.ns' => '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();
?>
+83
View File
@@ -0,0 +1,83 @@
<?php
include('connect.php');
include('functions_global.php');
$params = [
'openid.assoc_handle' => $_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) {
$val = $_GET['openid_'.str_replace('.', '_', $item)];
$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 (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 = 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);
$response = json_decode($response,true);
$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();
?>
+11
View File
@@ -0,0 +1,11 @@
<?php
include('functions_global.php');
echo "Please wait....";
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);
header("Location: index.php?all");
die();
?>
+178
View File
@@ -0,0 +1,178 @@
<?php
include('header.php');
if (!IsAdminLoggedIn()) {
echo "<div class='container'>
<div class='error-box'>
<p><i class='fa-solid fa-triangle-exclamation'></i> You do not have access to this page.</p>
</div>
</div>
</div>";
die();
}
$admin = new Admin();
$admin->UpdateAdminInfo($_COOKIE['steamID']);
if (!$admin->DoesHaveFullAccess()) {
echo "<div class='container'>
<div class='error-box'>
<p><i class='fa-solid fa-triangle-exclamation'></i> You do not have access to this page.</p>
</div>
</div>
</div>";
die();
}
if (isset($_GET['page'])) {
$currentPage = ($_GET['page'] <= 0) ? 1 : $_GET['page'];
} else {
$currentPage = 1;
}
$resultsPerPage = 20;
$resultsStart = (($currentPage - 1) * $resultsPerPage);
$sql = "SELECT * FROM ";
$sql .= "`web_logs`";
if (isset($_GET['s'])) {
$input = $_GET['s'];
$method = formatMethod(intval($_GET['m']));
$sql .= " WHERE `$method`=$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;
}
echo "<script>setActive(4); setModalSearch(\"web\");</script>";
?>
<!DOCTYPE html>
<html>
<?php
$query = $GLOBALS['DB']->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'));
}
?>
<div class="container">
<div class="container-header">
<h1><i class="fa-regular fa-hard-drive"></i>Web Logs</h1>
</div>
<div class="breadcrumb">
<i class="fas fa-angle-right"></i> <a href="index.php?all">Home</a>
<i class="fas fa-angle-right"></i> <a href="logs.php?web">Web Logs</a>
</div>
<div class="container-search">
<div class="search-button search-modal-btn-open" id="search-button" data-page="web">
<p><strong>Advanced Search (Click)</strong></p>
</div>
</div>
<div class="container-box1">
<div class="order1">
<i>&nbsp Total Logs: <?php echo $resultsCount; ?></i>
</div>
<div class="order2">
<?php
$resultsEnd = $resultsStart + $resultsRealCount;
?>
<p>displaying <?php echo "$resultsStart - $resultsEnd"; ?> of <?php echo $resultsCount; ?> results |
<?php
$nextPage = $currentPage + 1;
$previousPage = $currentPage - 1;
if ($previousPage > 0) {
$href = $url . "&page=$previousPage";
echo "<a href='$href'><i class='fa fa-arrow-circle-left'></i> previous</a> |";
}
if ($nextPage > 0 && $nextPage <= $totalPages) {
$href = $url . "&page=$nextPage";
echo "&nbsp;<a href='$href'>next <i class='fa fa-arrow-circle-right'></i></a>";
}
echo "&nbsp;<select class='select_' style='width: 60px;' data-href='$url'>";
for($i = 1; $i <= $totalPages; $i++) {
if ($currentPage == $i) {
echo "<option value='$i' selected>$i</option>";
} else {
echo "<option value='$i'>$i</option>";
}
}
echo "</select>";
?>
</p>
</div>
</div>
<div class="container-box2">
<div class="container-box2-table">
<div class="table">
<table>
<thead>
<tr>
<th style="width: 15%;">Date</th>
<th style="width: 25%;">Player</th>
<th style="width: 25%;">Admin</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php
$admin = new Admin();
$date = new DateTime("now", new DateTimeZone(DATE_TIME_ZONE));
foreach ($results1 as $result1) {
$clientName = $result1['client_name'];
$clientSteamID = $result1['client_steamid'];
$adminSteamID = $result1['admin_steamid'];
$message = $result1['message'];
$time_stamp = $result1['time_stamp'];
$adminName = $admin->GetAdminNameFromSteamID($adminSteamID);
$date->setTimestamp($time_stamp);
$dateFormated = $date->format(DATE_TIME_FORMAT);
echo "<tr class='row-expired'>";
echo "<td>$dateFormated</td>";
if (empty($clientName)) {
echo "<td><i>No nickname present</i> ($clientSteamID)</a></td>";
} else {
echo "<td>$clientName ($clientSteamID)</a></td>";
}
echo "<td>$adminName</td>";
echo "<td>$message</td>";
echo "</tr>";
}
?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<?php include('footer.php'); ?>
</div>
<script>
$(function() {
$('.select_').on('change', function() {
let value = $(this).val();
let href = $(this).attr('data-href');
href += '&page='+value;
window.location.replace(href);
});
});
</script>
+233
View File
@@ -0,0 +1,233 @@
<?php
include('header.php');
$admin = new Admin();
if (!IsAdminLoggedIn()) {
echo "<div class='container'>
<div class='error-box'>
<p><i class='fa-solid fa-triangle-exclamation'></i> You do not have access to this page.</p>
</div>
</div>
</div>";
die();
}
$reban = false;
$edit = false;
$add = false;
if (isset($_GET['reban'])) {
$reban = true;
$oldid = $_GET['oldid'];
$Eban = new Eban();
$info = $Eban->getEbanInfoFromID(intval($oldid));
}
if (isset($_GET['edit'])) {
$edit = true;
$oldid = $_GET['oldid'];
$Eban = new Eban();
$info = $Eban->getEbanInfoFromID(intval($oldid));
if ($info['is_expired'] == 1) {
echo "<div class='container'>
<div class='error-box'>
<p><i class='fa-solid fa-triangle-exclamation'></i> Cannot edit an old Eban!</p>
</div>
</div>
</div>";
die();
}
}
if (isset($_GET['add'])) {
$add = true;
}
if ($add || $reban) {
echo "<script>setActive(3);</script>";
}
?>
<!DOCTYPE html>
<html>
<?php
$text = ($edit == true) ? "Edit Eban" : "Add Eban";
$formHeader = ($edit == true) ? "<i class='fa-regular fa-pen-to-square'></i>" : "<i class='fas fa-user-times'></i>";
$formHeader .= " $text";
$icon = ($edit == false) ? "<i class='fas fa-user-times'></i>" : "<i class='fa-regular fa-pen-to-square'></i>";
?>
<div class="container">
<div class="container-header">
<h1><?php echo "$icon $text"; ?></h1>
<div class="breadcrumb">
<i class="fas fa-angle-right"></i> <a href="index.php?all">Home</a>
<i class="fas fa-angle-right"></i> <a href="manage.php?add"><?php echo $text ?></a>
</div>
</div>
<div class="container-box2">
<div class="Eban-form">
<div class="header">
<p><?php echo $formHeader; ?></p>
</div>
<div class="error">
</div>
<?php
$val = "";
if ($edit == true || $reban == true) {
$val = $info['client_name'];
}
?>
<div class="input-group">
<label for="name">Player Name</label>
<input id="playerName" type="text" class="input Eban-input" max="32" value=<?php echo "\"$val\""; ?>>
</div>
<?php
$val = "";
if ($edit == true || $reban == true) {
$val = $info['client_steamid'];
}
?>
<div class="input-group">
<label for="steamid">Steam ID</label>
<?php if (empty($val)) { ?>
<input id="playerSteamID" type="text" class="input Eban-input">
<?php } else { ?>
<input id="playerSteamID" type="text" class="input Eban-input" value=<?php echo "\"$val\""; ?> title="Why the f*ck do you want to edit the SteamID? Just add a new Eban nigger" disabled>
<?php } ?>
</div>
<?php
$val = "";
if ($edit == true || $reban == true) {
$val = $info['reason'];
}
?>
<div class="input-group">
<label for="reason">Reason</label>
<input id="reason" type="text" class="input Eban-input" max="120" value=<?php echo "\"$val\""; ?>>
</div>
<?php if ($add == true) { ?>
<div class="input-group">
<label for="length">Duration</label>
<?php GetEbanLengths(); ?>
</div>
<?php } ?>
<?php if ($add == false) {
$val = intval($info['duration']);
?>
<div class="input-group">
<label for="length"> Duration </label>
<p style="font-style: italic; color: var(--theme-text_light); margin-top: 5px;">Enter 0 minutes for a permanent ban</p>
<input id="length-edit" type="text" class="input Eban-input" value=<?php echo "\"$val\""; ?>style="width: 110px; display: inline-block;">
<?php GetEbanLengthTypes(); ?>
</div>
<?php } ?>
<?php
$buttonID = ($edit == false) ? "add-button" : "edit-button";
$buttonTextValidate = ($edit == false) ? "Add Eban" : "Save Changes";
if (!isset($_GET['oldid'])) {
$oldid = "";
}
echo "<button class='button button-success Eban-form-button' style='width: 80%; margin-left: 10%;' data-oldid='$oldid' id='$buttonID' type='submit'> $buttonTextValidate</button>";
?>
</div>
</div>
</div>
<?php include('footer.php'); ?>
</div>
</body>
<script>
$(function() {
function verifyAndConvertSteamID(steamID, callback) {
$.ajax({
url: 'verify_steamid.php',
type: 'POST',
data: { steamid: steamID },
success: function(response) {
const result = JSON.parse(response);
callback(result);
},
error: function() {
alert('Error verifying SteamID.');
}
});
}
$('#add-button').on('click', function() {
let playerName = $('#playerName').val();
let playerSteamID = $('#playerSteamID').val();
let reason = $('#reason').val();
let length = 30;
<?php if ($add == true) { ?>
length = $('#add-select').val();
<?php } else { ?>
length = $('#length-edit').val();
let select = $('#edit-select').val();
if (select == 2) {
length *= 60;
} else if (select == 3) {
length *= 60 * 60;
} else if (select == 4) {
length *= 60 * 60 * 24;
} else if (select == 5) {
length *= 60 * 60 * 24 * 7;
} else if (select == 6) {
length *= 60 * 60 * 24 * 30;
}
<?php } ?>
verifyAndConvertSteamID(playerSteamID, function(response) {
if (response.success) {
addNewEban(playerName, response.steamID2, length, reason);
} else {
alert('Invalid SteamID: ' + response.error);
}
});
});
$('#edit-button').on('click', function() {
let id = $(this).attr('data-oldid');
let playerName = $('#playerName').val();
let playerSteamID = $('#playerSteamID').val();
let reason = $('#reason').val();
let length = $('#length-edit').val();
let select = $('#edit-select').val();
if (select == 2) {
length *= 60;
} else if (select == 3) {
length *= 60 * 60;
} else if (select == 4) {
length *= 60 * 60 * 24;
} else if (select == 5) {
length *= 60 * 60 * 24 * 7;
} else if (select == 6) {
length *= 60 * 60 * 24 * 30;
}
verifyAndConvertSteamID(playerSteamID, function(response) {
if (response.success) {
EditEban(id, playerName, response.steamID2, length, reason);
} else {
alert('Invalid SteamID: ' + response.error);
}
});
});
});
</script>
+125
View File
@@ -0,0 +1,125 @@
<?php
class Steam
{
private static function resolveInputID($steamid)
{
switch (true) {
case preg_match("/STEAM_[0|1]:[0:1]:\d*/", $steamid):
return 'Steam2';
case preg_match("/\[U:1:\d*\]/", $steamid):
return 'Steam3';
case preg_match("/U:1:\d*/", $steamid):
return 'Steam3';
case preg_match("/\d{17}/", $steamid):
return 'Steam64';
default:
throw new Exception("Invalid SteamID input!");
}
}
public static function convertSteamID($steamid)
{
try {
$type = self::resolveInputID($steamid);
switch ($type) {
case 'Steam2':
return $steamid;
case 'Steam3':
$converted = self::SteamID3_To_SteamID($steamid);
return $converted;
case 'Steam64':
$converted = self::SteamID64_To_SteamID($steamid);
return $converted;
default:
throw new Exception("Invalid SteamID input!");
}
} catch (Exception $e) {
error_log("Error during conversion: " . $e->getMessage());
throw $e;
}
}
public static function SteamID_To_SteamID3($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)
{
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)
{
if (preg_match('/^STEAM_0\:1|0\:(.*)$/', $steamid32, $res)) {
list(, $m1, $m2) = explode(':', $steamid32, 3);
list($steam_cid, ) = explode('.', bcadd((((int)$m2 * 2) + $m1), '76561197960265728'), 2);
return $steam_cid;
}
return false;
}
public static function SteamID64_To_SteamID($steamid64)
{
$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)
{
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");
}
$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()];
}
}
}
?>
+10
View File
@@ -0,0 +1,10 @@
<?php
include('steam.php');
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$steamid = $_POST['steamid'];
$steam = new Steam();
$result = $steam->verifyAndConvertSteamID($steamid);
echo json_encode($result);
}
?>