Location: PHPKode > projects > Phpbbantispam > files/includes/functions_antispam.php
<?php
/** Antispam functions
 * @author  Ramon Fincken, Phpbbinstallers.net, RamonFincken.com, WebsiteFreelancers.nl
 *
 * V 1.3.2  (Make sure you update this file on regular basis)
 */

if (!defined('IN_PHPBB')) {
	die('Hacking attempt');
}
define('IN_ANTISPAM_FUNCTIONS', true);

// 1.2.7
$root_spoof_check = true;
$root_spoof_check_instantban = true;
if ($root_spoof_check && (isset ($HTTP_GET_VARS['phpbb_root_path']) || isset ($HTTP_GET_VARS['phpex']) || isset ($HTTP_GET_VARS['phpEx']))) {
	$stop_now = false;
	if (isset ($HTTP_GET_VARS['phpbb_root_path'])) {
		preg_match_all("/http:\/\/|ftp:\/\/|www|[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}/si", $HTTP_GET_VARS['phpbb_root_path'], $out, PREG_SET_ORDER);
		if (count($out) > 0)
			$stop_now = true;
	}

	if (isset ($HTTP_GET_VARS['phpEx']) || isset ($HTTP_GET_VARS['phpex']))
		$stop_now = true;
	if ($stop_now) {
		// We haven't got any board_config yet so grab the config because we will not reach any phpbb code from this point
		$board_config = grab_boardconfig();

		$html_on = $board_config['mod_spamcheck_htmlmail'];
		$admin_email = $board_config['mod_spamcheck_adminmail'];

		$timestamp = time();
		// Notify admin
		sent_mail('Root path or phpEx spoof attempt, time: ' . $timestamp, 'IP spoofer: ' . htmlspecialchars($_SERVER['REMOTE_ADDR']), $admin_email, $html_on, 'Root path spoof attempt, time: ' . $timestamp);

		// Ban?
		if ($root_spoof_check_instantban) {
			antispam_direct_ban(htmlspecialchars($_SERVER['REMOTE_ADDR']));
			sent_mail('Root path or phpEx spoof attempt IP has been blocked by the system <br/>FILE: ' . __FILE__ . ' <br/>LINE: ' . __LINE__ . ' <br/>TIME time: ' . $timestamp, 'IP spoofer: ' . htmlspecialchars($_SERVER['REMOTE_ADDR']), $admin_email, $html_on, 'Root path spoof attempt, time: ' . $timestamp);
		}
		// Get lost
		@ header("HTTP/1.0 404 Not Found");
		// Halt all code
		exit ();
		// And die please
		die();
	}
}


// More then 4 records of this IP? That is enough! Stop this user
$count_threshold = 4;
$sql = "SELECT id, ip, count(ip) as ip_count from " . ANTISPAMDB_TABLE;
$sql .= " WHERE ip = '" . decode_ip($userdata['session_ip']) . "' group by ip HAVING ( ip_count >" . intval($count_threshold) . ") order by ip_count DESC";
if (!($result = $db->sql_query($sql))) {
	message_die(GENERAL_ERROR, 'Could not retrieve antispam info', '', __LINE__, __FILE__, $sql);
}
while ($row = $db->sql_fetchrow($result)) {
	if(!defined('ANTISPAM_HAS_DIED'))
	{
		message_die(GENERAL_MESSAGE, $lang['Antispam_spam_exp_overall']);
		define('ANTISPAM_HAS_DIED',true);
	}
}
// More then 4 records of this IP? That is enough! Stop this user

/**
 * You were very naughty, and deserve an instant ban
 * V1.2.9_1
 * Adapted from admin_antispam_functions.php > antispam_quick_ban()
 */
function antispam_direct_ban($ip) {
	global $lang, $db;

	if (!ip2banstatus($ip)) {
		$encoded_ip = encode_ip($ip);

		$decoded_ip = $ip;

		if (preg_match("/[^0-9\.*]/", $decoded_ip)) {
			message_die(GENERAL_MESSAGE, $lang['qb_iip'] . $decoded_ip);
		}

		preg_match_all("/[192\.][168\.][0-9\.*][0-9*]/si", $decoded_ip, $out, PREG_SET_ORDER);
		if (count($out) == 4)
			return;
		unset ($out);

		preg_match_all("/[0\.][0\.][0\.][0*]/si", $decoded_ip, $out, PREG_SET_ORDER);
		if (count($out) == 4)
			return;
		unset ($out);

		preg_match_all("/[127\.][0\.][0\.*][0-9*]/si", $decoded_ip, $out, PREG_SET_ORDER);
		if (count($out) == 4)
			return;
		unset ($out);

		// GOGOGO
		$type = 'ban_ip';
		$sql = "INSERT INTO " . BANLIST_TABLE . " (`" . $type . "`) VALUES ('" . $encoded_ip . "')";
		if (!$db->sql_query($sql)) {
			message_die(GENERAL_ERROR, "Couldn't insert " . $type . " entry into database.", "", __LINE__, __FILE__, $sql);
		}
	}
}

// 1.2.3, updated 1.2.7
// Load lang file, Thanks to 3Di and Whicher for this !
// http://www.phpbb.com/community/viewtopic.php?f=16&t=393606&p=3045697&e=3045697
$user_pref_langfile = $phpbb_root_path . 'language/lang_' . $userdata['user_lang'] . '/lang_antispam.' . $phpEx;
$default_langfile = $phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . '/lang_antispam.' . $phpEx;
$english_langfile = $phpbb_root_path . 'language/lang_english/lang_antispam.' . $phpEx;
if (@ file_exists($user_pref_langfile)) {
	// User language first
	include ($user_pref_langfile);
} else {
	if (@ file_exists($default_langfile)) {
		// Now default language
		include ($default_langfile);
	} else {
		// Now english
		if (@ file_exists($english_langfile)) {
			include ($english_langfile);
		} else {
			message_die(GENERAL_ERROR, 'Could not load the <b>Antispam MOD</b> language file, please check your installation.', 'Problem: File missing.');
		}
	}
}

