diff --git a/SQL/database_changelog.txt b/SQL/database_changelog.txt index e142f20cfabf7..9835d792f6e46 100644 --- a/SQL/database_changelog.txt +++ b/SQL/database_changelog.txt @@ -1,3 +1,16 @@ +16th April 2016 + +Added ipintel table, only required if ip intel is enabled in the config + +CREATE TABLE `ipintel` ( +`ip` INT UNSIGNED NOT NULL , +`date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL , +`intel` REAL NOT NULL DEFAULT '0', +PRIMARY KEY ( `ip` ) +) ENGINE = INNODB; + +--------------------------------------------------- + 21 September 2015, by Jordie0608 Modified table 'poll_question', adding columns 'createdby_ckey', 'createdby_ip' and 'for_trialmin' to bring it inline with the schema used by the tg servers. diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql index 7fb896d93a688..72d08af90f710 100644 --- a/SQL/tgstation_schema.sql +++ b/SQL/tgstation_schema.sql @@ -369,7 +369,7 @@ DROP TABLE IF EXISTS `ipintel`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `ipintel` ( `ip` INT UNSIGNED NOT NULL , -`date` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL , +`date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL , `intel` REAL NOT NULL DEFAULT '0', PRIMARY KEY ( `ip` ) ) ENGINE = INNODB; diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql index c5bbd407125c3..ab49b337cf345 100644 --- a/SQL/tgstation_schema_prefixed.sql +++ b/SQL/tgstation_schema_prefixed.sql @@ -364,9 +364,9 @@ DROP TABLE IF EXISTS `SS13_ipintel`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `SS13_ipintel` ( `ip` INT UNSIGNED NOT NULL , -`date` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL , +`date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL , `intel` REAL NOT NULL DEFAULT '0', PRIMARY KEY ( `ip` ) ) ENGINE = INNODB; - +/*!40101 SET character_set_client = @saved_cs_client */; -- Dump completed on 2013-03-24 18:02:35 diff --git a/code/controllers/subsystem/ipintel.dm b/code/controllers/subsystem/ipintel.dm new file mode 100644 index 0000000000000..ecfb6c928f547 --- /dev/null +++ b/code/controllers/subsystem/ipintel.dm @@ -0,0 +1,18 @@ +var/datum/subsystem/ipintel/SSipintel + +/datum/subsystem/ipintel + name = "IP Intel" + priority = -3 + var/enabled = 0 //disable at round start to avoid checking reconnects + var/throttle = 0 + var/errors = 0 + + var/list/cache = list() + +/datum/subsystem/ipintel/New() + NEW_SS_GLOBAL(SSipintel) + +/datum/subsystem/ipintel/Initialize(timeofday, zlevel) + enabled = 1 + . = ..() + diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index fb320a66c0284..6b7f75a81dfc1 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -99,7 +99,7 @@ log_access("Failed Login: [key] [computer_id] [address] - Banned [.["reason"]]") return . - if (config.ipintel_email) + if (config.ipintel_email && SSipintel.enabled) var/datum/ipintel/res = get_ip_intel(address) if (res.intel > config.ipintel_rating_max) if (admin) diff --git a/code/modules/admin/ipintel.dm b/code/modules/admin/ipintel.dm index 58a69267a54dc..8b6a156686682 100644 --- a/code/modules/admin/ipintel.dm +++ b/code/modules/admin/ipintel.dm @@ -4,39 +4,61 @@ var/cache = FALSE var/cacheminutesago = 0 var/cachedate = "" + var/cacherealtime = 0 + /datum/ipintel/New() cachedate = SQLtime() + cacherealtime = world.realtime + +/datum/ipintel/proc/is_valid() + . = FALSE + if (intel < 0) + return + if (intel <= config.ipintel_rating_max) + if (world.realtime < cacherealtime+(config.ipintel_save_good*60*60*10)) + return TRUE + else + if (world.realtime < cacherealtime+(config.ipintel_save_bad*60*60*10)) + return TRUE + /proc/get_ip_intel(ip, bypasscache = FALSE, updatecache = TRUE) var/datum/ipintel/res = new() res.ip = ip . = res - if (!ip || !config.ipintel_email) + if (!ip || !config.ipintel_email || !SSipintel.enabled) return - if (!bypasscache && establish_db_connection()) - var/DBQuery/query = dbcon.NewQuery("SELECT date,intel,TIMESTAMPDIFF(MINUTE,date,NOW()) FROM [format_table_name("ipintel")] WHERE ip = INET_ATON('[ip]') AND ((intel <= [config.ipintel_rating_max] AND date + INTERVAL [config.ipintel_save_good] HOUR > NOW()) OR (intel > [config.ipintel_rating_max] AND date + INTERVAL [config.ipintel_save_bad] HOUR > NOW()))") - query.Execute() - if (query.NextRow()) - res.cache = TRUE - res.cachedate = query.item[1] - res.intel = query.item[2] - res.cacheminutesago = query.item[3] - return + if (!bypasscache) + var/datum/ipintel/cachedintel = SSipintel.cache[ip] + if (cachedintel && cachedintel.is_valid()) + cachedintel.cache = TRUE + return cachedintel + + if (establish_db_connection()) + var/DBQuery/query = dbcon.NewQuery("SELECT date, intel, TIMESTAMPDIFF(MINUTE,date,NOW()), UNIX_TIMESTAMP(date) FROM [format_table_name("ipintel")] WHERE ip = INET_ATON('[ip]') AND ((intel <= [config.ipintel_rating_max] AND date + INTERVAL [config.ipintel_save_good] HOUR > NOW()) OR (intel > [config.ipintel_rating_max] AND date + INTERVAL [config.ipintel_save_bad] HOUR > NOW()))") + query.Execute() + if (query.NextRow()) + res.cache = TRUE + res.cachedate = query.item[1] + res.intel = query.item[2] + res.cacheminutesago = query.item[3] + res.cacherealtime = query.item[4]*10 + SSipintel.cache[ip] = res + return res.intel = ip_intel_query(ip) if (updatecache && res.intel >= 0 && establish_db_connection()) - //if you're wondering, we don't add or update the date as its a TIMESTAMP field, and as such, automatically updates at any insert or update - var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("ipintel")] (ip, intel) VALUES (INET_ATON('[ip]'), [res.intel]) ON DUPLICATE KEY UPDATE intel = VALUES(intel)") + SSipintel.cache[ip] = res + var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("ipintel")] (ip, intel) VALUES (INET_ATON('[ip]'), [res.intel]) ON DUPLICATE KEY UPDATE intel = VALUES(intel), date = NULL") query.Execute() return -var/ip_intel_throttle = 0 -var/ip_intel_errors = 0 + /proc/ip_intel_query(ip, var/retry=0) . = -1 //default if (!ip) return - if (ip_intel_throttle > world.timeofday) + if (SSipintel.throttle > world.timeofday) return var/http[] = world.Export("http://check.getipintel.net/check.php?ip=[ip]&contact=[config.ipintel_email]&format=json") @@ -72,9 +94,9 @@ var/ip_intel_errors = 0 /proc/ipintel_handle_error(error, ip, retry) if (retry) - ip_intel_errors++ - error += " Could not check [ip]. Disabling IPINTEL for [ip_intel_errors] minute[( ip_intel_errors == 1 ? "" : "s" )]" - ip_intel_throttle = world.timeofday + (10 * 60 * ip_intel_errors) + SSipintel.errors++ + error += " Could not check [ip]. Disabling IPINTEL for [SSipintel.errors] minute[( SSipintel.errors == 1 ? "" : "s" )]" + SSipintel.throttle = world.timeofday + (10 * 60 * SSipintel.errors) else error += " Attempting retry on [ip]." log_ipintel(error) diff --git a/tgstation.dme b/tgstation.dme index b7142475ca627..301e7c4f1bd0d 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -136,6 +136,7 @@ #include "code\controllers\subsystem\fastprocess.dm" #include "code\controllers\subsystem\garbage.dm" #include "code\controllers\subsystem\icon_smooth.dm" +#include "code\controllers\subsystem\ipintel.dm" #include "code\controllers\subsystem\jobs.dm" #include "code\controllers\subsystem\lighting.dm" #include "code\controllers\subsystem\machines.dm"