<?php
// инсталятор базы

if (!isset($ab_version)) die('stop install');

$antibot_db = new SQLite3(__DIR__.'/../data/sqlite.db'); 
$antibot_db->busyTimeout(5000);
$antibot_db->exec("PRAGMA journal_mode = WAL;");

/* ipv4 правила:
priority - приоритет (индекс)
search - строка которую добавили, ip или ip/mask (уник)
ip1 - числовое представление стартового ip (индекс)
ip2 - числовое представление конечного ip (индекс)
rule - правило: allow, block, gray
comment - просто коммент, чтоб понятнее было
expires - юникс дата истечения (потом удаляется), если навсегда, то 9999999999
*/
$query = $antibot_db->exec("CREATE TABLE IF NOT EXISTS ipv4rules (
priority INTEGER NOT NULL default '100', 
search TEXT UNIQUE NOT NULL default '', 
ip1 INTEGER NOT NULL default '', 
ip2 INTEGER NOT NULL default '', 
rule TEXT NOT NULL default '', 
comment TEXT NOT NULL default '', 
expires INTEGER NOT NULL default '9999999999'
);");
// индексы:
$index = $antibot_db->exec("CREATE INDEX IF NOT EXISTS priority4 ON ipv4rules (priority);"); 
$index = $antibot_db->exec("CREATE INDEX IF NOT EXISTS ipv4index1 ON ipv4rules (ip1);"); 
$index = $antibot_db->exec("CREATE INDEX IF NOT EXISTS ipv4index2 ON ipv4rules (ip2);"); 
// дефолтные ip сервера:
$add = @$antibot_db->exec("INSERT INTO ipv4rules (priority, search, ip1, ip2, rule, comment, expires) VALUES ('10', '127.0.0.1', '".AbIp2num('127.0.0.1')."', '".AbIp2num('127.0.0.1')."', 'allow', 'Local IP for cron, etc.', '9999999999');");
if (filter_var($_SERVER['SERVER_ADDR'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
$add = @$antibot_db->exec("INSERT INTO ipv4rules (priority, search, ip1, ip2, rule, comment, expires) VALUES ('10', '127.0.0.1', '".AbIp2num($_SERVER['SERVER_ADDR'])."', '".AbIp2num($_SERVER['SERVER_ADDR'])."', 'allow', 'Local IP from SERVER_ADDR', '9999999999');");
}

/* ipv6 правила:
priority - приоритет (индекс)
search - строка которую добавили, ip или ip/mask (уник)
ip1 - числовое представление стартового ip (индекс)
ip2 - числовое представление конечного ip (индекс)
rule - правило: allow, block, gray
comment - просто коммент, чтоб понятнее было
expires - юникс дата истечения (потом удаляется), если навсегда, то 9999999999
*/
$query = $antibot_db->exec("CREATE TABLE IF NOT EXISTS ipv6rules (
priority INTEGER NOT NULL default '100', 
search TEXT UNIQUE NOT NULL default '', 
ip1 INTEGER NOT NULL default '', 
ip2 INTEGER NOT NULL default '', 
rule TEXT NOT NULL default '', 
comment TEXT NOT NULL default '', 
expires INTEGER NOT NULL default '9999999999'
);");
// индексы:
$index = $antibot_db->exec("CREATE INDEX IF NOT EXISTS priority6 ON ipv6rules (priority);"); 
$index = $antibot_db->exec("CREATE INDEX IF NOT EXISTS ipv6index1 ON ipv6rules (ip1);"); 
$index = $antibot_db->exec("CREATE INDEX IF NOT EXISTS ipv6index2 ON ipv6rules (ip2);"); 

/*
rules - все прочие правила:
* 
priority - приоритет (индекс)
type - тип данных: useragent, country, lang (2 зн код), referer (хост), ptr, asname, asnum, uri, scriptname, httpaccept
data - значение (может быть пустым)
search - строка которую ищем по точному совпадению (уник) вида: referer=iframe-toloka.com (индекс)
rule - правило: allow, block, gray
comment - просто коммент, чтоб понятнее было
expires - юникс дата истечения (потом удаляется), если навсегда, то 9999999999
*/
$query = $antibot_db->exec("CREATE TABLE IF NOT EXISTS rules (
priority INTEGER NOT NULL default '1', 
type TEXT NOT NULL default '', 
data TEXT NOT NULL default '', 
search TEXT UNIQUE NOT NULL default '', 
rule TEXT NOT NULL default '', 
comment TEXT NOT NULL default '', 
expires INTEGER NOT NULL default '9999999999'
);");

$index = $antibot_db->exec("CREATE INDEX IF NOT EXISTS i_priority ON rules (priority);"); 
$index = $antibot_db->exec("CREATE INDEX IF NOT EXISTS i_search ON rules (search);");

$add = @$antibot_db->exec("INSERT INTO rules (priority, type, data, search, rule, comment) VALUES ('10', 'useragent', '', 'useragent=', 'block', 'Empty User-Agent');");
$add = @$antibot_db->exec("INSERT INTO rules (priority, type, data, search, rule, comment) VALUES ('10', 'lang', '', 'lang=', 'block', 'Empty Language');");
$add = @$antibot_db->exec("INSERT INTO rules (priority, type, data, search, rule, comment) VALUES ('10', 'referer', '', 'referer=', 'gray', 'Empty Referer');");

// ---------------------------------------------------------------------

// основной лог, таблица hits:
/*
cid - id клика, из микротайм, уник, PRIMARY KEY, вида 1631801701.9918
date - unix дата
ip - полный адрес 127.0.0.1 + индекс по этому полю
ptr - userhost.com. (для заглушки из пхп)
useragent - полностью
uid - хэш из cookie, хэг от ипа и юзерагента, для слежения за юзером
country - страна (код страны типа: RU)
referer - реферер полностью
page - текущая страница полностью
lang - язык полностью
generation - время генерации скрипта антибота
passed - INTEGER + индекс по этому полю
* получил заглушку и остался на ней (0 - STOP)
* прошел проверку автоматически в облаке или ab.php (1 - AUTO)
* прошел post кликом (2 - POST)
* если это хит мимо заглушки имеющих куки (3 - LOCAL)
* если прошли по разрешающему правилу (4 - ALLOW)
* белый бот (по ip и из конфига) (5 - GOODIP)
* заблокированные по правилам или из конфига (6 - BLOCK)
* фейк боты (маскирующиеся белыми ботами) (7 - FAKE)
recaptcha - рейтинг score, 
js_w - ширина монитора (из JS)
js_h - высота монитора (из JS)
js_cw - ширина окна браузера (из JS)
js_ch - высота окна браузера (из JS)
js_co - colordepth (из JS)
js_pi - pixeldepth (из JS)
refhost - хост реферера
adblock - включен блокировщик рекламы (1) или нет (0)  (из JS)
asnum - номер блока ip провайдера
asname - название провайдера
result - причина блокировки из облака (из JS) или слово GRAY
http_accept - типа text/html,application/xhtml+xml,application/xml;q=0.9
method - GET, POST, PUT, HEAD, DELETE, TRACE, OPTIONS, CONNECT
ym_uid - ClientID яндекс метрики, из cookie $_COOKIE['_ym_uid'] вида: 1620997730486452159 (число)
ga_uid - идентификатор клиента в Google Analytics из cookie $_COOKIE['_ga'] вида "GA1.2.1709431122.1631721710"
*/
// основная таблица, добавить параметр UNINDEXED к ненужным полям по которым нету поиска:
$query = $antibot_db->exec("CREATE TABLE IF NOT EXISTS hits (
cid TEXT NOT NULL PRIMARY KEY default '', 
date INTEGER NOT NULL default '', 
ip TEXT NOT NULL default '', 
ptr TEXT NOT NULL default '', 
useragent TEXT NOT NULL default '', 
uid TEXT NOT NULL default '', 
country TEXT NOT NULL default '', 
referer TEXT NOT NULL default '', 
page TEXT NOT NULL default '', 
lang TEXT NOT NULL default '', 
generation TEXT NOT NULL default '', 
passed INTEGER NOT NULL default '0', 
recaptcha TEXT NOT NULL default '0', 
js_w INTEGER NOT NULL default '', 
js_h INTEGER NOT NULL default '', 
js_cw INTEGER NOT NULL default '', 
js_ch INTEGER NOT NULL default '', 
js_co INTEGER NOT NULL default '', 
js_pi INTEGER NOT NULL default '', 
refhost TEXT NOT NULL default '', 
adblock INTEGER NOT NULL default '', 
asnum TEXT NOT NULL default '', 
asname TEXT NOT NULL default '', 
result TEXT NOT NULL default '', 
http_accept TEXT NOT NULL default '', 
method TEXT NOT NULL default '', 
ym_uid TEXT NOT NULL default '', 
ga_uid TEXT NOT NULL default ''
);");

$index = $antibot_db->exec("CREATE INDEX IF NOT EXISTS i_ip ON hits (ip);"); 
$index = $antibot_db->exec("CREATE INDEX IF NOT EXISTS i_passed ON hits (passed);"); 

/*
таблица счетчиков (в некотором роде кеш) по датам:
обновлять кроном
* 
date - дата вида 20191223
test - колво попавших на заглушку
auto - колво автоматически прошедших заглушку
post - колво кликнувших на кнопку для прохода заглушки
allow - колво прошедших по общим белым правилам
goodip - колво белых ботов из конфига и по базе белых ip
local - колво прошедших имеющих cookie
uusers - колво уников (подсчет по ip: AUTO POST ALLOW LOCAL)
husers - колво хитов (подсчет по ip: AUTO POST ALLOW LOCAL)
block - колво хитов забаненных (страна, язык, реферер, ptr)
fakes - колво хитов фейк ботов
google - кол-во хитов гугл бота
yandex - кол-во хитов яндекс бота
bing - кол-во хитов бинг бота
*/
$query = $antibot_db->exec("CREATE TABLE IF NOT EXISTS counters (
date INTEGER UNIQUE NOT NULL default '', 
test INTEGER NOT NULL default '0', 
auto INTEGER NOT NULL default '0', 
post INTEGER NOT NULL default '0', 
allow INTEGER NOT NULL default '0', 
goodip INTEGER NOT NULL default '0', 
local INTEGER NOT NULL default '0', 
uusers INTEGER NOT NULL default '0', 
husers INTEGER NOT NULL default '0', 
block INTEGER NOT NULL default '0', 
fakes INTEGER NOT NULL default '0', 
google INTEGER NOT NULL default '0', 
yandex INTEGER NOT NULL default '0', 
bing INTEGER NOT NULL default '0'
);");

/*
priority - приоритет
search - часть юзерагента
data - список валидных ptr
rule - правило: allow, block, gray
comment - просто коммент, чтоб понятнее было
* 
в php файл сохранять кэш в 2 массива ab_se как было в конфиге и массив ab_rule в котором search и rule
*/
$query = $antibot_db->exec("CREATE TABLE IF NOT EXISTS ab_se (
priority INTEGER NOT NULL default '100', 
search TEXT UNIQUE NOT NULL default '', 
data TEXT NOT NULL default '', 
rule TEXT NOT NULL default '', 
comment TEXT NOT NULL default ''
);");

// дефолтные поисковики:
$add = @$antibot_db->exec("INSERT INTO ab_se (priority, search, data, rule, comment) VALUES ('10', 'Googlebot', '.googlebot.com', 'allow', 'GoogleBot main indexer');");
$add = @$antibot_db->exec("INSERT INTO ab_se (priority, search, data, rule, comment) VALUES ('10', 'yandex.com', '.yandex.ru .yandex.net .yandex.com', 'allow', 'All Yandex bots');");
$add = @$antibot_db->exec("INSERT INTO ab_se (priority, search, data, rule, comment) VALUES ('10', 'Mail.RU_Bot', '.mail.ru .smailru.net', 'allow', 'All Bots Mail.RU Indexers');");
$add = @$antibot_db->exec("INSERT INTO ab_se (priority, search, data, rule, comment) VALUES ('10', 'bingbot', 'search.msn.com', 'allow', 'Bing.com indexer');");
$add = @$antibot_db->exec("INSERT INTO ab_se (priority, search, data, rule, comment) VALUES ('10', 'msnbot', 'search.msn.com', 'allow', 'Additional Indexer Bing.com');");
$add = @$antibot_db->exec("INSERT INTO ab_se (priority, search, data, rule, comment) VALUES ('10', 'Google-Site-Verification', '.googlebot.com .google.com', 'allow', 'Check for Google Search Console');");

$se_save = '<?php
$ab_rule[\'Googlebot\'] = \'allow\';
$ab_se[\'Googlebot\'] = array(\'.googlebot.com\');
$ab_rule[\'yandex.com\'] = \'allow\';
$ab_se[\'yandex.com\'] = array(\'.yandex.ru\', \'.yandex.net\', \'.yandex.com\');
$ab_rule[\'Mail.RU_Bot\'] = \'allow\';
$ab_se[\'Mail.RU_Bot\'] = array(\'.mail.ru\', \'.smailru.net\');
$ab_rule[\'bingbot\'] = \'allow\';
$ab_se[\'bingbot\'] = array(\'search.msn.com\');
$ab_rule[\'msnbot\'] = \'allow\';
$ab_se[\'msnbot\'] = array(\'search.msn.com\');
$ab_rule[\'Google-Site-Verification\'] = \'allow\';
$ab_se[\'Google-Site-Verification\'] = array(\'.googlebot.com\', \'.google.com\');
';
file_put_contents(__DIR__.'/../data/se.php', $se_save, LOCK_EX);

/*
priority - приоритет
search - часть урла вида /wp-content/uploads/
rule - правило: allow, block, gray
comment - просто коммент, чтоб понятнее было
* 
в php файл сохранять кэш массива ab_path в котором search и rule
*/
$query = $antibot_db->exec("CREATE TABLE IF NOT EXISTS ab_path (
priority INTEGER NOT NULL default '100', 
search TEXT UNIQUE NOT NULL default '', 
rule TEXT NOT NULL default '', 
comment TEXT NOT NULL default ''
);");

file_put_contents(__DIR__.'/../data/path.php', '<?php'."\n", LOCK_EX);

/*
k - 127.0.0.0/24
v - HTTP_X_REAL_IP
*/
$query = $antibot_db->exec("CREATE TABLE IF NOT EXISTS ab_proxy (
k TEXT UNIQUE NOT NULL default '', 
v TEXT NOT NULL default ''
);");

file_put_contents(__DIR__.'/../data/proxy.php', '<?php'."\n", LOCK_EX);

echo 'The database is installed.
<script>location.reload();</script>';