function validate_spam($txt, $type = 'word') {
	global $db, $userdata, $board_config, $HTTP_GET_VARS, $HTTP_POST_VARS, $phpEx, $lang;

	// 1.2.7
	if (is_array($txt) || is_object($txt)) {
		die('Function/API error: Please sent in strings and not arrays or objects!');
	}
	// 1.1.6
	// Grab settings
	$group_id = $board_config['mod_spamcheck_groupbypassid'];
	$sent_mail = $board_config['mod_spamcheck_sentmail'];
	$html_on = $board_config['mod_spamcheck_htmlmail'];
	$admin_email = $board_config['mod_spamcheck_adminmail'];
	$main_admin_id = $board_config['mod_spamcheck_main_adminid'];
	$store_db = $board_config['mod_spamcheck_dbstore'];

	// 1.2.1
	$check_pm = $board_config['mod_spamcheck_check_pm'];
	$check_post = $board_config['mod_spamcheck_check_post'];
	$check_register = $board_config['mod_spamcheck_check_register'];

	// 1.1.7
	if (strlen($txt) < 2)
		return;

	// 1.2.7
	// Run the semi_cron
	antispam_semi_cron();

	// 1.1.3
	// For approved members in the usergroup ..
	if (user_check($userdata, $group_id))
		return;

	// 1.2.4
	// Handle unwanted IP's.. Let phpbb handle disallowed usernames and email's
	// Do not sent or store the results in the DB..
	// First IP's ..
	$user_ip = htmlspecialchars($_SERVER['REMOTE_ADDR']);
	$forwarded_ip = htmlspecialchars($_SERVER['HTTP_X_FORWARDED_FOR']);
	if ((!empty ($user_ip) && ip2banstatus($user_ip)) || (!empty ($forwarded_ip) && ip2banstatus($forwarded_ip))) {
		$spam_exp = $lang['Not_Authorised'] . '<br />' . $lang['You_been_banned'];
		message_die(GENERAL_ERROR, '<strong>' . $lang['Not_Authorised'] . '</strong><br />' . $spam_exp);
		exit ();
	}
	// Now usernames ..
	if (isset ($HTTP_POST_VARS['username'])) {
		$test_value = $HTTP_POST_VARS['username'];
		$test_result = test_username($test_value, '');
		if (strlen($test_result) > 0) {
			// Hit on an unwanted username, return and let the Phpbb system handle this
			return;
		}
	}
	// Now emails ..
	if (isset ($HTTP_POST_VARS['email'])) {
		$test_value = $HTTP_POST_VARS['email'];
		$test_result = test_email($test_value, '');
		if (strlen($test_result) > 0) {
			// Hit on an unwanted email, return and let the Phpbb system handle this
			return;
		}
	}

	// For admins... let them do the /admin/ stuff..
	if ($userdata['user_level'] == ADMIN) {
		// let MAIN-admin post ( like a rules topic: do not enter words like 'casino' or 'c4$1n0'
		if ($userdata['user_id'] == $main_admin_id)
			return;

		// let admin search a user
		if ($HTTP_GET_VARS['mode'] == "searchuser")
			return;
	}

	// 1rst round
	$txt1 = change_txt($txt, 1);
	// 2nd round
	$txt2 = change_txt($txt1, 2);
	// 3rd round
	$txt3 = change_txt($txt2, 3);
	// 4rd round
	$txt4 = change_txt($txt3, 4);
	// 5rd round
	$txt5 = change_txt($txt4, 5);

	// Determine or change type
	// ---------------------------------
	// Set $type to Registration ..
	if (array_key_exists('email', $HTTP_POST_VARS) && array_key_exists('username', $HTTP_POST_VARS)) {
		$type = 'register';
	}
	if (array_key_exists('mode', $HTTP_POST_VARS) && $HTTP_POST_VARS['mode'] === 'register') {
		$type = 'register';
	}
	if (array_key_exists('mode', $HTTP_POST_VARS) && array_key_exists('usersubmit', $HTTP_POST_VARS) && array_key_exists('folder', $HTTP_POST_VARS)) {
		$type = 'pm';
	}

	// Set $type to Editprofile
	if (array_key_exists('mode', $HTTP_POST_VARS) && $HTTP_POST_VARS['mode'] === 'editprofile') {
		$type = 'editprofile';
	}
	// Set $type to Post just in case ..
	// Simple check..
	if ($type === 'word') {
		if (array_key_exists('post', $HTTP_POST_VARS) && array_key_exists('subject', $HTTP_POST_VARS)) {
			$type = 'post';
		}
	}
	// ---------------------------------
	// Determine or change type

	// Shall we return?
	// ---------------------------------
	if ($type === 'pm' && !($check_pm))
		return;
	if ($type === 'post' && !($check_post))
		return;
	if ($type === 'register' && !($check_register))
		return;

	// ---------------------------------
	// Shall we return?

	// Set message to user
	// ---------------------------------
	$spam_exp = $lang['Antispam_spam_exp'];
	if ($type === 'register') {
		$spam_exp = $lang['Antispam_spam_exp_register'];
	}
	elseif ($type === 'post') {
		$spam_exp = $lang['Antispam_spam_exp_post'];
	}
	// ---------------------------------
	// Set message to user

	$sql = "SELECT word_id as id, word FROM  " . ANTISPAMWORDLIST_TABLE;
	if ($result = $db->sql_query($sql)) {
		if ($row = $db->sql_fetchrow($result)) {
			do {
				if (word_has_spamstatus($row['word'], $txt1, 1) || word_has_spamstatus($row['word'], $txt2, 2) || word_has_spamstatus($row['word'], $txt3, 3) || word_has_spamstatus($row['word'], $txt4, 4) || word_has_spamstatus($row['word'], $txt5, 5)) {
					if ($sent_mail)
						sent_mail($txt, $row[word], $admin_email, $html_on, $type);
					if ($store_db)
						$insert_id = db_store($txt, $row['id'], $type);

					// Update word_count for statistics..
					$sql_update = "UPDATE " . ANTISPAMWORDLIST_TABLE . " SET word_count = word_count + 1 WHERE word_id = '" . $row[id] . "'";
					parse_sql($sql_update, 'Could not store antispam information', __LINE__, __FILE__);

					$db->sql_freeresult($result);

					if(isset($insert_id) && intval($insert_id) > 0)
					{
						redirect(append_sid("antispam_check.$phpEx?id=" . $insert_id.'&type='.$type, true));
					}
					else
					{
						// 1.1.3, Show the word found to admin or mod, NOT to normal user !
						if ($userdata['user_level'] == ADMIN || $userdata['user_level'] == MOD) {
							message_die(GENERAL_ERROR, '<b>' . $lang['Antispam_spam_exp_usageof'] . '</b /><br />' . $spam_exp . '<br /><br/>' . $row[word] . '<BR/>' . $txt);
						} else {
							message_die(GENERAL_ERROR, '<b>' . $lang['Antispam_spam_exp_usageof'] . '</b /><br />' . $spam_exp . '<br /><br/>' . $txt);
						}
					}
				}

			} while ($row = $db->sql_fetchrow($result));
		}
	}
	$db->sql_freeresult($result);

	if ($board_config['mod_spamcheck_maxsites'] == 1) {
		// 1.2.7 Check max websites
		$number_of_sites = count_number_of_sites($txt);
		if ($number_of_sites > 0 && ($number_of_sites > $board_config['mod_spamcheck_maxsitescount'])) {
			message_die(GENERAL_MESSAGE, sprintf('Antispam Mod installed: Too many websites or urls entered'));
		}
	}
	return;
}

function sent_mail($txt, $word, $admin_email, $html_on, $type) {
	global $HTTP_POST_VARS, $HTTP_GET_VARS, $board_config, $userdata, $phpEx;
	// 1.1.3
	// Sent a mail to admin containing ALL post vars + get vars + username + ip

	$headers = "From: PhpBB-board <" . $admin_email . ">\r\n";
	$headers .= "Reply-To: PhpBB-board <" . $admin_email . ">\r\n";
	if ($html_on) {
		$headers .= "MIME-Version: 1.0\r\n";
		$headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
	}

	$user_ip = htmlspecialchars($_SERVER['REMOTE_ADDR']);
	$forwarded_ip = htmlspecialchars($_SERVER['HTTP_X_FORWARDED_FOR']);

	$the_post_vars_value = "ip => $user_ip\n<br />";
	if (strlen($forwarded_ip) > 0)
		$the_post_vars_value .= "ip forwarded for => $forwarded_ip\n<br />";
	$the_post_vars_value .= "userdata_username => " . $userdata['username'] . "\n<br />";

	// 1.2.7
	$profile_path = append_sid("profile.$phpEx?mode=viewprofile&amp;" . POST_USERS_URL . "=" . $userdata['user_id']);
	$server_url = get_serverurl($profile_path);
	if ($userdata['user_id'] > 0) {
		// Member of this board..
		$the_post_vars_value .= '<a href="' . $server_url . '">Click here to see the profile of ' . $userdata['username'] . '</a><br /><br />';
	}

	$the_post_vars_value .= "http_referer => " . $_SERVER["HTTP_REFERER"] . "\n<br />";
	$the_post_vars_value .= "http_user_agent => " . $_SERVER["HTTP_USER_AGENT"] . "\n<br />\n<br />";

	// Store get and post vars
	$vars = '';
	if (!empty ($HTTP_POST_VARS)) {
		$the_post_vars = $HTTP_POST_VARS;
		while (list ($key, $val) = each($the_post_vars)) {
			$the_post_vars_value .= "$key => $val\n<br />";
		}
		$vars .= '<hr /><br />Post vars are below:<br /><br />' . $the_post_vars_value;
	}
	if (!empty ($HTTP_GET_VARS)) {
		$the_get_vars = $HTTP_GET_VARS;
		$the_get_vars_value = '';
		while (list ($key, $val) = each($the_get_vars)) {
			$the_get_vars_value .= "$key => $val\n<br />";
		}
		$vars .= '<hr /><br />Get vars are below:<br /><br />' . $the_get_vars_value;
	}

	$themessage = '<html>Type:  ' . $type . '<br />Word is below<br /><br />' . $word . '<hr /><br />Text is below<br /><br />' . $txt . $vars . '</html>';
	if (!$html_on) {
		$themessage = str_replace('<br />', '\n', $themessage);
		$themessage = htmlspecialchars(strip_tags($themessage));
		$themessage = str_replace('&gt;', '>', $themessage);
	}

	// Safety first ..
	$themessage = str_replace('<scr', 'javascript disabled<', $themessage);

	// No use of $emailer, no HTML allowed
	mail($admin_email, $board_config['sitename'] . ' : Spam attempt', $themessage, $headers);
}

