333 lines
No EOL
13 KiB
PHP
333 lines
No EOL
13 KiB
PHP
<?php
|
|
namespace sockchat;
|
|
use \PDO;
|
|
|
|
class FFDB {
|
|
protected static function CreateFile($dir) {
|
|
try {
|
|
while(file_exists($fname = "$dir/". md5(microtime())));
|
|
} catch(\Exception $e) {
|
|
while(file_exists($fname = "$dir/". md5(time() + rand(0, 100))));
|
|
}
|
|
return $fname;
|
|
}
|
|
|
|
public static function Init() {
|
|
if(!file_exists("./ffdb")) mkdir("./ffdb");
|
|
if(!file_exists("./ffdb/chans")) mkdir("./ffdb/chans");
|
|
if(!file_exists("./ffdb/bans")) mkdir("./ffdb/bans");
|
|
if(!file_exists("./ffdb/logs.txt")) file_put_contents("./ffdb/logs.txt", "");
|
|
}
|
|
|
|
public static function Log($str) {
|
|
file_put_contents("./ffdb/logs.txt", "{$str}\n", FILE_APPEND);
|
|
}
|
|
|
|
public static function Ban($ip, $id, $username, $expire) {
|
|
$fname = FFDB::CreateFile("./ffdb/bans");
|
|
file_put_contents($fname, implode("\f", [$ip, $id, $username, $expire]));
|
|
echo $fname ."\n";
|
|
}
|
|
|
|
public static function Unban($ip, $id, $username) {
|
|
$files = glob("./ffdb/bans/*");
|
|
foreach($files as $file) {
|
|
$data = explode("\f", file_get_contents($file));
|
|
if(($data[0] == $ip && $data[0] != null) || ($data[1] == $id && $data[1] != null) || ($data[2] == $username && $data[2] != null))
|
|
unlink($file);
|
|
}
|
|
}
|
|
|
|
public static function GetAllBans() {
|
|
$bans = [];
|
|
|
|
$files = glob("./ffdb/bans/*");
|
|
foreach($files as $file) {
|
|
$data = explode("\f", file_get_contents($file));
|
|
if($data[3] <= time() && $data[3] != "-1") {
|
|
unlink($file);
|
|
continue;
|
|
}
|
|
|
|
array_push($bans, new Ban($data[0], $data[1], $data[2], $data[3]));
|
|
}
|
|
|
|
return $bans;
|
|
}
|
|
|
|
public static function CreateChannel($name, $pwd, $priv) {
|
|
$fname = FFDB::CreateFile("./ffdb/chans");
|
|
echo $fname ."\n";
|
|
file_put_contents($fname, implode("\f", [$name, $pwd, $priv]));
|
|
}
|
|
|
|
public static function ModifyChannel($oldname, $newname, $pwd, $priv) {
|
|
$files = glob("./ffdb/chans/*");
|
|
foreach($files as $file) {
|
|
$data = explode("\f", file_get_contents($file));
|
|
if($data[0] == $oldname) {
|
|
file_put_contents($file, implode("\f", [$newname, $pwd, $priv]));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static function RemoveChannel($name) {
|
|
$files = glob("./ffdb/chans/*");
|
|
foreach($files as $file) {
|
|
$data = explode("\f", file_get_contents($file));
|
|
if($data[0] == $name) {
|
|
unlink($file);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static function GetAllChannels() {
|
|
$chans = [];
|
|
|
|
$files = glob("./ffdb/chans/*");
|
|
foreach($files as $file) {
|
|
$data = explode("\f", file_get_contents($file));
|
|
$chans[$data[0]] = new Channel($data[0], $data[1], $data[2]);
|
|
}
|
|
|
|
return $chans;
|
|
}
|
|
}
|
|
|
|
class Database {
|
|
protected static $conn = null;
|
|
protected static $persist = true;
|
|
protected static $statements;
|
|
protected static $useFlatFile;
|
|
|
|
protected static function Execute($stmt, $fetch = false) {
|
|
Database::SpawnConnection();
|
|
$tmp = Database::$conn->prepare(Database::$statements[$stmt]["query"]);
|
|
foreach(Database::$statements[$stmt] as $param => $value) {
|
|
if($param != "query") $tmp->bindValue(":{$param}", $value);
|
|
}
|
|
$tmp->execute();
|
|
$ret = [];
|
|
if ($fetch) $ret = $tmp->fetchAll(PDO::FETCH_BOTH);
|
|
$tmp = null;
|
|
Database::$conn = null;
|
|
return $ret;
|
|
}
|
|
|
|
public static function SpawnConnection() {
|
|
$chat = $GLOBALS["chat"];
|
|
Database::$conn = new PDO($chat["DB_DSN"], $chat["DB_USER"], $chat["DB_PASS"], Database::$persist ? [PDO::ATTR_PERSISTENT => true] : []);
|
|
}
|
|
|
|
public static function Init() {
|
|
$chat = $GLOBALS["chat"];
|
|
Database::$useFlatFile = !$chat["DB_ENABLE"];
|
|
$persist = $chat["DB_PERSIST"];
|
|
if($chat["DB_ENABLE"]) {
|
|
try {
|
|
self::$persist = $persist;
|
|
Database::SpawnConnection();
|
|
$pre = $chat["DB_TABLE_PREFIX"];
|
|
|
|
Database::$statements = [
|
|
"logstore" => [
|
|
"query" => "INSERT INTO {$pre}_logs (epoch, userid, username, color, channel, chrank, message, flags) VALUES (:epoch, :uid, :uname, :color, :chan, :chrank, :msg, :flags)",
|
|
"epoch" => "","uid" => "", "uname" => "", "color" => "", "chan" => "", "chrank" => "", "msg" => "", "flags" => ""
|
|
],
|
|
"fetchbacklog" => [
|
|
"query" => "SELECT * FROM {$pre}_logs WHERE channel = :chan OR channel = '@all' ORDER BY epoch DESC LIMIT 0, ". Backlog::$loglen,
|
|
"chan" => ""
|
|
],
|
|
"login" => [
|
|
"query" => "INSERT INTO {$pre}_online_users (userid, username, color, perms) VALUES (:uid, :uname, :col, :perms)",
|
|
"uid" => "", "uname" => "", "col" => "", "perms" => ""
|
|
],
|
|
"logout" => [
|
|
"query" => "DELETE FROM {$pre}_online_users WHERE userid = :uid",
|
|
"uid" => ""
|
|
],
|
|
"clrusers" => [
|
|
"query" => "TRUNCATE TABLE {$pre}_online_users"
|
|
],
|
|
"crchan" => [
|
|
"query" => "INSERT INTO {$pre}_channels (chname, pwd, priv) VALUES (:chn, :pwd, :priv)",
|
|
"chn" => "", "pwd" => "", "priv" => ""
|
|
],
|
|
"modchan" => [
|
|
"query" => "UPDATE {$pre}_channels SET chname = :chn, pwd = :pwd, priv = :priv WHERE chname = :chon",
|
|
"chn" => "", "pwd" => "", "priv" => "", "chon" => ""
|
|
],
|
|
"delchan" => [
|
|
"query" => "DELETE FROM {$pre}_channels WHERE chname = :chn",
|
|
"chn" => ""
|
|
],
|
|
"fetchchan" => [
|
|
"query" => "SELECT * FROM {$pre}_channels"
|
|
],
|
|
"banuser" => [
|
|
"query" => "INSERT INTO {$pre}_banned_users (ip, uid, username, expiration) VALUES (:ip, :id, :uname, :exp)",
|
|
"ip" => "", "id" => "", "uname" => "", "exp" => ""
|
|
],
|
|
"unban" => [
|
|
"query" => "DELETE FROM {$pre}_banned_users WHERE (ip IS NOT NULL AND ip LIKE :ip) OR (uid IS NOT NULL AND uid = :id) OR (username IS NOT NULL AND username = :uname)",
|
|
"ip" => "", "id" => "", "uname" => ""
|
|
],
|
|
"fetchbans" => [
|
|
"query" => "SELECT * FROM {$pre}_banned_users"
|
|
],
|
|
"updatebans" => [
|
|
"query" => "DELETE FROM {$pre}_banned_users WHERE expiration <= :epoch AND expiration != -1",
|
|
"epoch" => ""
|
|
]
|
|
];
|
|
} catch(\Exception $err) {
|
|
echo "Could not connect to the database! Details: ". $err->getMessage() ."\n";
|
|
return;
|
|
}
|
|
} else FFDB::Init();
|
|
}
|
|
|
|
public static function FetchBacklog($chan) {
|
|
if(!Database::$useFlatFile) {
|
|
$ret = new Backlog();
|
|
|
|
Database::$statements["fetchbacklog"]["chan"] = $chan;
|
|
$logs = Database::Execute("fetchbacklog", true);
|
|
foreach($logs as $log)
|
|
$ret->Log(new User($log["userid"], "", $log["username"], $log["color"], "", null), $log["message"], "rlbl", $log["epoch"], $log["flags"]);
|
|
$ret->logs = array_reverse($ret->logs);
|
|
|
|
return $ret;
|
|
} else return new Backlog();
|
|
}
|
|
|
|
public static function TruncateUserList() {
|
|
if(!Database::$useFlatFile) Database::Execute("clrusers");
|
|
}
|
|
|
|
public static function Login($user) {
|
|
if(!Database::$useFlatFile) {
|
|
Database::$statements["login"]["uid"] = $user->id;
|
|
Database::$statements["login"]["uname"] = $user->username;
|
|
Database::$statements["login"]["col"] = $user->color;
|
|
Database::$statements["login"]["perms"] = $user->permstr;
|
|
Database::Execute("login");
|
|
}
|
|
}
|
|
|
|
public static function Logout($user) {
|
|
if(!Database::$useFlatFile) {
|
|
Database::$statements["logout"]["uid"] = $user->id;
|
|
Database::Execute("logout");
|
|
}
|
|
}
|
|
|
|
public static function Log($time, $user, $msg, $chan = null, $flags = "10010") {
|
|
$chan == null ? $user->channel : $chan;
|
|
if($chan == $GLOBALS["chat"]["DEFAULT_CHANNEL"]) $chan = "@default";
|
|
|
|
if(Database::$useFlatFile)
|
|
FFDB::Log("(". date("m/d/Y H:i:s") . ") ". $user->username ." to ". ($chan == null ? $user->channel : $chan) .": ". $msg);
|
|
else {
|
|
Database::$statements["logstore"]["epoch"] = $time;
|
|
Database::$statements["logstore"]["uid"] = $user->id;
|
|
Database::$statements["logstore"]["uname"] = $user->username;
|
|
Database::$statements["logstore"]["color"] = $user->color;
|
|
Database::$statements["logstore"]["chan"] = $chan == null ? $user->channel : $chan;
|
|
Database::$statements["logstore"]["chrank"] = $chan[0] == "@" ? 0 : Context::GetChannel($user->channel)->permissionLevel ?? 0;
|
|
Database::$statements["logstore"]["msg"] = $msg;
|
|
Database::$statements["logstore"]["flags"] = substr($flags, 0, 4) ."0";
|
|
Database::Execute("logstore");
|
|
}
|
|
}
|
|
|
|
public static function Ban($ip, $id, $username, $expire) {
|
|
if(Database::$useFlatFile)
|
|
FFDB::Ban($ip, $id, $username, $expire);
|
|
else {
|
|
Database::$statements["banuser"]["ip"] = $ip;
|
|
Database::$statements["banuser"]["id"] = $id;
|
|
Database::$statements["banuser"]["uname"] = $username;
|
|
Database::$statements["banuser"]["exp"] = $expire;
|
|
Database::Execute("banuser");
|
|
}
|
|
}
|
|
|
|
// you've got no bans
|
|
// you've got no drans
|
|
public static function GetAllBans() {
|
|
if(Database::$useFlatFile)
|
|
return FFDB::GetAllBans();
|
|
else {
|
|
$time = time();
|
|
Database::$statements["updatebans"]["epoch"] = $time;
|
|
Database::Execute("updatebans");
|
|
|
|
$blist = [];
|
|
$bans = Database::Execute("fetchbans", true);
|
|
foreach($bans as $ban) {
|
|
if($ban["expiration"] > $time || $ban["expiration"] == "-1") array_push($blist, new Ban($ban["ip"], $ban["uid"], $ban["username"], $ban["expiration"]));
|
|
}
|
|
return $blist;
|
|
}
|
|
}
|
|
|
|
// you want some
|
|
// i'll give it ya
|
|
public static function Unban($ip, $id, $username) {
|
|
if(Database::$useFlatFile)
|
|
FFDB::Unban($ip, $id, $username);
|
|
else {
|
|
Database::$statements["unban"]["ip"] = $ip;
|
|
Database::$statements["unban"]["id"] = $id;
|
|
Database::$statements["unban"]["uname"] = $username;
|
|
Database::Execute("unban");
|
|
}
|
|
}
|
|
|
|
public static function CreateChannel($name, $pwd, $priv = 0) {
|
|
if(Database::$useFlatFile)
|
|
FFDB::CreateChannel($name, $pwd, $priv);
|
|
else {
|
|
Database::$statements["crchan"]["chn"] = $name;
|
|
Database::$statements["crchan"]["pwd"] = $pwd;
|
|
Database::$statements["crchan"]["priv"] = $priv;
|
|
Database::Execute("crchan");
|
|
}
|
|
}
|
|
|
|
public static function RemoveChannel($name) {
|
|
if(Database::$useFlatFile)
|
|
FFDB::RemoveChannel($name);
|
|
else {
|
|
Database::$statements["delchan"]["chn"] = $name;
|
|
Database::Execute("delchan");
|
|
}
|
|
}
|
|
|
|
public static function ModifyChannel($oldname, $newname, $pwd, $priv) {
|
|
if(Database::$useFlatFile)
|
|
FFDB::ModifyChannel($oldname, $newname, $pwd, $priv);
|
|
else {
|
|
Database::$statements["modchan"]["chon"] = $oldname;
|
|
Database::$statements["modchan"]["chn"] = $newname;
|
|
Database::$statements["modchan"]["pwd"] = $pwd;
|
|
Database::$statements["modchan"]["priv"] = $priv;
|
|
Database::Execute("modchan");
|
|
}
|
|
}
|
|
|
|
public static function GetAllChannels() {
|
|
if(Database::$useFlatFile)
|
|
return FFDB::GetAllChannels();
|
|
else {
|
|
$clist = [];
|
|
$chans = Database::Execute("fetchchan", true);
|
|
foreach($chans as $chan)
|
|
$clist[$chan["chname"]] = new Channel($chan["chname"], $chan["pwd"], $chan["priv"], null, CHANNEL_PERM, Database::FetchBacklog($chan["chname"]));
|
|
return $clist;
|
|
}
|
|
}
|
|
} |