From 4bf5a533b1b2e5b638b73bb68b1aa3be27ca40ba Mon Sep 17 00:00:00 2001 From: mckaygerhard Date: Tue, 20 Jun 2023 11:43:13 -0400 Subject: [PATCH] featured geoip, check if already provided --- README.md | 65 +++++++++++++++++++++++++++ geoip.lua | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ init.lua | 2 +- 3 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 geoip.lua diff --git a/README.md b/README.md index abf1c77..c5c41b7 100644 --- a/README.md +++ b/README.md @@ -16,3 +16,68 @@ etc etc etc CC-BY-SA-NC 4.0 + +it provides geoip mod for minetest + +Lets you resolve geoip requests on a player + +powered by [IP Location Finder by KeyCDN](https://tools.keycdn.com/geo) + +### minetest.conf +``` +# enable curl/http on that mod +secure.http_mods = geoip,governing +``` + +### Commands +``` +/geoip +``` + +### privs + +* `geoip` can make a geoip query + +# Api + +```lua +-- lookup command +governing.lookup("213.152.186.35", function(result) + -- see "Geoip result data" +end) + +-- overrideable callback on player join +governing.joinplayer_callback = function(playername, result) + -- see "Geoip result data" +end +``` + +## Geoip result data +```json +{ + "status": "success", + "description": "Data successfully received.", + "data": { + "geo": { + "host": "213.152.186.35", + "ip": "213.152.186.35", + "rdns": "213.152.186.35", + "asn": 49453, + "isp": "Global Layer B.V.", + "country_name": "Netherlands", + "country_code": "NL", + "region_name": null, + "region_code": null, + "city": null, + "postal_code": null, + "continent_name": "Europe", + "continent_code": "EU", + "latitude": 52.3824, + "longitude": 4.8995, + "metro_code": null, + "timezone": "Europe/Amsterdam", + "datetime": "2021-05-20 08:45:56" + } + } +} +``` diff --git a/geoip.lua b/geoip.lua new file mode 100644 index 0000000..0bc5e24 --- /dev/null +++ b/geoip.lua @@ -0,0 +1,128 @@ +if not governing.geoip then + + minetest.register_privilege("geoip", { + description = "can do geoip lookups on players for governing", + give_to_singleplayer = false + }) +end + +function governing.lookup(ip, callback) + + local http = minetest.request_http_api() + + if not http then + minetest.log("error", "[governing/geoip] mod not in the trusted http mods!") + return + end + + http.fetch({ + url = "https://tools.keycdn.com/geo.json?host=" .. ip, + extra_headers = { + "User-Agent: keycdn-tools:https://minetest.org" + }, + timeout = 1, + }, function(res) + if res.code == 200 and callback then + local data = minetest.parse_json(res.data) + callback(data) + else + minetest.log("warning", "[governing/geoip] http request returned status: " .. res.code) + end + end) +end + +local function format_result(result) + if result and result.status == "success" and result.data and result.data.geo then + local txt = "Geoip result: " + if result.data.geo.country_name then + txt = txt .. " Country: " .. result.data.geo.country_name + end + if result.data.geo.city then + txt = txt .. " City: " .. result.data.geo.city + end + if result.data.geo.timezone then + txt = txt .. " Timezone: " .. result.data.geo.timezone + end + if result.data.geo.asn then + txt = txt .. " ASN: " .. result.data.geo.asn + end + if result.data.geo.isp then + txt = txt .. " ISP: " .. result.data.geo.isp + end + if result.data.geo.ip then + txt = txt .. " IP: " .. result.data.geo.ip + end + return txt + else + return false + end +end + +-- function(name, result) +governing.joinplayer_callback = function() end + +-- query ip on join, record in logs and execute callback +minetest.register_on_joinplayer(function(player) + if not minetest.get_player_ip then + return + end + + local name = player:get_player_name() + local ip = minetest.get_player_ip(name) + if not ip then + return + end + + governing.lookup(ip, function(data) + -- log to debug.txt + local txt = format_result(data) + if txt then + minetest.log("action", "[goberning/geoip] result for player " .. name .. ": " .. txt) + else + minetest.log("error", "[goberning/geoip] result for player " .. name .. ": seems fails for ip "..ip) + end + + -- execute callback + governing.joinplayer_callback(name, data) + end) +end) + +-- manual query +minetest.register_chatcommand("geoip", { + params = "", + privs = {geoip=true}, + description = "Does a geoip lookup on the given player for governing", + func = function(name, param) + + if not param then + return true, "usage: /geoip " + end + + minetest.log("action", "[geoip] Player " .. name .. " queries the player: " .. param) + + if not minetest.get_player_ip then + return true, "minetest.get_player_ip no available!" + end + + local ip = minetest.get_player_ip(param) + + if not ip then + return true, "no ip available!" + end + + governing.lookup(ip, function(result) + local txt = format_result(result) + + if not txt then + minetest.chat_send_player(name, "Geoip error: "..name..":"..ip": " .. (result.description or "unknown error")) + return + end + + minetest.log("action", "[geoip] result for player " .. param .. ": " .. txt) + + minetest.chat_send_player(name, txt) + end) + + + end +}) diff --git a/init.lua b/init.lua index 04d284a..4398440 100644 --- a/init.lua +++ b/init.lua @@ -68,7 +68,7 @@ function governing.is_creative(name) end end ---dofile(governing.modpath.."/geoip.lua") +dofile(governing.modpath.."/geoip.lua") dofile(governing.modpath.."/commands.lua") print("[MOD] governing mod loaded" )