/**
 * Stores entry in DB
 * @return	insert_id ($core_id)
 */
function db_store($txt, $word_id, $type) {
	global $db, $HTTP_POST_VARS, $HTTP_GET_VARS, $board_config, $userdata, $phpEx;

	$user_ip = htmlspecialchars($_SERVER['REMOTE_ADDR']);
	$forwarded_ip = htmlspecialchars($_SERVER['HTTP_X_FORWARDED_FOR']);

	$the_post_vars_value = "http_referer => " . $_SERVER["HTTP_REFERER"] . "\n<br />";
	$the_post_vars_value .= "http_user_agent => " . $_SERVER["HTTP_USER_AGENT"] . "\n<br />\n<br />";

	$spamscore = 0;

	// Fieldfest corrections ..
	if (!empty ($HTTP_POST_VARS) && ($type == 'register' || $type == 'website source') && fieldfest_on() && fieldfest_regchange()) {
		$the_get_vars = $HTTP_POST_VARS;
		if (!empty ($HTTP_POST_VARS['username']))
			$HTTP_POST_VARS['attempted_username'] = $HTTP_POST_VARS['username'];
		// Base case..
		$HTTP_POST_VARS['username'] = '';
		$antispam_username_check = fieldfest_get_changedfield('register', 'username');

		if (isset ($HTTP_POST_VARS[$antispam_username_check])) {
			$HTTP_POST_VARS['username'] = (!empty ($HTTP_POST_VARS[$antispam_username_check])) ? $HTTP_POST_VARS[$antispam_username_check] : '';
		}
	}
	// Fieldfest corrections ..

        $uppercased = preg_match_all('/[A-Z]/', $HTTP_POST_VARS['username'], $null1);
        $allcased = preg_match_all('/[A-Za-z]/', $HTTP_POST_VARS['username'], $null2);
        $namelen = strlen($HTTP_POST_VARS['username']);

        if($allcased >0)
        {
        	$ucratio = $uppercased/$allcased;
        	if($namelen > 8 && $ucratio > 0.3){
            	$spamscore+=3;
            }
        }

	// Set core_id values..
	$time = time();
	$sql = "INSERT INTO " . ANTISPAMDB_TABLE .
	" (user_id, ip, ip_forwarded, time,type,word_triggerid,score)" .
	" VALUES" .
	" ($userdata[user_id],'$user_ip','$forwarded_ip', $time,'$type',$word_id,$spamscore)";
	$error_msg = '';
	if (!($result = $db->sql_query($sql))) {
		message_die(GENERAL_ERROR, $error_msg, '', __LINE__, __FILE__, $sql);
	}

	// Now get the core_id to store extra info in the _data DB ..
	$core_id = $db->sql_nextid();
	if (intval($core_id) < 1) {
		message_die(GENERAL_ERROR, $error_msg, '', __LINE__, __FILE__, $sql);
	}

   // Save logs, courticy of Lord Raiden, Raiden.net
   $sql = "INSERT INTO ".ANTISPAMDB_LOGS_TABLE." (ip, ip_forwarded, time) VALUES ('$user_ip','$forwarded_ip', $time)";
   if ( !($result = $db->sql_query($sql)) )
   {
      message_die(GENERAL_ERROR, $error_msg, '', __LINE__, __FILE__, $sql);
   }

	// Store get and post vars
	if (!empty ($HTTP_POST_VARS)) {
		$row_type = 'post';
		$the_post_vars = $HTTP_POST_VARS;
		while (list ($key, $val) = each($the_post_vars)) {
			// create new row
			insert_antispamdb_data($core_id, $row_type, $key, $val, $type);
		}
	}
	if (!empty ($HTTP_GET_VARS)) {
		$row_type = 'get';
		$the_get_vars = $HTTP_GET_VARS;
		while (list ($key, $val) = each($the_get_vars)) {
			// create new row
			insert_antispamdb_data($core_id, $row_type, $key, $val, $type);
		}
	}
	return $core_id;
}

/**
 * Stores all vars in DB
 */
function insert_antispamdb_data($core_id, $row_type, $key, $val, $type) {
	global $db;

	// Go back if we store unwanted entries..
	if ($type = 'post' || $type = 'pm') {
		$array = array (
			"addbbcode0",
			"addbbcode2",
			"addbbcode4",
			"addbbcode6",
			"addbbcode8",
			"addbbcode10",
			"addbbcode12",
			"addbbcode14",
			"addbbcode16",
			"addbbcode18",
			"addbbcode20",
			"helpbox",
			"preview"
		);
		if (in_array($key, $array))
			return;
		if (in_array("agreed", $array) && $val = 'agreed')
			return;
	}

	// loop call
	$sql = "INSERT INTO " . ANTISPAMDB_DATA_TABLE . " (core_id, vartype, varkey, varvalue) ";
	$sql .= " VALUES  ($core_id,'$row_type','$key','$val')";
	if (!($result = $db->sql_query($sql))) {
		message_die(GENERAL_ERROR, 'error inserting file,line ' . __FILE__ . '  ' . __LINE__, '', __LINE__, __FILE__, $sql);
	}
	// loop call
}

// ---------------- CHANGE STRING FUNCTIONS
function change_txt($txt, $mode) {
	// 1.1.2, 1.1.3
	switch ($mode) {
		case 1 :
			// [url=http://www.badurl.com]Click[/url]
			$txt = preg_replace("/\[url=(\W?)(.*?)(\W?)\](.*?)\[\/url\]/", "$2" . " " . "$4", $txt);

			// [url]http://www.badurl.com[/url]
			$txt = preg_replace("/\[url\](.*?)\[\/url\]/", "$1", $txt);

			// [b ][/b ]
			$txt = preg_replace('/\[.+\]\[\/.+\]/', '', $txt);

			// 1.1.3
			// [size=0]hidden_txt[/size]
			$txt = preg_replace("/\[size=0\:(.*?)\](.*?)\[\/size\:(.*?)\]/", "$4", $txt);
			// [size=-{int}]really small txt[/size]
			$txt = preg_replace("/\[size=-(.*?)\:(.*?)\](.*?)\[\/size\:(.*?)\]/", "$5", $txt);

			// Soften the txt for the algoritm is too strong..
			// you can also -> anal  ? I'll -> pill
			// hide@address.com -> hide@address.com ...
			// 1.2.7 Thanks WebSnail! http://www.phpbbantispam.com/viewtopic.php?t=75
			$search = array (
				'can always',
				'can allow',
				'can also',
				' except',
				' example',
				'? I',
				'? i',
				'casino mod',
				'casino hack',
				'@yahoo.com',
				'http://www.google-analytics.com',
				'https://www.google-analytics.com',
				'google-analytics.com/ga.js',

			);
			$replace = array (
				'',
				'',
				'',
				'',
				'',
				'',
				'',
				'',
				'',
				'',
				'',
				'',
				''
			);
			$txt = str_replace($search, $replace, $txt);
			break;
		case 2 :
			// 1.1.2
			$search = array (
				'4',
				'@',
				'$',
				'8',
				'3',
				'!',
				'1',
				'0',
				'?',
				'7'
			);
			$replace = array (
				'a',
				'a',
				's',
				'b',
				'e',
				'i',
				'i',
				'o',
				'p',
				't'
			);
			$txt = str_replace($search, $replace, $txt);
			break;
		case 3 :
			//    & goes to aamp;
			$search = array (
				'.',
				',',
				' ',
				'_',
				':',
				'[',
				']',
				'|',
				'\\',
				'/',
				'&',
				'aamp;'
			);
			$replace = array (
				'',
				'',
				'',
				'',
				'',
				'i',
				'i',
				'i',
				'i',
				'i',
				'a',
				'a'
			);
			$txt = str_replace($search, $replace, $txt);
			break;
		case 4 :
			// 1.2.6
			// Remove double chars
			$txt = strip_doublechars($txt);
			break;
		case 5 :
			// [size=1]small_txt[/size]
			$txt = preg_replace("/\[size=1\:(.*?)\](.*?)\[\/size\:(.*?)\]/", "$4", $txt);
			// [{}][/{}]
			$txt = preg_replace("/\[(.*?)\]\[(.*?)\]/", "$5", $txt);

			$txt = ereg_replace("[^a-zA-Z0-9]", "", $txt);
			break;
		default :
			break;
	}
	return $txt;
}

