mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 15:17:01 +01:00
ip intel mk2 (#82683)
Do not merge this without coordinating with your server's host. ## About The Pull Request Slightly refactors the way we handle IP intel. You can still use the old data stored in the database. Adds the ability to automatically reject connections determined by config flags. ## Why It's Good For The Game We used to have IP intel to check for VPNs, although it was disabled due to being bad and unhelpful. This refactor should make it much more manageable for hosts and admins. ## HOSTS BEWARE This adds a new SQL table `ipintel_whitelist` Look at the schema! ## Changelog 🆑 admin: The return of IPIntel /🆑 --------- Co-authored-by: MrStonedOne <kyleshome@gmail.com> Co-authored-by: oranges <email@oranges.net.nz>
This commit is contained in:
co-authored by
MrStonedOne
oranges
parent
a300ec3f7b
commit
cbcf5a7108
@@ -1,136 +0,0 @@
|
||||
/datum/ipintel
|
||||
var/ip
|
||||
var/intel = 0
|
||||
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_GET(number/ipintel_rating_bad))
|
||||
if (world.realtime < cacherealtime + (CONFIG_GET(number/ipintel_save_good) * 60 * 60 * 10))
|
||||
return TRUE
|
||||
else
|
||||
if (world.realtime < cacherealtime + (CONFIG_GET(number/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_GET(string/ipintel_email) || !SSipintel.enabled)
|
||||
return
|
||||
if (!bypasscache)
|
||||
var/datum/ipintel/cachedintel = SSipintel.cache[ip]
|
||||
if (cachedintel?.is_valid())
|
||||
cachedintel.cache = TRUE
|
||||
return cachedintel
|
||||
|
||||
if(SSdbcore.Connect())
|
||||
var/rating_bad = CONFIG_GET(number/ipintel_rating_bad)
|
||||
var/datum/db_query/query_get_ip_intel = SSdbcore.NewQuery({"
|
||||
SELECT date, intel, TIMESTAMPDIFF(MINUTE,date,NOW())
|
||||
FROM [format_table_name("ipintel")]
|
||||
WHERE
|
||||
ip = INET_ATON(':ip')
|
||||
AND ((
|
||||
intel < :rating_bad
|
||||
AND
|
||||
date + INTERVAL :save_good HOUR > NOW()
|
||||
) OR (
|
||||
intel >= :rating_bad
|
||||
AND
|
||||
date + INTERVAL :save_bad HOUR > NOW()
|
||||
))
|
||||
"}, list("ip" = ip, "rating_bad" = rating_bad, "save_good" = CONFIG_GET(number/ipintel_save_good), "save_bad" = CONFIG_GET(number/ipintel_save_bad)))
|
||||
if(!query_get_ip_intel.Execute())
|
||||
qdel(query_get_ip_intel)
|
||||
return
|
||||
if (query_get_ip_intel.NextRow())
|
||||
res.cache = TRUE
|
||||
res.cachedate = query_get_ip_intel.item[1]
|
||||
res.intel = text2num(query_get_ip_intel.item[2])
|
||||
res.cacheminutesago = text2num(query_get_ip_intel.item[3])
|
||||
res.cacherealtime = world.realtime - (text2num(query_get_ip_intel.item[3])*10*60)
|
||||
SSipintel.cache[ip] = res
|
||||
qdel(query_get_ip_intel)
|
||||
return
|
||||
qdel(query_get_ip_intel)
|
||||
res.intel = ip_intel_query(ip)
|
||||
if (updatecache && res.intel >= 0)
|
||||
SSipintel.cache[ip] = res
|
||||
if(SSdbcore.Connect())
|
||||
var/datum/db_query/query_add_ip_intel = SSdbcore.NewQuery(
|
||||
"INSERT INTO [format_table_name("ipintel")] (ip, intel) VALUES (INET_ATON(:ip), :intel) ON DUPLICATE KEY UPDATE intel = VALUES(intel), date = NOW()",
|
||||
list("ip" = ip, "intel" = res.intel)
|
||||
)
|
||||
query_add_ip_intel.Execute()
|
||||
qdel(query_add_ip_intel)
|
||||
|
||||
|
||||
/proc/ip_intel_query(ip, retryed=0)
|
||||
. = -1 //default
|
||||
if (!ip)
|
||||
return
|
||||
if (SSipintel.throttle > world.timeofday)
|
||||
return
|
||||
if (!SSipintel.enabled)
|
||||
return
|
||||
|
||||
var/list/http[] = world.Export("http://[CONFIG_GET(string/ipintel_domain)]/check.php?ip=[ip]&contact=[CONFIG_GET(string/ipintel_email)]&format=json&flags=f")
|
||||
|
||||
if (http)
|
||||
var/status = text2num(http["STATUS"])
|
||||
|
||||
if (status == 200)
|
||||
var/response = json_decode(file2text(http["CONTENT"]))
|
||||
if (response)
|
||||
if (response["status"] == "success")
|
||||
var/intelnum = text2num(response["result"])
|
||||
if (isnum(intelnum))
|
||||
return text2num(response["result"])
|
||||
else
|
||||
ipintel_handle_error("Bad intel from server: [response["result"]].", ip, retryed)
|
||||
if (!retryed)
|
||||
sleep(2.5 SECONDS)
|
||||
return .(ip, 1)
|
||||
else
|
||||
ipintel_handle_error("Bad response from server: [response["status"]].", ip, retryed)
|
||||
if (!retryed)
|
||||
sleep(2.5 SECONDS)
|
||||
return .(ip, 1)
|
||||
|
||||
else if (status == 429)
|
||||
ipintel_handle_error("Error #429: We have exceeded the rate limit.", ip, 1)
|
||||
return
|
||||
else
|
||||
ipintel_handle_error("Unknown status code: [status].", ip, retryed)
|
||||
if (!retryed)
|
||||
sleep(2.5 SECONDS)
|
||||
return .(ip, 1)
|
||||
else
|
||||
ipintel_handle_error("Unable to connect to API.", ip, retryed)
|
||||
if (!retryed)
|
||||
sleep(2.5 SECONDS)
|
||||
return .(ip, 1)
|
||||
|
||||
|
||||
/proc/ipintel_handle_error(error, ip, retryed)
|
||||
if (retryed)
|
||||
SSipintel.errors++
|
||||
error += " Could not check [ip]. Disabling IPINTEL for [SSipintel.errors] minute[( SSipintel.errors == 1 ? "" : "s" )]"
|
||||
SSipintel.throttle = world.timeofday + (10 * 120 * SSipintel.errors)
|
||||
else
|
||||
error += " Attempting retry on [ip]."
|
||||
log_ipintel(error)
|
||||
|
||||
/proc/log_ipintel(text)
|
||||
log_game("IPINTEL: [text]")
|
||||
debug_admins("IPINTEL: [text]")
|
||||
Reference in New Issue
Block a user