123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- -- Vps Blocker
- local http = minetest.request_http_api()
- assert(http ~= nil, "You need to add vps_blocker to secure.http_mods")
- local kick_message = minetest.settings:get("vps_kick_message") or "You are using a proxy, vpn or other hosting services, please disable them to play on this server."
- vps_blocker = {}
- local cache = {}
- local storage = minetest.get_mod_storage()
- --[[
- cache of ip == nil not checked yet
- == 1 checked allow
- == 2 checked deny
- ]]
- local checkers = {}
- --[[
- vps_blocker.register_check(check):
- passed check is a array:
- getreq(ip) return req, callback or nil, err for failed
- callback func will get the result of the req and is supposed
- to return true for allow and false for denying the client
- nil, err for failed requests
- active = true
- If the checker is currently working is true by default
- The checker can store any other data inside this table.
- ]]
- function vps_blocker.register_checker(check)
- assert(type(check) == "table")
- check.active = true
- assert(type(check.getreq) == "function")
- -- Dummy testing function:
- local req, call = check.getreq("0.0.0.0")
- assert(type(req) == "table")
- assert(type(req.url == "string"))
- assert(type(call) == "function")
- table.insert(checkers, check)
- end
- -- Load checkers
- dofile(minetest.get_modpath(minetest.get_current_modname()).. "/checker.lua")
- -- Add the main ipcheckup function
- local function check_ip(name, ip, hash)
- -- Loop throught the list of checkers and use one
- local checked = false
- for _, check in pairs(checkers) do
- if check.active then
- local req, call = check.getreq(ip)
- if req then
- function callback(result)
- local pass, err = call(result)
- if pass then
- cache[hash] = 1
- minetest.log("action", "vps_blocker: Passing good-ip-player "..name.." ["..ip.."]")
- elseif pass == false then
- cache[hash] = 2
- minetest.log("action", "vps_blocker: Kicking bad-ip-player "..name.." ["..ip.."]")
- else minetest.log("error", "vps_blocker: Callback-Error "..err.." while checking "..name.." ["..ip.."]!")
- end
- end
- http.fetch(req, callback)
- checked = true
- break
- else minetest.log("error", "vps_blocker: Checker failed to create requests for "..name.." ["..ip.."]!")
- end
- end
- end
- -- Report error if no working was found
- if not checked then
- minetest.log("error", "vps_blocker: No working checker found!")
- end
- end
- -- Add a function which handels what do do(check, kick, nth...)
- function vps_blocker.handle_player(name, ip)
- if not ip or not name then
- return
- end
- local iphash = minetest.sha1(ip)
- if not iphash then
- return
- end
- if cache[iphash] == 1 or storage:get_int(name) == 1 then
- return
- end
- if not cache[iphash] then
- check_ip(name, ip, iphash)
- return
- end
- if cache[iphash] == 2 then
- local player = minetest.get_player_by_name(name)
- if player then
- -- Kick after a server step, to prevent other on_joinplayer to crash
- minetest.after(0, function()
- minetest.kick_player(name, kick_message)
- end)
- else return kick_message
- end
- end
- end
- -- Do handle_player on prejoin and normal join
- minetest.register_on_prejoinplayer(vps_blocker.handle_player)
- minetest.register_on_joinplayer(function(player)
- local name = player:get_player_name()
- local ip = minetest.get_player_ip(name)
- vps_blocker.handle_player(name, ip)
- end)
- -- Add a command to whitelist players
- minetest.register_chatcommand("vps_wl", {
- description = "Allow a player to use vps services.",
- params = "<add or remove> <name>",
- privs = {server=true},
- func = function(name, params)
- local p = string.split(params, " ")
- if p[1] == "add" then
- storage:set_int(p[2], 1)
- return true, "Added "..p[2].." to the whitelist."
- elseif p[1] == "remove" then
- storage:set_int(p[2], 0)
- return true, "Removed "..p[2].." from the whitelist."
- else return false, "Invalid Input"
- end
- end
- })
|