// 1.2.6
function strip_doublechars($txt) {
	/* Partial/rewrote code from: Forum Assassin, Dom Walenczak http://spam.wulfslair.com/ (Cybertronian Alliance Corp) */

	$txt_stripped = '';
	$last_character = '';
	for ($i = 0; $i < strlen($txt); $i++) {
		if ($txt[$i] != $last_character) {
			$txt_stripped .= $txt[$i];
		}
		$last_character = $txt[$i];
	}
	return $txt_stripped;
}
// ---------------- CHANGE STRING FUNCTIONS

/**
 * Is the user free of the spam check?
 * @return boolean
 */
function user_check($userdata, $group_id) {
	// basic case, user is not logged in, so no need for extra checks
	if ($userdata['user_id'] == ANONYMOUS)
		return false;

	// check if user is in bypass usergroup
	if ((group_check($userdata['user_id'], $group_id))) {
		// user is in usergroup
		return true;
	}

	// check user posts and membership length in days
	if (!(userdata_check($userdata))) {
		// user has failed the background test
		return false;
	}

	// congratulations, this user is free of the spam check!
	return true;
}

function userdata_check($userdata, $times_multiple = 1) {
	global $db, $board_config;
	// $times_multiple is to make sure the cron will be a bit more on the safe
	// side lets say multplied by 2
	$profiledata = get_userdata($userdata['user_id']);

	// 1.2.9
	if ($profiledata['antispam_approved'] == 1) {
		return true;
	}

	$timecheck = time() - (86400 * (intval($board_config['mod_spamcheck_userdays'] * $times_multiple)));
	if ($profiledata['user_regdate'] < ($timecheck)) {
		if ($profiledata['user_posts'] >= ($board_config['mod_spamcheck_userposts'] * $times_multiple)) {
			// Passed all tests
			return true;
		}
	}
	// Failed at least one test, return false
	return false;
}

function group_check($user_id, $group_id) {
	// 1.1.6
	global $db;
	$sql = "SELECT user_id FROM " . USER_GROUP_TABLE . " WHERE user_id = " . intval($user_id) . " AND user_pending = 0 AND ((group_id = " . intval($group_id) . ") )  LIMIT 1";
	if (!($result = $db->sql_query($sql))) {
		message_die(GENERAL_ERROR, 'Could not obtain group information for this user', '', __LINE__, __FILE__, $sql);
	}
	$ok = False;
	while ($group_data = $db->sql_fetchrow($result)) {
		$ok = True;
	}
	return $ok;
}

/**
 * Check remote websites, uses the simple_check()
 */
function validate_spam_website($url) {
	global $board_config, $userdata;

	// 1.1.6
	// Remote check enabled?
	if (!($board_config['mod_spamcheck_checkremote']))
		return;

	// 1.1.6
	// Grab settings
	$group_id = $board_config['mod_spamcheck_groupbypassid'];
	$sent_mail = $board_config['mod_spamcheck_sentmail'];
	$html_on = $board_config['mod_spamcheck_htmlmail'];
	$admin_email = $board_config['mod_spamcheck_adminmail'];
	$main_admin_id = $board_config['mod_spamcheck_main_adminid'];
	$store_db = $board_config['mod_spamcheck_dbstore'];

	// 1.3.0
	// For approved members in the usergroup ..
	if (user_check($userdata, $group_id))
		return;

	if (!website_syntax_ok($url)) {
		return;
	}
	if (strlen($url) < 8)
		return;
	if (!(substr_count($url, "http:") > 0))
		return;
	if (!(substr_count($url, ".") > 0))
		return;

	if ((substr_count($url, ".ht") > 0))
		return;
	if ((substr_count($url, ".php") > 0))
		return;

	// Gogogo!
	$handle = @ fopen($url, "rb");
	$contents = '';
	while (!@ feof($handle)) {
		$contents .= @ fread($handle, 8192);
	}
	fclose($handle);

	if (!empty ($contents))
		simple_check($contents);
}

/**
 * Called from function validate_spam_website($url)
 */
function simple_check($txt, $type = 'website source') {
	global $db, $userdata, $board_config, $HTTP_GET_VARS, $phpEx, $lang;

	// 1.1.7
	if (strlen($txt) < 2)
		return;

	// 1.1.6
	// Grab settings
	$group_id = $board_config['mod_spamcheck_groupbypassid'];
	$sent_mail = $board_config['mod_spamcheck_sentmail'];
	$html_on = $board_config['mod_spamcheck_htmlmail'];
	$admin_email = $board_config['mod_spamcheck_adminmail'];
	$main_admin_id = $board_config['mod_spamcheck_main_adminid'];
	$store_db = $board_config['mod_spamcheck_dbstore'];

	// 1.3.0
	// For approved members in the usergroup ..
	if (user_check($userdata, $group_id))
		return;

	$sql = "SELECT word_id as id, word FROM  " . ANTISPAMWORDLIST_TABLE;
	if ($result = $db->sql_query($sql)) {
		if ($row = $db->sql_fetchrow($result)) {
			do {
				if (word_has_spamstatus($row['word'], $txt, 1)) {
					if ($sent_mail)
						sent_mail($txt, $row[word], $admin_email, $html_on, 'website source');
					if ($store_db)
						$insert_id = db_store($txt, $row[id], $type);

					$db->sql_freeresult($result);
					if(isset($insert_id) && intval($insert_id) > 0)
					{
						redirect(append_sid("antispam_check.$phpEx?id=" . $insert_id.'&type='.$type, true));
					}
					else
					{
						// 1.1.3, Show the word found to admin or mod, NOT to normal user !
						if ($userdata['user_level'] == ADMIN || $userdata['user_level'] == MOD) {
							message_die(GENERAL_ERROR, '<b>' . $lang['Antispam_spam_exp_usageof'] . '</b /><br />' . $lang['Antispam_spam_exp'] . '<br /><BR/>' . $row[word] . '<BR/>');
						} else {
							message_die(GENERAL_ERROR, '<b>' . $lang['Antispam_spam_exp_usageof'] . '</b /><br />' . $lang['Antispam_spam_exp'] . '<br /><BR/>');
						}
					}
				}

			} while ($row = $db->sql_fetchrow($result));
		}
	}
	$db->sql_freeresult($result);
	return;
}

// One of the core functions ..
function word_has_spamstatus($word, $txt, $change_algoritm = 1) {
	global $board_config;

	$spamstatus = false;

	// 1.2.7
	// Since 1.2.7 we allow admins to determine the spamchecklevel
	$spamcheck_level = $board_config['mod_spamcheck_level'];

	if ($change_algoritm > $spamcheck_level) {
		// If the requested algoritm level > board spamcheck level,
		// return that these words are NOT spam
		return $spamstatus;
	}

	// 1.1.2
	if (preg_match("#\b(" . str_replace("\*", ".*?", preg_quote($word, '#')) . ")\b#i", $txt)) {
		$spamstatus = true;
	}
	return $spamstatus;
}

/**
 * IP is banned?
 */
function ip2banstatus($ip) {
	global $db;
	preg_match('/(..)(..)(..)(..)/', encode_ip($ip), $user_ip_parts);

	$sql = "SELECT ban_ip FROM " . BANLIST_TABLE;
	$sql .= " WHERE ban_ip IN ('" . $user_ip_parts[1] . $user_ip_parts[2] . $user_ip_parts[3] . $user_ip_parts[4] . "', '" . $user_ip_parts[1] . $user_ip_parts[2] . $user_ip_parts[3] . "ff', '" . $user_ip_parts[1] . $user_ip_parts[2] . "ffff', '" . $user_ip_parts[1] . "ffffff')";

	if (!($result = $db->sql_query($sql))) {
		message_die(CRITICAL_ERROR, 'Could not obtain ban information', '', __LINE__, __FILE__, $sql);
	}

	if ($ban_info = $db->sql_fetchrow($result)) {
		if ($ban_info['ban_ip']) {
			return true;
		}
	}
	return false;
}

function parse_sql($sql, $error_msg, $line, $file, $freeresult = false) {
	global $db;
	if (!($result = $db->sql_query($sql))) {
		message_die(GENERAL_ERROR, $error_msg, '', $line, $file, $sql);
	}
	if ($freeresult)
		$db->sql_freeresult($result);
}

// ---------------- REGISTER FUNCTIONS
function register_antispam_init() {
	global $db, $mode, $HTTP_POST_VARS, $userdata, $lang;
	// -------
	// Username name of the txt input field
	if ($mode == 'register' && fieldfest_on() && fieldfest_regchange()) {
		if (isset ($HTTP_POST_VARS['submit'])) {
			// Get old value..
			$antispam_username_check = fieldfest_get_changedfield('register', 'username');
			if (isset ($HTTP_POST_VARS[$antispam_username_check])) {
				$antispam_username = (!empty ($HTTP_POST_VARS[$antispam_username_check])) ? phpbb_clean_username($HTTP_POST_VARS[$antispam_username_check]) : '';
			} else {
				message_die(GENERAL_MESSAGE, 'Get lost_register ' . __LINE__);
			}
		}
	}

	if (isset ($HTTP_POST_VARS['submit']) || isset ($HTTP_POST_VARS['avatargallery']) || isset ($HTTP_POST_VARS['submitavatar']) || isset ($HTTP_POST_VARS['cancelavatar']) || $mode == 'register') {
		if ($mode == 'register' && fieldfest_on() && fieldfest_regchange()) {
			$username = $antispam_username;
		} else {
			$username = (!empty ($HTTP_POST_VARS['username'])) ? phpbb_clean_username($HTTP_POST_VARS['username']) : '';
		}
	}

	// Username name of the txt input field
	// -------

	// Lengths
	// -------
	if (isset ($HTTP_POST_VARS['submit']) || isset ($HTTP_POST_VARS['avatargallery']) || isset ($HTTP_POST_VARS['submitavatar']) || isset ($HTTP_POST_VARS['cancelavatar']) || $mode == 'register') {
		$length_notresonable_bool = false;
		$max_normal_length = 200; // above this value for a username?
		$matches = explode('|', $username);
		if (strlen($username) > $max_normal_length || count($matches) > 15) {
			$length_notresonable_bool = true;
		}
		if (!empty ($HTTP_POST_VARS['msn'])) {
			if (strlen($HTTP_POST_VARS['msn'] > $max_normal_length)) {
				$length_notresonable_bool = true;
			}
		}
		if (!empty ($HTTP_POST_VARS['msn']) && (strlen($HTTP_POST_VARS['msn']) == strlen($HTTP_POST_VARS['aim'])) && (strlen($HTTP_POST_VARS['msn']) == strlen($HTTP_POST_VARS['yim']))) {
			if (strlen($HTTP_POST_VARS['msn'] > $max_normal_length)) {
				$length_notresonable_bool = true;
			}
		}
		if ($length_notresonable_bool) {
			message_die(GENERAL_MESSAGE, 'Get lost_register ' . __LINE__);
		}
	}
	// Lengths

	// Hidden fields
	// -------
	if ($mode == 'register' && fieldfest_on() && fieldfest_regadd()) {
		if (isset ($HTTP_POST_VARS['submit'])) {
			// Field 1
			// Get old value..
			$antispam_hidden1_check = fieldfest_get_changedfield('register', 'add_1', 'add_1');
			if (!isset ($HTTP_POST_VARS[$antispam_hidden1_check]) || !empty ($HTTP_POST_VARS[$antispam_hidden1_check])) {
				// Field not found or not empty ?
				message_die(GENERAL_MESSAGE, 'Get lost_register' . __LINE__);
			}

			// Field 2
			// Get old value..
			$antispam_hidden2_check = fieldfest_get_changedfield('register', 'add_2', 'add_2');
			if (!isset ($HTTP_POST_VARS[$antispam_hidden2_check])) {
				// Field not found
				message_die(GENERAL_MESSAGE, 'Get lost_register' . __LINE__);
			} else {
				// Get the value of the hidden field
				$antispam_hidden2_val_check = fieldfest_get_changedfield('register', 'add_2temp', 'add_2temp');
				if ($HTTP_POST_VARS[$antispam_hidden2_check] != $antispam_hidden2_val_check) {
					// Righty, field was found but not with the desired hidden value
					// BUSTED
					message_die(GENERAL_MESSAGE, 'Get lost_register' . __LINE__);
				}
			}
		}
	}

	// Time spent on page
	if ($mode == 'register' && (isset ($HTTP_POST_VARS['submit']) || isset ($HTTP_POST_VARS['avatargallery']) || isset ($HTTP_POST_VARS['submitavatar']) || isset ($HTTP_POST_VARS['cancelavatar']))) {
		$antispam_hidden3_check = fieldfest_get_changedfield('register', 't_1', 't_1');
		if (!isset ($HTTP_POST_VARS[$antispam_hidden3_check])) {
			// Field not found
			message_die(GENERAL_MESSAGE, 'Get lost_register' . __LINE__);
		} else {
			$timecheck = (time() - $HTTP_POST_VARS[$antispam_hidden3_check]);
			if ($timecheck < 3 || intval($HTTP_POST_VARS[$antispam_hidden3_check]) == 0) {
				message_die(GENERAL_MESSAGE, 'Get lost_register, to soon' . __LINE__);
			}
		}
	}
	// -------
	// Hidden fields

	// -------
	// Check stored spam attempts for this IP
	if ($mode == 'register') {
		$count_threshold = 2;
		$sql = "SELECT id, ip, count(ip) as ip_count from " . ANTISPAMDB_TABLE;
		$sql .= " WHERE ip = '" . decode_ip($userdata['session_ip']) . "' group by ip HAVING ( ip_count >" . intval($count_threshold) . ") order by ip_count DESC";
		if (!($result = $db->sql_query($sql))) {
			message_die(GENERAL_ERROR, 'Could not retrieve antispam registration info', '', __LINE__, __FILE__, $sql);
		}
		while ($row = $db->sql_fetchrow($result)) {
			message_die(GENERAL_MESSAGE, $lang['Too_many_registers']);
		}

		$forwarded_ip = htmlspecialchars($_SERVER['HTTP_X_FORWARDED_FOR']);
		$sql = "SELECT id, ip_forwarded, count(ip_forwarded) as ip_count from " . ANTISPAMDB_TABLE;
		$sql .= " WHERE ip_forwarded != '' AND ip_forwarded = '" . $forwarded_ip . "' group by ip_forwarded HAVING ( ip_count >" . intval($count_threshold) . ") order by ip_count DESC";
		if (!($result = $db->sql_query($sql))) {
			message_die(GENERAL_ERROR, 'Could not retrieve antispam registration info', '', __LINE__, __FILE__, $sql);
		}
		while ($row = $db->sql_fetchrow($result)) {
			message_die(GENERAL_MESSAGE, $lang['Too_many_registers']);
		}
	}
	// Check stored spam attempts for this IP
	// -------

	// Check stored spam attempts for this email, MSN, ICQ, website
	// -------
	if ($mode == 'register') {
		if (isset ($HTTP_POST_VARS['submit'])) {
			// Mail
			if (isset ($HTTP_POST_VARS['email'])) {
				$mail = $HTTP_POST_VARS['email'];
				if (!empty ($mail) && mail_syntax_ok($mail)) {
					// Read DB
					$sql = "SELECT count(varvalue) as email_count FROM " . ANTISPAMDB_DATA_TABLE;
					$sql .= " WHERE varkey ='email' AND varvalue = '" . $mail . "'";
					if (!($result = $db->sql_query($sql))) {
						message_die(GENERAL_ERROR, 'Could not retrieve antispam registration info', '', __LINE__, __FILE__, $sql);
					}
					$count_threshold = 3;
					while ($row = $db->sql_fetchrow($result)) {
						if ($row['email_count'] > $count_threshold) {
							message_die(GENERAL_MESSAGE, $lang['Too_many_registers']);
						}
					}
				}
			}

			// MSN
			if (isset ($HTTP_POST_VARS['msn'])) {
				$msn = $HTTP_POST_VARS['msn'];
				if (!empty ($msn) && mail_syntax_ok($msn)) {
					// Read DB
					$sql = "SELECT count(varvalue) as msn_count FROM " . ANTISPAMDB_DATA_TABLE;
					$sql .= " WHERE varkey ='msn' AND varvalue = '" . $msn . "'";
					if (!($result = $db->sql_query($sql))) {
						message_die(GENERAL_ERROR, 'Could not retrieve antispam registration info', '', __LINE__, __FILE__, $sql);
					}
					$count_threshold = 3;
					while ($row = $db->sql_fetchrow($result)) {
						if ($row['msn_count'] > $count_threshold) {
							message_die(GENERAL_MESSAGE, $lang['Too_many_registers']);
						}
					}
				}
			}

			// ICQ
			if (isset ($HTTP_POST_VARS['icq'])) {
				$icq = intval($HTTP_POST_VARS['icq']);
				if ($icq > 0) {
					// Read DB
					$sql = "SELECT count(varvalue) as icq_count FROM " . ANTISPAMDB_DATA_TABLE;
					$sql .= " WHERE varkey ='icq' AND varvalue = '" . $icq . "'";
					if (!($result = $db->sql_query($sql))) {
						message_die(GENERAL_ERROR, 'Could not retrieve antispam registration info', '', __LINE__, __FILE__, $sql);
					}
					$count_threshold = 3;
					while ($row = $db->sql_fetchrow($result)) {
						if ($row['icq_count'] > $count_threshold) {
							message_die(GENERAL_MESSAGE, $lang['Too_many_registers']);
						}
					}
				}
			}
			// Website
			if (isset ($HTTP_POST_VARS['website'])) {
				$website = $HTTP_POST_VARS['website'];
				if (!empty ($website) && website_syntax_ok($website)) {
					// Read DB
					$sql = "SELECT count(varvalue) as website_count FROM " . ANTISPAMDB_DATA_TABLE;
					$sql .= " WHERE varkey ='website' AND varvalue = '" . $website . "'";
					if (!($result = $db->sql_query($sql))) {
						message_die(GENERAL_ERROR, 'Could not retrieve antispam registration info', '', __LINE__, __FILE__, $sql);
					}
					$count_threshold = 3;
					while ($row = $db->sql_fetchrow($result)) {
						if ($row['website_count'] > $count_threshold) {
							message_die(GENERAL_MESSAGE, $lang['Too_many_registers']);
						}
					}
				}
			}
		}
	}
	// -------
	// Check stored spam attempts for this email, MSN, ICQ, website

	// Well looks clean, return the submitted username :)
	return $username;
}
function register_antispam_createfields() {
	global $mode, $template, $userdata, $s_hidden_fields;

	if ($mode == 'register' && fieldfest_on() && fieldfest_regchange()) {
		// Create or update fieldname
		$fieldfest_username = fieldfest_createfield('register', 'change', 'username');
		$template->assign_vars(array (
			'ANTISPAM_FIELDFEST_USERNAME' => $fieldfest_username
		));
	} else {
		$template->assign_vars(array (
			'ANTISPAM_FIELDFEST_USERNAME' => 'username'
		));
	}

	// -------
	// Hidden fields
	if ($mode == 'register' && fieldfest_on() && fieldfest_regadd()) {
		// Create or update fieldname
		$value = '';
		$fieldfest_name = fieldfest_createfield('register', 'add_1', 'add_1');
		$s_hidden_fields .= '<input type="hidden" name="' . $fieldfest_name . '" value="' . $value . '" />';

		// Create or update fieldname
		$value = fieldfest_createfield('register', 'add_2temp', 'add_2temp');
		$fieldfest_name = fieldfest_createfield('register', 'add_2', 'add_2');
		$s_hidden_fields .= '<input type="hidden" name="' . $fieldfest_name . '" value="' . $value . '" />';
	}
	if ($mode == 'register') {
		// Create or update fieldname
		$value = time();
		$fieldfest_name = fieldfest_createfield('register', 't_1', 't_1');
		$s_hidden_fields .= '<input type="hidden" name="' . $fieldfest_name . '" value="' . $value . '" />';
	}
	// Hidden fields
	// -------
}

function register_antispam_compare() {
	global $HTTP_POST_VARS, $HTTP_GET_VARS, $phpEx, $phpbb_root_path,$username;
	/*
	define(IN_ANTISPAM,true);
	include($phpbb_root_path.'/includes/functions_lev.' . $phpEx);
	*/

	// Here we go gnagna

	$refer = explode('///', $_SERVER["HTTP_REFERER"]);
	if (isset ($refer[1]) && !empty ($refer[1])) {
		return array (
			'error' => true,
			'error_msg' => 'Bad referrer Code 1'
		);
	}
	$refer = explode('/./.', $_SERVER["HTTP_REFERER"]);
	if (isset ($refer[1]) && !empty ($refer[1])) {
		return array (
			'error' => true,
			'error_msg' => 'Bad referrer Code 2'
		);
	}

	// Code from includes/usercp_register.php
	$strip_var_list = array (
		'email' => 'email',
		'icq' => 'icq',
		'aim' => 'aim',
		'msn' => 'msn',
		'yim' => 'yim',
		'website' => 'website',
		'location' => 'location',
		'occupation' => 'occupation',
		'interests' => 'interests',
		'timezone' => 'timezone',
		'signature' => 'signatue'
	);
	// Strip all tags from data ... may p**s some people off, bah, strip_tags is
	// doing the job but can still break HTML output ... have no choice, have
	// to use htmlspecialchars ... be prepared to be moaned at.
	while (list ($var, $param) = @ each($strip_var_list)) {
		if (!empty ($HTTP_POST_VARS[$param])) {
			$$var = trim(htmlspecialchars($HTTP_POST_VARS[$param]));
		} else {
			$$var = '';
		}

		if(!empty($$var) && $$var != 'website')
		{
			$number_of_sites = count_number_of_sites($$var);
			if($number_of_sites >= 2)
			{
				return array (
					'error' => true,
					'error_msg' => 'Found '.$number_of_sites. ' sites in '.$var.'. Please remove some!'
				);
			}
		}
	}

	if(!empty($username))
	{
		// Valid Email?
		if ((mail_syntax_ok($username))) {
			return array (
				'error' => true,
				'error_msg' => 'Username looks like email'
			);
		}
		$username_low = strtolower($username);
		if(website_syntax_ok($username) || strpos($username_low,'https://') !== false || strpos($username_low,'http://') !== false || strpos($username_low,'www.') !== false){
			return array (
				'error' => true,
				'error_msg' => 'Username looks like website'
			);
		}
	}

	// Email tests
	if (!empty ($email)) {
		// Valid Email?
		if (!(mail_syntax_ok($email))) {
			return array (
				'error' => true,
				'error_msg' => 'No valid email syntax'
			);
		}
		/*
		// LEV
		$lev_check = go_lev_validate($email);
		if($lev_check['error'])
		{
		   return array (
		      'error' => true,
		      'error_msg' => $lev_check['error_msg']
		   );
		}
		*/
	}

	// ICQ tests
	if (!empty ($icq) && strlen($icq) > 2) {
		// Valid ICQ ?
		if (!is_numeric($icq)) {
			return array (
				'error' => true,
				'error_msg' => 'No valid ICQ.'
			);
		}

		// Valid ICQ cannot be a valid MSN adress
		if (!empty ($msn) && $msn == $icq) {
			return array (
				'error' => true,
				'error_msg' => 'No valid MSN syntax.'
			);
		}
	}

	// MSN tests
	if (!empty ($msn)) {
		// Valid MSN?
		if (!(mail_syntax_ok($msn))) {
			return array (
				'error' => true,
				'error_msg' => 'No valid MSN syntax.'
			);
		}
		/*
		// LEV
		$lev_check = go_lev_validate($msn);
		if($lev_check['error'])
		{
		   return array (
		      'error' => true,
		      'error_msg' => $lev_check['error_msg']
		   );
		}
		*/
	}

	// AIM tests
	if (!empty ($aim)) {
		if (website_syntax_ok($aim)) {
			return array (
				'error' => true,
				'error_msg' => 'No valid AIM, looks like a website url.'
			);
		}
	}

	// YIM tests
	if (!empty ($yim)) {
		if (website_syntax_ok($yim)) {
			return array (
				'error' => true,
				'error_msg' => 'No valid YIM, looks like a website url.'
			);
		}
	}

	// Website tests
	if (!empty ($website) && strlen($website) > 2) {
		if (!website_syntax_ok($website)) {
			return array (
				'error' => true,
				'error_msg' => 'No valid website url.'
			);
		}
	}

	// Timezone tests
	if (isset ($timezone) && !empty ($timezone) && $timezone == -12) {
		$locations = array (
			'usa',
			'us',
			'london',
			'paris',
			'belgium',
			'holland',
			'bulgaria',
			'cambodia',
			'denmark',
			'denver',
			'deutschland',
			'england',
			'eritrea',
			'nigeria',
			'niger',
			'milan',
			'napels',
			'netherlands',
			'amsterdam',
			'europe'
		);
		foreach ($locations as $testlocation) {
			$pattern = '/' . $testlocation . '/';
			preg_match($pattern, strtolower($location), $matches, PREG_OFFSET_CAPTURE);
			if (count($matches) > 0) {
				return array (
					'error' => true,
					'error_msg' => 'No valid timezone.'
				);
			}
		}
		$location = str_replace(' ', '', $location);
		if (empty ($location)) {
			return array (
				'error' => true,
				'error_msg' => 'No valid location for this timezone.'
			);
		}
	}

	// Base case
	return array (
		'error' => false,
		'error_msg' => ''
	);
}
// ---------------- REGISTER FUNCTIONS

// ---------------- FIELDFEST FUNCTIONS
function fieldfest_on() {
	global $board_config;

	if ($board_config['mod_spamcheck_fieldfest'] == 1)
		return true;
	return false;
}

function fieldfest_regchange() {
	global $board_config;

	if ($board_config['mod_spamcheck_fieldfest_regchange'] == 1)
		return true;
	return false;
}
function fieldfest_regadd() {
	global $board_config;

	if ($board_config['mod_spamcheck_fieldfest_regadd'] == 1)
		return true;
	return false;
}

function fieldfest_semicron($sort, $user_session_id) {
	// First some clean up, 2 days
	$timecheck = (time() - (2 * 60 * 60 * 24));
	$sql = "DELETE FROM " . ANTISPAMDBFIELDFEST_TABLE . " WHERE time < " . $timecheck;
	parse_sql($sql, 'Could not delete old antispam sessions', __LINE__, __FILE__);

	// Remove all same sessions :)
	$sql = "DELETE FROM " . ANTISPAMDBFIELDFEST_TABLE . " WHERE sort = '" . $sort . "' AND session_id = '" . $user_session_id . "'";
	parse_sql($sql, 'Could not delete old antispam sessions', __LINE__, __FILE__);
}

function fieldfest_createfield($type, $sort, $fieldname) {
	global $db, $userdata;

	$user_id = intval($userdata['user_id']);
	$user_session_id = $userdata['session_id'];

	// Do some clean up first
	fieldfest_semicron($sort, $user_session_id);

	// Random random !!
	$newfield = antispam_create_random(rand(1, 6) + 1);

	// Now insert new entry..
	$sql = "INSERT INTO " . ANTISPAMDBFIELDFEST_TABLE;
	$sql .= " (type, sort, old, new, time, session_id) VALUES ('" . $type . "', '" . $sort . "', '" . $fieldname . "', '" . $newfield . "', " . time() . ", '" . $user_session_id . "')";
	if (!$db->sql_query($sql)) {
		message_die(GENERAL_ERROR, 'Could not insert antispam register information', '', __LINE__, __FILE__, $sql);
	}
	return $newfield;
}

function fieldfest_get_changedfield($type, $fieldname, $sort = 'change') {
	global $db, $lang, $userdata;
	// Base case
	$new = '';
	$sql = "SELECT new FROM " . ANTISPAMDBFIELDFEST_TABLE;
	$sql .= " WHERE type = '$type' AND sort = '" . $sort . "' AND old = '$fieldname' AND session_id = '" . $userdata[session_id] . "' LIMIT 1";
	if (!($result = $db->sql_query($sql))) {
		message_die(GENERAL_ERROR, 'Could not get value for the antispam register information', '', __LINE__, __FILE__, $sql);
	}
	while ($row = $db->sql_fetchrow($result)) {
		$new = (!empty ($row['new'])) ? $row['new'] : '';
	}
	$db->sql_freeresult($result);
	return $new;
}
// ---------------- FIELDFEST FUNCTIONS

// ---------------- SEMI CRON FUNCTIONS
function antispam_semi_cron() {
	// 1.2.7
	global $db, $board_config, $lang;
	$last_cron_time = $board_config['mod_spamcheck_semicron'];
	// Let's stick to dayly first shall we?
	$timecheck = ($last_cron_time + (1 * 60 * 60 * 24));

	if ($timecheck > $last_cron_time) {
		// Let's do it
		// Clean up usergroup

		// Thanks to Evil<3 for this code!
		$hide_sql = ' AND g.group_type <> ' . GROUP_HIDDEN;
		$hide_sql .= " AND ug.user_pending = 0 ";

		// Execute the select query
		$sql = 'SELECT g.*, u.user_id, u.username FROM ';
		$sql .= USERS_TABLE . ' u, ' . GROUPS_TABLE . ' g, ' . USER_GROUP_TABLE . ' ug ';
		$sql .= 'WHERE u.user_id = ug.user_id AND ug.group_id = g.group_id ';
		$sql .= 'AND g.group_single_user = 0 AND g.group_id = ' . $board_config['mod_spamcheck_groupbypassid'];
		$sql .= $hide_sql . ' ORDER BY u.user_id ASC';

		if (!$result = $db->sql_query($sql)) {
			// Error handling
			print_r($db->sql_error());
			die();
		}
		while ($row = $db->sql_fetchrow($result)) {
			if ($row['user_id'] != $row['group_moderator']) {
				// Update our user table
				// V1.2.9
				$sql = "UPDATE " . USERS_TABLE . " SET antispam_approved = '1' WHERE user_id = '" . $row['user_id'] . "' LIMIT 1";
				parse_sql($sql, $lang['Antispam_db_errorstore'], __LINE__, __FILE__);

				// Delete this user from usergroup, but leave the group moderator!
				$sql = "DELETE FROM " . USER_GROUP_TABLE .
				" WHERE group_id = '" . $board_config['mod_spamcheck_groupbypassid'] . "'" .
				" AND user_id = '" . $row['user_id'] . "' AND user_id != '" . $row['group_moderator'] . "' LIMIT 1";
				parse_sql($sql, $lang['Antispam_db_errorstore'], __LINE__, __FILE__);
			}

		}
		$sql = "UPDATE " . CONFIG_TABLE .
		" SET config_value = '" . time() . "' " .
		" WHERE config_name = 'mod_spamcheck_semicron' LIMIT 1";
		parse_sql($sql, $lang['Antispam_db_errorstore'], __LINE__, __FILE__);
	}

}

// ---------------- SEMI CRON FUNCTIONS

// ---------------- CREATE RANDOM FUNCTIONS
function antispam_create_random($till = 3) {
	$i = 1;
	while ($i <= intval($till)) {
		global $r, $t;
		$i++;
		$r = rand(0, 10);
		$random_number2 = rand(0, 25) + 65;
		$t = chr($random_number2);
		$random_number .= $t;
		$random_number .= $r;
	}
	return $random_number;
}
// ---------------- CREATE RANDOM FUNCTIONS

// ---------------- NEW ENTRIES FOR ADMINS
function show_newentrieslink() {
	global $db, $lang, $userdata;
	if (!($userdata['user_level'] == ADMIN)) {
		return '<a href="http://www.phpbbantispam.com" title="'.$lang['Antispam__open_reports_protectedby'].'">'.$lang['Antispam__open_reports_protectedby'].'</a>';
	}

	$sql = "SELECT count(db.Id) as total FROM " . ANTISPAMDB_TABLE . " as db WHERE time >= " . intval($userdata['user_lastvisit']);
	if (!($result = $db->sql_query($sql))) {
		message_die(GENERAL_ERROR, 'Could not query spam information', '', __LINE__, __FILE__, $sql);
	}
	$total = 0;
	while ($row = $db->sql_fetchrow($result)) {
		$total = $row['total'];
	}
	if ($total > 0) {
		$spam_open_reports = sprintf((($total == 1) ? $lang['Antispam__open_reports_one'] : $lang['Antispam__open_reports_many']), $total);
		$spam_open_reports = '<b><font color="red">' . $spam_open_reports . '</font></b>';
		$spam_report_notice = '&nbsp; ' . $spam_open_reports . '&nbsp;';
	}
	return $spam_report_notice;
}
// ---------------- NEW ENTRIES FOR ADMINS

// ---------------- SYNTAX TEST FUNCTIONS
/**
 * Counts occurences of webadresses (including [url])
 */
function count_number_of_sites($txt)
{
	// 1.2.9
	// http://phpbbantispam.com/viewtopic.php?t=129
	// [url=somesites.nw]Some site[/url] becomes http://somesites.nw https://somesites.nw Some site
	$txt = preg_replace('/\[url=([^http](.+))\](.+)\[\/(.+)\]/', "http://$1 https://$1 $3", $txt);

	// 1.2.7 Check max websites
	// Partially re-coded from : http://www.phpbb.com/community/viewtopic.php?f=16&t=360188&start=30&st=0&sk=t&sd=a
	$out = array();
	preg_match_all("/http:\/\/|ftp:\/\/|www|[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}/si", $txt, $out, PREG_SET_ORDER);
	$number = count($out);
	return $number;
}

function website_syntax_ok($url) {
	$url = strtolower($url);
	if (empty ($url))
		return false;
	if (!preg_match('#^http[s]?\\:\\/\\/[a-z0-9\-]+\.([a-z0-9\-]+\.)?[a-z]+#i', $url)) {
		return false;
	}
	$pattern = '/\[url/';
	preg_match($pattern, $url, $matches, PREG_OFFSET_CAPTURE);
	if (count($matches) > 0) {
		return false;
	}
	return true;
}

function mail_syntax_ok($mail) {
	if (empty ($mail))
		return false;
	@ list ($local, $host) = explode("@", $mail);
	$pattern_local = "^([0-9a-z]*([-|_]?[0-9a-z]+)*)(([-|_]?)\.([-|_]?)[0-9a-z]*([-|_]?[0-9a-z]+)+)*([-|_]?)$";
	$pattern_host = "^([0-9a-z]+([-]?[0-9a-z]+)*)(([-]?)\.([-]?)[0-9a-z]*([-]?[0-9a-z]+)+)*\.[a-z]{2,4}$";
	$match_local = eregi($pattern_local, $local);
	$match_host = eregi($pattern_host, $host);

	if ($match_local && $match_host) {
		return true;
	} else {
		return false;
	}
}
// ---------------- SYNTAX TEST FUNCTIONS

// ---------------- TEST FUNCTIONS

function test_ip($ip, $test_result = '') {
	// 1.3.x
}

function test_email($email, $test_result = '') {
	// 1.2.4
	global $db, $lang;
	if ($email != '') {
		$sql = "SELECT ban_email
		                                                                                                                                                        FROM " . BANLIST_TABLE;
		if ($result = $db->sql_query($sql)) {
			if ($row = $db->sql_fetchrow($result)) {
				do {
					$match_email = str_replace('*', '.*?', $row['ban_email']);
					if (preg_match('/^' . $match_email . '$/is', $email)) {
						$db->sql_freeresult($result);
						$test_result .= '<br/>» ' . $lang['Email_banned'];
					}
				} while ($row = $db->sql_fetchrow($result));
			}
		}
		$db->sql_freeresult($result);
	}
	return $test_result;
}

function test_username($username, $test_result = '') {
	// 1.2.4
	global $db, $lang;
	$sql = "SELECT disallow_username FROM " . DISALLOW_TABLE;
	if ($result = $db->sql_query($sql)) {
		if ($row = $db->sql_fetchrow($result)) {
			do {
				if (preg_match("#\b(" . str_replace("\*", ".*?", preg_quote($row['disallow_username'], '#')) . ")\b#i", $username)) {
					$test_result .= '<br/>» ' . $lang['Username_disallowed'];
				}
			} while ($row = $db->sql_fetchrow($result));
		}
	}
	$db->sql_freeresult($result);
	$sql = "SELECT word FROM  " . WORDS_TABLE;
	if ($result = $db->sql_query($sql)) {
		if ($row = $db->sql_fetchrow($result)) {
			do {
				if (preg_match("#\b(" . str_replace("\*", ".*?", preg_quote($row['word'], '#')) . ")\b#i", $username)) {
					$test_result .= '<br/>» ' . $lang['Username_disallowed'];
				}
			} while ($row = $db->sql_fetchrow($result));
		}
	}
	$db->sql_freeresult($result);
	return $test_result;
}
// ---------------- TEST FUNCTIONS

// ---------------- STANDALONE BOARD CONFIG
function grab_boardconfig() {
	global $db, $board_config;

	// Original lines from common.php
	$sql = "SELECT * FROM " . CONFIG_TABLE;
	if (!($result = $db->sql_query($sql))) {
		message_die(CRITICAL_ERROR, "Could not query config information", "", __LINE__, __FILE__, $sql);
	}

	while ($row = $db->sql_fetchrow($result)) {
		$board_config[$row['config_name']] = $row['config_value'];
	}
	// Original lines from common.php
	return $board_config;
}
// ---------------- STANDALONE BOARD CONFIG

// ---------------- GLOBAL MAIL FUNCTIONS
function get_serverurl($path = '') {
	global $board_config;
	// 1.2.7
	// Used and slightly modified from Phpbb2 profile.php
	// Lines 61 till 67
	$script_name = preg_replace('/^\/?(.*?)\/?$/', '\1', trim($board_config['script_path']));
	$script_name = ($script_name != '') ? $script_name . '/' . $path : $path;
	$server_name = trim($board_config['server_name']);
	$server_protocol = ($board_config['cookie_secure']) ? 'https://' : 'http://';
	$server_port = ($board_config['server_port'] <> 80) ? ':' . trim($board_config['server_port']) . '/' : '/';

	$server_url = $server_protocol . $server_name . $server_port . $script_name;
	return $server_url;
}

// ---------------- GLOBAL MAIL FUNCTIONS
// Ramon Fincken, antispam
?>
Return current item: Phpbbantispam