governing - anticheat - anticrack - client detector - administrator mod

master
mckaygerhard 2023-08-07 04:35:22 -04:00
parent 1d8124043c
commit 7603217477
13 changed files with 1924 additions and 0 deletions

View File

@ -57,6 +57,8 @@ To download you can play this game with the following minetest engines:
* fireflies as `fireflies` [mods/fireflies](mods/fireflies) https://github.com/Ezhh/fireflies/blob/master/license.txt
* Skandarella
* Wilhelmines Marinara as `marinara` [mods/marinara](mods/marinara) https://git.minetest.io/minenux/minetest-mod-marinara forked compatible version
* mckaygerhard
* Governing dictatorchip as `governing` [mods/governing](mods/governing) https://gitlab.com/minenux/minetest-mod-governing
## Licensing

View File

@ -0,0 +1,49 @@
License of source code
----------------------
Copyright (C) 2023 mckaygerhard <mckaygerhard@gmail.com> CC-BY-SA-NC 4.0
Copyright (C) 2023 mckayshirou <mckayshirou@gmail.com> CC-BY-SA-NC 4.0
It applies CC-BY-SA-NC 4.0 unless you ask to request permission
with special conditions. The ipcheck idea, the mod inclusion,
can be distributed if the URL of repo are not altered when promotes.
CC-BY-SA-NC 4.0
===============
Attribution-ShareAlike 4.0 Unported (CC BY-SA 4.0)
http://creativecommons.org/licenses/by-sa/4.0/
You are free to:
* Share — copy and redistribute the material in any medium or format
* Adapt — remix, transform, and build upon the material
The licensor cannot revoke these freedoms as long as you follow
the license terms.
Under the following terms:
* Attribution — You must give appropriate credit, provide a link to
the license, and indicate if changes were made. You may do so in any
reasonable manner, but not in any way that suggests the licensor
endorses you or your use.
* NonCommercial — You may not use the material for commercial purposes.
* ShareAlike — If you remix, transform, or build upon the material,
you must distribute your contributions under the same license as the
original.
* No additional restrictions — You may not apply legal terms or technological
measures that legally restrict others from doing anything the license permits.
Notices:
You do not have to comply with the license for elements of the material in
the public domain or where your use is permitted by an applicable exception
or limitation.
No warranties are given. The license may not give you all of the permissions
necessary for your intended use. For example, other rights such as publicity,
privacy, or moral rights may limit how you use the material.

131
mods/governing/README.md Normal file
View File

@ -0,0 +1,131 @@
minetest mod governing
======================
ADMIN mod, light version of various mods and extra tool for manage server
Information
-----------
@mckaygerhard PICCORO's improvement administration combo and commands for minetest
This mod attempts to be an improvement administration combo, but minimized
as a light version of some other tools like geoip, names-per-ip, antigrif, antihack,
etc etc etc
![](governing.png)
## Technical info
-----------------
This mod must be named `governing` and provides administrarion tools and
procedures to manage server.
This mod features powerfully anticheat tools, mostly mixture of many others,
and are able to detect the modified clients.
Repository : https://git.minetest.io/minenux/minetest-mod-governing
> **Note:** this mod requires that the server have compiled with extra information enabled
#### Configurations
| config param | type | value | req | default/min/mx | example or description |
| --------------------- | ------ | ---------- | --- | --------------- | -------------------------------- |
| secure.http_mods | string | governing | yes | none set | geoip,governing |
| secure.trusted_mods | string | governing | yes | none set | auth_rx,governing |
| governing.checkapikey | string | `<string>` | yes | none set | 177cd4797a4949c4b1114d2e4ab9af11 |
| anticheat.timestep | int | 15 | no | 15 / 10 / 300 | How many time will run checks in seconds |
| anticheat.timeagain | int | 15 | no | 15 / 10 / 300 | How many seconds checks again (to compare) on a suspected player |
| anticheat.moderators | string | admin | yes | admin,singleplayer | Comma separated list name players that can watch and check stats |
| beowulf.dfdetect.enable_kick | boot | false | no | false | will kick the cheater when performs detections |
The `governing.checkapikey` string is requested by registering a free (or paid)
account at https://vpnapi.io/ and **if not configured, will be used a simple geoip request**.
1. its powered by [VPNapi.io IP VPN & Proxy Detection API](https://vpnapi.io/api-documentation)
2. but if apykey is not set, its powered by [IP Location Finder by KeyCDN](https://tools.keycdn.com/geo)
> Warning: anticheat its a WIP from rnd's anticheat mod with beowulf mod fusioned
#### Commands
| command & format | permission | description function | observations |
| --------------------- | --------- | ----------------------- | ----------------------- |
| `/killme` | interact | kill yourselft | no matter if killme mod is present or not |
| `/govip <playername>` | governing | complete ip player info | Will require keyapi configuration set |
| `/geoip <playername>` | geoip | simple ip player info | no matter if geoip mod is present or not |
| `/cstats` | moderator | to see latest detected cheater | its not a privilegie, use config settings |
| `/cdebug` | moderator | to see even suspected cheats to be verified later | its not a privilegie, use config settings |
| `/satiation` | server | manipulates the satiation of a player | only provide if our mod its present, the original mod already has it |
| `/cchk <playername>` | moderator | checks for a cheater player | it send a msh rare to the cheater |
#### privs
* `geoip` can make a geoip query, no matter if geoip mod is present or missing
* `governing` can run administration command like ip check
> Warning: currently moderator its not a privs.. its a list of players names, its a WIP from rnd's anticheat mod with beowulf mod fusioned
#### Api
Currently only geoip functions are exposed, we later exposed antcheat also
```lua
-- lookup command
governing.checkip("213.152.186.35", function(result)
-- see "Check ip information data"
end)
-- overrideable callback on player join
governing.joinplayer_callback = function(playername, result)
-- see "Check ip information result data"
end
```
Check IP information on data:
```json
{
"ip": "8.8.8.8",
"security": {
"vpn": false,
"proxy": false,
"tor": false,
"relay": false,
},
"location": {
"city": "",
"region": "",
"country": "United States",
"continent": "North America",
"region_code": "",
"country_code": "US",
"continent_code": "NA",
"latitude": "37.7510",
"longitude": "-97.8220",
"time_zone": "America/Chicago",
"locale_code": "en",
"metro_code": "",
"is_in_european_union": false
},
"network": {
"network": "8.8.8.0/24",
"autonomous_system_number": "AS15169",
"autonomous_system_organization": "GOOGLE"
}
}
```
## LICENSE
* Copyright (C) 2023 mckaygerhard <mckaygerhard@gmail.com> CC-BY-SA-NC 4.0
* Copyright (C) 2023 mckayshirou <mckayshirou@gmail.com> CC-BY-SA-NC 4.0
* Copyright 2016-2017 rnd LGPL v3 for anticheat code of minetest 0.4 engines
* Copyright 2021-2023 BuckarooBanzay MIT for beowulf code of mt-mods
It applies CC-BY-SA-NC 4.0 unless you ask to request permission
with special conditions. The ipcheck idea, the mod inclusion,
can be distributed if the URL of repo are not altered when promotes.
URL : https://git.minetest.io/minenux and http://minetest.org

View File

@ -0,0 +1,926 @@
-------------------------------------------------------------------------
-- ANTI PRIVS detects if a custom client without interacting "zips" around the map
-- Copyright (c) 2021 mt-mods/BuckarooBanzay MIT
-- Copyright 2020-2023 improvements and few fixes, mckaygerhard CC-BY-SA-NC 4.0
-------------------------------------------------------------------------
-- per-player data
local player_data = {}
local is_player = function(player)
-- a table being a player is also supported because it quacks sufficiently
-- like a player if it has the is_player function
local t = type(player)
return (t == "userdata" or t == "table") and type(player.is_player) == "function"
end
-- obtain player data cheats, improved respect beowulf with missing checks and methods
local function get_player_data(name)
local player = minetest.get_player_by_name(name)
if not player_data[name] then
player_data[name] = {
fliyers = 0, -- number of checks for fly ( added only with governing)
strikes = 0, -- number of "strikes" (odd movements)
checked = 0, -- number of checks
pre_pos = player:get_pos() -- position track (missing in beowulf as bug)
}
end
return player_data[name]
-- WARNING pos its always current so checked must be after an interval using callbacks
end
-- clear player data for cheats
local function track_player_clear(player)
if is_player(player) then
if player:get_player_name() then
player_data[player:get_player_name()] = nil
end
end
end
-- store player data cheats strikes and checks
local function track_player(player)
if not is_player(player) then return end
local name = player:get_player_name()
local data = get_player_data(name)
local pos = player:get_pos()
if data.pre_pos then
-- compare positions
local d = vector.distance(pos, data.pre_pos)
if d > 200 then
data.strikes = data.strikes + 1
end
data.checked = data.checked + 1
end
if data.checked >= 10 then
-- check strike-count after 10 movement checks
if data.strikes > 8 then
-- suspicious movement, log it
-- TODO: if this doesn't yield any false-positives, add a kick/ban option
local msg = "suspicious movement detected for player: '" .. name .. "'"
minetest.log("action", "[governing][beowulf] " .. msg)
end
-- reset counters
data.checked = 0
data.strikes = 0
end
-- store current position
data.pre_pos = pos
end
-----------------------------------------------------------------------
-- ANTI CRACKERS and CHEATERS by mckaygerhard based on beowulf
------------------------------------------------------------------------
-- luacheck: push no max line length
local df = {
"2.0",
"dragonfire", -- many based clients by example teamclient
"f8fd5c11b", -- Merge pull request #59 from PrairieAstronomer/readme_irrlicht_change
"c66ae6717", -- Add exact irrlichtmt version to the clone command
"296cce39d", -- Fix upstream merge issues
"350b6d175", -- Install lua_async dependency
"393c83928", -- Don't include client/game.h on server build
"ccd4c504d", -- Ship dragonfireclient with selected high-quality mods
"147aaf326", -- Fix build instructions
"b09fc5de5", -- Add spider
"d404517d2", -- Make LuaVoxelManipulator available to CSM API
"1ccf88e80", -- minetest.dig_node: Remove node
"950d2c9b3", -- Add ClientObjectRef:remove and return true in on_object_add callback to remove newly added object
"fb4815c66", -- Merge pull request #35 from arydevy/patch-1
"f12288814", -- Merge pull request #42 from Minetest-j45/master
"f3082146c", -- remove irrlicht from lid dir (accident)
"a3925db22", -- add airjump and remove unused headers
"7824a4956", -- Merge pull request #1 from EliasFleckenstein03/master
"35445d24f", -- Make set_pitch and set_yaw more accurate by not rounding it to integers
"5131675a6", -- Add guards to stop server build fail
"96a37aed3", -- Add minetest.get_send_speed
"d08242316", -- Fix format
"ce0d81a82", -- Change default cheat menu entry height
"b7abc8df2", -- Add on_object_add callback
"4f613bbf5", -- Include tile definitions in get_node_def; Client-side minetest.object_refs table
"c86dcd0f6", -- Add on_object_hp_change callback and nametag images
"b84ed7d0b", -- Call on_object_properties_change callback when adding object to scene
"26cfbda65", -- Add on_object_properties_change callback
"6dc7a65d9", -- Add ClientObjectRef:set_properties
"7d7d4d675", -- Add ClientObjectRef.get_properties
"ea8fa30b6", -- Changed README.md to fit the dragonfire client
"c47eae316", -- Add table.combine to luacheckrc
"83d09ffaf", -- Complete documentation
"e0b4859e7", -- Add ClientObjectRef:remove
"63f7c96ec", -- Fix legit_speed
"5c06763e8", -- Add noise to client CSM API
"7613d9bfe", -- Update .wielded command to output the entire itemstring; add LocalPlayer:get_hotbar_size
"bc79c2344", -- CSM: Use server-like (and safe) HTTP API instead of Mainmenu-like
"166968232", -- Port formspec API from waspsaliva This API is inofficial and undocumented; invalid usage causes the game to crash. Use at own risk!
"e391ee435", -- Forcefully place items when minetest.place_node is used
"546ab256b", -- Update buildbot to new MineClone2 repo and set the game name to MineClone2 rather than mineclone2
"d3780cefd", -- Attempt to fix SEGFAULT in push_inventory
"d1c84ada2", -- Merge minetest changes
"74f5f033e", -- Add Custom version string
"b2f629d8d", -- Logo improvements
"78b7d1019", -- Add dragonfire logo
"19e0528e3", -- Add minetest.get_nearby_objects
"47d0882cc", -- Fix line containing only whitespace
"4fedc3a31", -- Add minetest.interact
"dc67f669e", -- Make the Cheat Menu size configureable
"906845a87", -- Add minetest.registered_items and minetest.registered_nodes (Doesn't do anything yet)
"3a4325902", -- Fixed crash by adding legacy stuff to defaultsettings (for now)
"53c991c5f", -- Fixed crash due to missing entry in defaultsettings.cpp
"0c6e0c717", -- Reorganize categories
"e8faa2afb", -- Rework Range
"a4d914ba2", -- Make GitHub Actions Happy try 3
"a34c61093", -- Make GitHub Actions Happy try 2
"f783f5939", -- Make GitHub Actions Happy try 1
"8b58465aa", -- Remove obsolete code from clientenvironment
"35c15567a", -- Update builtin/settingtypes.txt to the new philosophy
"0c9e7466e", -- New Cheat Philosophy
"a1e61e561", -- World Cheats improvements; Add BlockLava; Readd minetest.request_http_api for Compatibility
"56d536ea5", -- Update CheatDB URL again
"ce47003cc", -- Update defaults for ContentDB (->CheatDB)
"89995efee", -- CheatDB Support & Enable/Disable CSMs in Main Menu
"3df23e23c", -- Small AutoTool Fix
"8b3eaf5b0", -- Lua API: Particle callbacks; Add NoWeather
"0a285dd33", -- Remove NextItem
"4695222bc", -- Fix and Improve AutoTool
"5bead7daa", -- Added minetest.close_formspec
"f825cf0e3", -- Fixed Minimap position
"eaa8a5132", -- Fixed FastPlace and AutoPlace
"b4e475726", -- Added configureable Colors for PlayerESP and EntityESP
"549025f6a", -- EntityESP, EntityTracers, PlayerESP, PlayerTracers
"eb6aca8b4", -- Merged Minetest
"8de51dae9", -- Fixed crash when attempting to access nonexistant inventory from Lua API
"a65251a7a", -- Fixed glowing GenericCAOs being rendered completely back when Fullbright is enabled
"eaec3645b", -- Added ClientObjectRef:get_hp()
"fb4d54ee3", -- Added minetest.register_on_play_sound
"50629cc6a", -- Improved Scaffold
"3d74e17cc", -- Added AutoSlip (-> Credit to Code-Sploit)
"f9c632466", -- Added JetPack and AutoHit (-> Credits to Code-Sploit and cora)
"843239c0b", -- Added Speed/Jump/Gravity Override
"598e9bdbc", -- Update Credits
"7d327def8", -- Improved AutoSneak
"82216e147", -- LocalPlayer:set_physics_override; minetest.register_on_recieve_physics_override
"4dd5ecfc5", -- Added setpitch & setyaw commands; AutoSprint
"b65db98bd", -- Added OnlyTracePlayers
"e16bbc1fb", -- Merge pull request #14 from corarona/master
"1780adeea", -- lua-api: fix get/set_pitch
"3e7c5d720", -- Possibility to use cheat menu while pressing other keys
"0aa63aafc", -- Fixed warning
"9db80fc6f", -- Run Lint Script
"91ad0d049", -- Merge pull request #10 from corarona/master
"6bda686c0", -- MapBlockMesh Performance Improvement
"1bab49049", -- add LUA_FCT
"6efa8a758", -- add g/s pitch and make_screenshot in lua api
"46237330d", -- Several Enhancements
"60a9ff6ff", -- api-screenshot: change function name to make_screenshot
"1f56317d5", -- Added NodeESP
"75ecaa217", -- Fix and run the Lint autocorrect script
"6ccb5835f", -- Revert "Make Lint Happy"
"244713971", -- Added script that automaticall corrects lint style
"07e61e115", -- Fix github build problems #3
"3af10766f", -- Fix github build problems #2
"16d302c9a", -- Fix github build problems
"ad148587d", -- Make Lint Happy
"1145b05ea", -- Updated Credits
"c9221730d", -- Updated Cheat Menu Color Design
"1799d5aa9", -- Cheat Menu Improvements Change
"fba7dc216", -- Merge pull request #8 from realOneplustwo/master
"a7dc1135e", -- Added CheatHUD
"f1d9ac014", -- Moved Killaura to Lua; Added ForceField; Added Friendlist; Added ClientObjectRef:is_local_player(); Documented LocalPlayer:get_object()
"06b72069d", -- Fixed ColorChat
"62958bd60", -- Reverted accidental commit in wrong repo
"00d51fbd5", -- Armor textures support
"7cbe42b1d", -- Re-Added Chat Effects
"28f6a7970", -- lua api: add set/get_pitch
"4f9797b6e", -- lua api: add core.take_screenshot()
"8e9e76a50", -- Revert "Add Block Formspec Hack"
"6652d7ac2", -- Add Block Formspec Hack
"8bc7d49b3", -- Added Nuke
"62cf9b466", -- Fix compile error
"519f98c65", -- Merge pull request #3 from JosiahWI/ui_revamp
"f236476af", -- Fix errors in cheatMenu.
"7af3dee31", -- Merge pull request #2 from JosiahWI/ui_revamp
"ea88dde4b", -- Added Strip, AutoRefill, indexing for InventoryActions and Wield Index starts at 1 now
"7aff09ab2", -- Fix overindent!
"aea9b36ef", -- Improved Colours
"1ef72ad9c", -- Fix indentation style.
"586241008", -- Add missing return.
"b211e90ff", -- Prepare cheatMenu::draw function for easier UI changes.
"e22e334e9", -- Merge pull request #1 from JosiahWI/ui_revamp
"f605308ee", -- Improve drawEntry.
"130d476f6", -- Changed Cheat Menu UI
"f1ff05bf5", -- Added ThroughWalls, InventoryActions API and AutoTotem
"1a7d3d818", -- Extended ClientObjectRef; Improved CrystalPvP
"1e4f35492", -- This is the last try for lint...
"7e0f8fba0", -- Another Lint commit
"151e5782e", -- Lint is still not happy...
"28a560684", -- Added the API additions from waspsaliva
"c1aea404b", -- Lint is bitch
"3a718f12b", -- Make lint happy; Remove stupid redirector
"3b596a96e", -- Fixed Github build problems
"847198edb", -- Edited .gitignore properly; fixed armor invulnarability in the server code.
"bbcd24954", -- New Mod System
"80f416d51", -- Added AttachmentFloat
"cb1915efa", -- Added minetest.drop_selected_item(), Improved AutoEject
"43ee069db", -- Improved X-Ray, added AutoEject
"faa32610e", -- Added ESP, fixed Tracers, improved Jesus
"ee88f4b94", -- Improved Tracers
"c36ff3edb", -- Added AutoSneak and improved X-Ray MapBlock updating
"0a2c90f4c", -- Only draw tracers to objects that are not attached (that fixes tracers to armor)
"044a12666", -- Added Tracers, NoSlow and NoForceRotate; GUI Colors changed
"b9f8f0a23", -- The Robot Update
"af085acbd", -- Added Schematicas
"0730ed216", -- Delete my stupid test mod lol
"772c9629e", -- Unrestricted HTTP API for Client, Server and Main Menu
"9b1030cac", -- Added minetest.get_inventory(location)
"2321e3da4", -- Removed console output spammed by minetest.find_node_near
"90f66dad8", -- Removed experimental code
"8b4d27141", -- Fixed typo in clientmods/inventory/mod.conf
"d8b8c1d31", -- Added Documentation for Additional API
"6e6c68ba0", -- Added Chat Spam, Replace and settingtypes.txt for Clientmods
"79d0314d7", -- Update Buildbots
"770bde9c6", -- idk
"e245151c5", -- Improved World hacks
"19205f6b3", -- Improved World Hacks, added API functions
"73b89703f", -- Improved World hacks, added fill
"248dedaba", -- Added floationg water to BlockWater
"9dc3eb777", -- Fixed broken Chatcommands
"80371bc16", -- Added .listwarps
"1c29f21e0", -- Imporoved set_wield_index() to include camera update
"3bed0981d", -- UI Update; Added AutoTool
"622d54726", -- Added DestroyWater (:P anon)
"9019e18b9", -- Some Updates
"107dec6c0", -- Added Coords
"f1760622e", -- Added BrightNight
"2675bcca1", -- Added more cheats
"3d980cf57", -- Improved Xray and Fullbright
"f7a042223", -- Added cheat Menu
"344fddc17", -- Improved Killaura and Chat position
"678559bb6", -- removed leagcy clientmods
"9194165cf", -- Added autodig, moved chat
"064c25caa", -- Added EntitySpeed
"5a8610c2f", -- Added customizable keybindings, improved freecam, added special inventory keybind (by default ender inventory)
"83f59484d", -- Fixed 5.4.0-dev build
"ffe3c2ae0", -- Update to minetest 5.4.0-dev
"45aa2516b", -- Added settings
"f22339ed8", -- Removed fast killaura
"408e39a1d", -- Added Anti Knockback
"eee0f960b", -- Removed minetest.conf.old
"39d7567c1", -- Fixed Crash
"305e0e0d3", -- Auto disable smooth lighting when fullbright is active
"6796baec6", -- Defaultsettings
"5a2bf6634", -- Added Clientmods
"e610149c0", -- Initial Commit
"68f9263a2", -- Hacked Client
"90d885506", -- GalwayGirl Client
}
--[[
To update commit list: save commit logs for master branches of minetest in mt.log and dragonfire in df.log
$ git log --oneline origin/master > mt.log; git log --oneline dragonfire/master > df.log (both in same remo using git remote)
Find and drop commits that seems to exist in both remotes, print rest of it:
$ sort -k3 <(awk '{print NR" "$0}' df.log mt.log mt.log) | uniq -uf2 | sort -nk1 | sed -r 's/^[^ ]+ ([^ ]+) (.*)$/\t"\1", -- \2/'
Replace above entries with output
--]]
local function dfver(stringversion)
-- loop into table of commmits and find the compared version
for _,v in ipairs(df) do
local pp = stringversion:find(v)
if pp then
return v
end
end
end
-------------------------------------------------------------------------
-- ANTI CHEAT for MT4 and old MT5 engines by rnd
-- Copyright 2016 rnd LGPL v3
-- Copyright 2020-2023 improvements and few fixes, mckaygerhard CC-BY-SA-NC 4.0
-------------------------------------------------------------------------
local cheat = {};
local version = "09/08/2017";
anticheatsettings = {};
anticheatsettings.moderators = {}
anticheatsettings.CHEAT_TIMESTEP = tonumber(minetest.settings:get("governing.timestep")) or 15; -- check timestep all players
anticheatsettings.CHECK_AGAIN = tonumber(minetest.settings:get("governing.timeagain")) or 15; -- after player found in bad position check again after this to make sure its not lag, this should be larger than expected lag in seconds
anticheatsettings.STRING_MODERA = minetest.settings:get("governing.moderators") or "admin,singleplayer";
-- moderators list, those players can use cheat debug and will see full cheat message
for str in string.gmatch(anticheatsettings.STRING_MODERA, "([^,]+)") do table.insert(anticheatsettings.moderators, str) end
local CHEAT_TIMESTEP = anticheatsettings.CHEAT_TIMESTEP;
local CHECK_AGAIN = anticheatsettings.CHECK_AGAIN;
cheat.moderators = anticheatsettings.moderators;
bonemod = minetest.get_modpath("boneworld")
anticheatdb = {}; -- data about detected cheaters
cheat.suspect = "";
cheat.players = {}; -- temporary cheat detection db
cheat.message = "";
cheat.debuglist = {}; -- [name]=true -- who gets to see debug msgs
cheat.scan_timer = 0; -- global scan of players
cheat.stat_timer = 0; -- used to collect stats
cheat.nodelist = {};
cheat.timestep = CHEAT_TIMESTEP;
-- list of forbidden nodes
cheat.nodelist = {["default:stone"] = false, ["default:cobble"]= false, ["default:dirt"] = false, ["default:sand"]=false,["default:tree"]= false};
local punish_cheat = function(name)
local player = minetest.get_player_by_name(name);
local ip = tostring(minetest.get_player_ip(name));
if not player then return end
local text=""; local logtext = "";
if cheat.players[name].cheattype == 1 then
text = "#anticheat: ".. name .. " was caught walking inside wall";
logtext = os.date("%H:%M.%S").." #anticheat: ".. name .. " was caught walking inside wall at " .. minetest.pos_to_string(cheat.players[name].cheatpos);
--player:set_hp(0);
elseif cheat.players[name].cheattype == 2 then
local gravity = player:get_physics_override().gravity; if gravity<1 then return end
logtext= os.date("%H:%M.%S").." #anticheat: ".. name .. " was caught flying at " .. minetest.pos_to_string(cheat.players[name].cheatpos);
if cheat.players[name].cheatpos.y>5 then -- only above height 5 it directly damages flyer
text = "#anticheat: ".. name .. " was caught flying";
--player:set_hp(0);
end
end
if text~="" then
minetest.chat_send_all(text);
end
if logtext~="" then
minetest.log("action", logtext);
cheat.message = logtext;
anticheatdb[ip] = {name = name, msg = logtext};
cheat.players[name].count=0; -- reset counter
cheat.players[name].cheattype = 0;
for namem,_ in pairs(cheat.moderators) do -- display full message to moderators
minetest.chat_send_player(namem,logtext);
end
end
end
-- CHECKS
-- DETAILED NOCLIP CHECK
local check_noclip = function(pos)
local nodename = minetest.get_node(pos).name;
local clear=true;
if nodename ~= "air" then -- check if forbidden material!
clear = cheat.nodelist[nodename]; -- test clip violation
if clear == nil then clear = true end
end
if not clear then -- more detailed check
local anodes = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+1, z=pos.z+1}, {"air"});
if #anodes == 0 then return false end
clear=true;
end
return clear;
end
-- DETAILED FLY CHECK
local check_fly = function(pos) -- return true if player not flying
local fly = (minetest.get_node(pos).name=="air" and minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}).name=="air"); -- prerequisite for flying is this to be "air", but not sufficient condition
if not fly then return true end;
local anodes = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y, z=pos.z+1}, {"air"});
if #anodes == 18 then -- player standing on air?
return false
else
return true
end
end
local round = function (x)
if x > 0 then
return math.floor(x+0.5)
else
return -math.floor(-x+0.5)
end
end
--main check routine
local check_player = function(player)
local name = player:get_player_name();
local privs = minetest.get_player_privs(name).kick;if privs then return end -- dont check moderators
local pos = player:getpos(); -- feet position
pos.x = round(pos.x*10)/10;pos.z = round(pos.z*10)/10; -- less useless clutter
pos.y = round(pos.y*10)/10; -- minetest buggy collision - need to do this or it returns wrong materials for feet position: aka magic number 0.498?????228
if pos.y<0 then pos.y=pos.y+1 end -- weird, without this it fails to check feet block where y<0, it checks one below feet
local nodename = minetest.get_node(pos).name;
local clear=true;
if nodename ~= "air" then -- check if forbidden material!
clear = cheat.nodelist[nodename]; -- test clip violation
if clear == nil then clear = true end
end
local fly = (nodename=="air" and minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}).name=="air"); -- prerequisite for flying, but not sufficient condition
if cheat.players[name].count == 0 then -- player hasnt "cheated" yet, remember last clear position
cheat.players[name].clearpos = cheat.players[name].lastpos
end
-- manage noclip cheats
if not clear then -- player caught inside walls
local moved = (cheat.players[name].lastpos.x~=pos.x) or (cheat.players[name].lastpos.y~=pos.y) or (cheat.players[name].lastpos.z~=pos.z);
if moved then -- if player stands still whole time do nothing
if cheat.players[name].count == 0 then cheat.players[name].cheatpos = pos end -- remember first position where player found inside wall
if cheat.players[name].count == 0 then
minetest.after(CHECK_AGAIN+math.random(5),
function()
cheat.players[name].count = 0;
if not check_noclip(pos) then
punish_cheat(name)-- we got a cheater!
else
cheat.players[name].count = 0; -- reset
cheat.players[name].cheattype = 0;
end
end
)
end
if cheat.players[name].count == 0 then -- mark as suspect
cheat.players[name].count = 1;
cheat.players[name].cheattype = 1;
end
end
end
-- manage flyers
if fly then
local fpos;
fly,fpos = minetest.line_of_sight(pos, {x = pos.x, y = pos.y - 4, z = pos.z}, 1); --checking node maximal jump height below feet
if fly then -- so we are in air, are we flying?
if player:get_player_control().sneak then -- player sneaks, maybe on border?
--search 18 nodes to find non air
local anodes = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y, z=pos.z+1}, {"air"});
if #anodes < 18 then fly = false end
end -- if at this point fly = true means player is not standing on border
if pos.y>=cheat.players[name].lastpos.y and fly then -- we actually didnt go down from last time and not on border
-- was lastpos in air too?
local lastpos = cheat.players[name].lastpos;
local anodes = minetest.find_nodes_in_area({x=lastpos.x-1, y=lastpos.y-1, z=lastpos.z-1}, {x=lastpos.x+1, y=lastpos.y, z=lastpos.z+1}, {"air"});
if #anodes == 18 then fly = true else fly = false end
if fly then -- so now in air above previous position, which was in air too?
if cheat.players[name].count == 0 then cheat.players[name].cheatpos = pos end -- remember first position where player found "cheating"
if cheat.players[name].count == 0 then
minetest.after(CHECK_AGAIN,
function()
cheat.players[name].count = 0;
if not check_fly(pos) then
punish_cheat(name)-- we got a cheater!
else
cheat.players[name].count = 0;
cheat.players[name].cheattype = 0;
end
end
)
end
if cheat.players[name].count == 0 then -- mark as suspect
cheat.players[name].count = 1;
cheat.players[name].cheattype = 2;
end
end
end
end
end
cheat.players[name].lastpos = pos
end
minetest.register_globalstep(function(dtime)
cheat.scan_timer = cheat.scan_timer + dtime
-- GENERAL SCAN OF ALL PLAYERS
if cheat.scan_timer>cheat.timestep then
cheat.stat_timer = cheat.stat_timer + cheat.timestep;
-- dig xp stats every 2 minutes
if bonemod and cheat.stat_timer>120 then
cheat.stat_timer = 0;
local players = minetest.get_connected_players();
for _,player in pairs(players) do
local pname = player:get_player_name();
if cheat.players[pname].stats.state == 1 then -- only if dig xp loaded to prevent anomalous stats
if boneworld.digxp[pname] then
local deltadig = cheat.players[pname].stats.digxp;
cheat.players[pname].stats.digxp = boneworld.digxp[pname];
deltadig = boneworld.digxp[pname]-deltadig;
cheat.players[pname].stats.deltadig = deltadig;
if deltadig>cheat.players[pname].stats.maxdeltadig then
cheat.players[pname].stats.maxdeltadig = deltadig;
end
if deltadig>2 then -- unnaturally high deltadig
local ip = tostring(minetest.get_player_ip(pname));
local logtext = os.date("%H:%M.%S") .. " #anticheat: " .. pname .. " (ip " .. ip .. ") is mining resources too fast, deltadig " .. deltadig;
anticheatdb[ip] = {name = pname, msg = logtext};
minetest.log("action", logtext);
end
end
end
end
end
cheat.timestep = CHEAT_TIMESTEP + (2*math.random()-1)*2; -- randomize step so its unpredictable
cheat.scan_timer=0;
--local t = minetest.get_gametime();
local players = minetest.get_connected_players();
for _,player in pairs(players) do
check_player(player);
end
for name,_ in pairs(cheat.debuglist) do -- show suspects in debug
for _,player in pairs(players) do
local pname = player:get_player_name();
if cheat.players[pname].count>0 then
minetest.chat_send_player(name, "name " .. pname .. ", cheat pos " .. minetest.pos_to_string(cheat.players[pname].cheatpos) .. " last clear pos " .. minetest.pos_to_string(cheat.players[pname].clearpos) .. " cheat type " .. cheat.players[pname].cheattype .. " cheatcount " .. cheat.players[pname].count );
end
end
end
end
end)
-- long range dig check
local check_can_dig = function(pos, digger)
local p = digger:getpos();
if p.y<0 then p.y=p.y+2 else p.y=p.y+1 end -- head position
local dist = math.max(math.abs(p.x-pos.x),math.abs(p.y-pos.y),math.abs(p.z-pos.z));
if dist>6 then -- here 5
dist = math.floor(dist*100)/100;
local pname = digger:get_player_name();
local logtext = os.date("%H:%M.%S") .. "#anticheat: long range dig " .. pname ..", distance " .. dist .. ", pos " .. minetest.pos_to_string(pos);
for name,_ in pairs(cheat.debuglist) do -- show to all watchers
minetest.chat_send_player(name,logtext)
minetest.log("warning", "[governing] "..logtext)
end
local ip = tostring(minetest.get_player_ip(pname));
anticheatdb[ip] = {name = pname, msg = logtext};
return false
end
return true
end
local set_check_can_dig = function(name)
local tabl = minetest.registered_nodes[name];
if not tabl then return end
tabl.can_dig = check_can_dig;
minetest.override_item(name, {can_dig = check_can_dig})
--minetest.register_node(":"..name, tabl);
end
local function is_player(player)
if player then
if type(player) == "userdata" or type(player) == "table" then return true end
end
return false
end
minetest.register_on_joinplayer(function(player)
-- init stuff on player join
if not is_player(player) then return end
local name = player:get_player_name();
if type(name) ~= "string" then return end
local pos = player:getpos();
-- no matter if are incomplete info, save most possible of and start recolection of stats
if cheat.players[name] == nil then
cheat.players[name]={count=0,cheatpos = pos, clearpos = pos, lastpos = pos, cheattype = 0}; -- type 0: none, 1 noclip, 2 fly
end
-- try to fill some stats or retrieve previously
if cheat.players[name] and cheat.players[name].stats == nil then
cheat.players[name].stats = {maxdeltadig=0,deltadig = 0,digxp = 0, state = 0}; -- various statistics about player: max dig xp increase in 2 minutes, current dig xp increase
if bonemod then
minetest.after(4, -- load digxp after boneworld loads it
function()
if boneworld.xp then
cheat.players[name].stats.digxp = boneworld.digxp[name] or 0;
cheat.players[name].stats.state = 1;
end
end
) --state 0 = stats not loaded yet
end
end
-- check anticheat db for cheaters clients
-- ===================================
local ip = tostring(minetest.get_player_ip(name));
local info = minetest.get_player_information(name)
local msgiplevelone = "";
local msgipleveltwo = "";
--check ip first try of info manually, later from player info
if anticheatdb[ip] then
msgiplevelone = "#anticheat: welcome back detected cheater, ip = " .. ip .. ", name " .. anticheatdb[ip].name .. ", new name = " .. name;
end;
--check names from stats
for ip,v in pairs(anticheatdb) do
if v.name == name then
msgiplevelone = "#anticheat: welcome back detected cheater, ip = " .. ip .. ", name = newname = " .. v.name;
break;
end
end
-- send detection msg before try to check info (cos info may be incomplete detection)
if msgiplevelone~="" then
minetest.after(1, function()
for namemd,_ in pairs(cheat.moderators) do
minetest.chat_send_player(namemd,msgiplevelone);
end
end)
end
-- rare case / simple sanity check, _should_ not happen ;) pretty rare but modified client that does not give info
if not info then
if not is_player(player) then
name = name .. " is a bot confirmed, also"
end
msgipleveltwo = "[governing] can't retrieve info, player '" .. name .. "' disappeared or seems craker"
minetest.after(2, function()
for namemd,_ in pairs(cheat.moderators) do
minetest.chat_send_player(namemd,msgipleveltwo);
end
end)
minetest.log("warning", msgipleveltwo)
return
end
-- prepare information report log, "version_string" is only available if the engine was compiled in debug mode (or patched accordingly)
local msgipleveltwo = "[governing] player '" .. name .. "' joined" ..
" from:" .. info.address ..
" protocol_version:" .. (info.protocol_version or "20?") ..
" formspec_version:" .. (info.formspec_version or "old") ..
" lang_code:" .. (info.lang_code or "<unknown>") ..
" serialization_version:" .. (info.serialization_version or "20?") ..
" version_string:" .. (info.version_string or "not supported")
minetest.log("action", msgipleveltwo)
local msgm = "#anticheat detected a cheater with ".. tostring(minetest.get_player_ip(name)).." named "..name
if info.version_string then
local dfv = dfver(info.version_string)
if dfv then
minetest.after(3, function()
minetest.chat_send_player(name, msgiplevelone);
if minetest.settings:get_bool("beowulf.dfdetect.enable_kick", false) then
minetest.kick_player(name, "Are you a cheater stupid user? change your cracked client for play")
end
for namemd,_ in pairs(cheat.moderators) do
minetest.chat_send_player(namemd,msgm); -- advertise moderators
end
end)
minetest.log(msgm)
end
else
for namemd,_ in pairs(cheat.moderators) do
minetest.chat_send_player(namemd,msgm); -- advertise moderators
end
minetest.log(msgm)
end
end)
minetest.register_chatcommand("cchk", {
privs = {
interact = true
},
description = "cchk NAME, checks if player is cheating in this moment",
func = function(name, param)
local privs = minetest.get_player_privs(name).privs;
if not cheat.moderators[name] and not privs then return end
local player = minetest.get_player_by_name(param);
if not player then return end
check_player(player);
local ip = tostring(minetest.get_player_ip(param));
local info = minetest.get_player_information(param)
local msgm = "#anticheat detected a cheater with "..ip.." named "..param
if info.version_string then
local dfv = dfver(info.version_string)
if dfv then
msgm = msgm.." using "..info.version_string
minetest.chat_send_player(param, "..... cheat");
if minetest.settings:get_bool("beowulf.dfdetect.enable_kick", false) then
minetest.kick_player(param, "Are you a cheater stupid user? change your cracked client for play")
end
minetest.chat_send_player(name,msgm); -- advertise moderators
for namemd,_ in pairs(cheat.moderators) do
minetest.chat_send_player(namemd,msgm); -- advertise moderators
end
minetest.log(msgm)
end
else
for namemd,_ in pairs(cheat.moderators) do
minetest.chat_send_player(namemd,msgm); -- advertise moderators
end
minetest.log(msgm)
end
local players = minetest.get_connected_players();
for name,_ in pairs(cheat.debuglist) do -- show suspects in debug
for _,player in pairs(players) do
local pname = player:get_player_name();
if cheat.players[pname].count>0 then
minetest.chat_send_player(name, "name " .. pname .. ", cheat pos " .. minetest.pos_to_string(cheat.players[pname].cheatpos) .. " last clear pos " .. minetest.pos_to_string(cheat.players[pname].clearpos) .. " cheat type " .. cheat.players[pname].cheattype .. " cheatcount " .. cheat.players[pname].count );
end
end
end
end
})
minetest.register_chatcommand("crep", { -- see cheat report
privs = {
interact = true
},
description = "crep 0/1, 0 = default cheat report, 1 = connected player stats",
func = function(name, param)
local privs = minetest.get_player_privs(name).privs;
if not cheat.moderators[name] and not privs then return end
if param == "" then
minetest.chat_send_player(name,"use: crep type, types: 0(default) cheat report, 1 connected player stats (".. version ..")");
end
param = tonumber(param) or 0;
if param == 0 then -- show cheat report
local text = "";
for ip,v in pairs(anticheatdb) do
if v and v.name and v.msg then
text = text .. "ip " .. ip .. " ".. v.msg .. "\n";
end
end
if text ~= "" then
local form = "size [6,7] textarea[0,0;6.5,8.5;creport;CHEAT REPORT;".. text.."]"
minetest.show_formspec(name, "anticheatreport", form)
end
elseif param == 1 then -- show cheat stats
local text = "";
local players = minetest.get_connected_players();
for _,player in pairs(players) do
local pname = player:get_player_name();
local ip = tostring(minetest.get_player_ip(pname));
text = text .. "\nname " .. pname .. ", digxp " .. math.floor(1000*cheat.players[pname].stats.digxp)/1000 ..
", deltadigxp(2min) " .. math.floor(1000*cheat.players[pname].stats.deltadig)/1000 .. ", maxdeltadigxp " .. math.floor(1000*cheat.players[pname].stats.maxdeltadig)/1000; -- .. " ".. string.gsub(dump(cheat.players[pname].stats), "\n", " ");
if anticheatdb[ip] then text = text .. " (DETECTED) ip ".. ip .. ", name " .. anticheatdb[ip].name end
end
if text ~= "" then
local form = "size [10,8] textarea[0,0;10.5,9.;creport;CHEAT STATISTICS;".. text.."]"
minetest.show_formspec(name, "anticheatreport", form)
end
end
-- suspects info
local players = minetest.get_connected_players();
for _,player in pairs(players) do
local pname = player:get_player_name();
if cheat.players[pname].count>0 then
minetest.chat_send_player(name, "name " .. pname .. ", cheat pos " .. minetest.pos_to_string(cheat.players[pname].cheatpos) .. " last clear pos " .. minetest.pos_to_string(cheat.players[pname].lastpos) .. " cheat type " .. cheat.players[pname].cheattype .. " cheatcount " .. cheat.players[pname].count );
end
end
end
})
minetest.register_chatcommand("cdebug", { -- toggle cdebug= display of stats on/off for this player
privs = {
interact = true
},
func = function(name, param)
local privs = minetest.get_player_privs(name).privs;
if not cheat.moderators[name] and not privs then return end
if cheat.debuglist[name] == nil then cheat.debuglist[name] = true else cheat.debuglist[name] = nil end;
minetest.chat_send_player(name,"#anticheat: " .. version);
if cheat.debuglist[name]==true then
minetest.chat_send_player(name,"#anticheat: display of debug messages is ON");
else
minetest.chat_send_player(name,"#anticheat: display of debug messages is OFF");
end
end
})
-------------------------------------------------------------------------
-- GOVERNONR custom action for features mod code improvements
-- minetest routines to implement the mod features
-- Copyright 2020-2023 mckaygerhard CC-BY-SA-NC 4.0
-------------------------------------------------------------------------
-- cleanup after the player leaves
minetest.register_on_leaveplayer(function(player)
if is_player(player) then
track_player_clear(player)
end
end)
-- list of nodes to enable damage if noclip or to check if player its diggin too fast
local node_list_check = {}
-- TODO move this to a comma separted list in config, and adde the check below in node check for fly
if minetest.get_modpath("default") then
table.insert(node_list_check, "default:stone")
table.insert(node_list_check, "default:stone_with_iron")
table.insert(node_list_check, "default:stone_with_copper")
table.insert(node_list_check, "default:stone_with_coal")
table.insert(node_list_check, "default:stone_with_gold")
table.insert(node_list_check, "default:stone_with_mese")
table.insert(node_list_check, "default:stone_with_diamond")
end
local function interval_fn()
if not governing.modbeowulf then
for _, player in ipairs(minetest.get_connected_players()) do
track_player(player)
end
end
if not governing.modanticheat then
for _, nodename in ipairs(node_list_check) do
set_check_can_dig(nodename);
end
end
minetest.after(2, interval_fn)
end
-- TODO: beowulf was pretty unneficient on large player servers.. cos only its made each 1 second and again each x inside function
if governing.is_50 then
minetest.register_on_mods_loaded(interval_fn )
else
minetest.after(0.1, interval_fn)
end
-- damaged if a player its making noclip, no matter if admin is doing
for _, nodename in ipairs(node_list_check) do
minetest.override_item(nodename, {
damage_per_second = 1
})
end

View File

@ -0,0 +1,250 @@
-- taken from https://github.com/S-S-X/dftest/blob/master/init.lua
local has_beerchat = minetest.get_modpath("beerchat")
-- luacheck: push no max line length
local df = {
"dragonfire", -- many based clients by example teamclient
"f8fd5c11b", -- Merge pull request #59 from PrairieAstronomer/readme_irrlicht_change
"c66ae6717", -- Add exact irrlichtmt version to the clone command
"296cce39d", -- Fix upstream merge issues
"350b6d175", -- Install lua_async dependency
"393c83928", -- Don't include client/game.h on server build
"ccd4c504d", -- Ship dragonfireclient with selected high-quality mods
"147aaf326", -- Fix build instructions
"b09fc5de5", -- Add spider
"d404517d2", -- Make LuaVoxelManipulator available to CSM API
"1ccf88e80", -- minetest.dig_node: Remove node
"950d2c9b3", -- Add ClientObjectRef:remove and return true in on_object_add callback to remove newly added object
"fb4815c66", -- Merge pull request #35 from arydevy/patch-1
"f12288814", -- Merge pull request #42 from Minetest-j45/master
"f3082146c", -- remove irrlicht from lid dir (accident)
"a3925db22", -- add airjump and remove unused headers
"7824a4956", -- Merge pull request #1 from EliasFleckenstein03/master
"35445d24f", -- Make set_pitch and set_yaw more accurate by not rounding it to integers
"5131675a6", -- Add guards to stop server build fail
"96a37aed3", -- Add minetest.get_send_speed
"d08242316", -- Fix format
"ce0d81a82", -- Change default cheat menu entry height
"b7abc8df2", -- Add on_object_add callback
"4f613bbf5", -- Include tile definitions in get_node_def; Client-side minetest.object_refs table
"c86dcd0f6", -- Add on_object_hp_change callback and nametag images
"b84ed7d0b", -- Call on_object_properties_change callback when adding object to scene
"26cfbda65", -- Add on_object_properties_change callback
"6dc7a65d9", -- Add ClientObjectRef:set_properties
"7d7d4d675", -- Add ClientObjectRef.get_properties
"ea8fa30b6", -- Changed README.md to fit the dragonfire client
"c47eae316", -- Add table.combine to luacheckrc
"83d09ffaf", -- Complete documentation
"e0b4859e7", -- Add ClientObjectRef:remove
"63f7c96ec", -- Fix legit_speed
"5c06763e8", -- Add noise to client CSM API
"7613d9bfe", -- Update .wielded command to output the entire itemstring; add LocalPlayer:get_hotbar_size
"bc79c2344", -- CSM: Use server-like (and safe) HTTP API instead of Mainmenu-like
"166968232", -- Port formspec API from waspsaliva This API is inofficial and undocumented; invalid usage causes the game to crash. Use at own risk!
"e391ee435", -- Forcefully place items when minetest.place_node is used
"546ab256b", -- Update buildbot to new MineClone2 repo and set the game name to MineClone2 rather than mineclone2
"d3780cefd", -- Attempt to fix SEGFAULT in push_inventory
"d1c84ada2", -- Merge minetest changes
"74f5f033e", -- Add Custom version string
"b2f629d8d", -- Logo improvements
"78b7d1019", -- Add dragonfire logo
"19e0528e3", -- Add minetest.get_nearby_objects
"47d0882cc", -- Fix line containing only whitespace
"4fedc3a31", -- Add minetest.interact
"dc67f669e", -- Make the Cheat Menu size configureable
"906845a87", -- Add minetest.registered_items and minetest.registered_nodes (Doesn't do anything yet)
"3a4325902", -- Fixed crash by adding legacy stuff to defaultsettings (for now)
"53c991c5f", -- Fixed crash due to missing entry in defaultsettings.cpp
"0c6e0c717", -- Reorganize categories
"e8faa2afb", -- Rework Range
"a4d914ba2", -- Make GitHub Actions Happy try 3
"a34c61093", -- Make GitHub Actions Happy try 2
"f783f5939", -- Make GitHub Actions Happy try 1
"8b58465aa", -- Remove obsolete code from clientenvironment
"35c15567a", -- Update builtin/settingtypes.txt to the new philosophy
"0c9e7466e", -- New Cheat Philosophy
"a1e61e561", -- World Cheats improvements; Add BlockLava; Readd minetest.request_http_api for Compatibility
"56d536ea5", -- Update CheatDB URL again
"ce47003cc", -- Update defaults for ContentDB (->CheatDB)
"89995efee", -- CheatDB Support & Enable/Disable CSMs in Main Menu
"3df23e23c", -- Small AutoTool Fix
"8b3eaf5b0", -- Lua API: Particle callbacks; Add NoWeather
"0a285dd33", -- Remove NextItem
"4695222bc", -- Fix and Improve AutoTool
"5bead7daa", -- Added minetest.close_formspec
"f825cf0e3", -- Fixed Minimap position
"eaa8a5132", -- Fixed FastPlace and AutoPlace
"b4e475726", -- Added configureable Colors for PlayerESP and EntityESP
"549025f6a", -- EntityESP, EntityTracers, PlayerESP, PlayerTracers
"eb6aca8b4", -- Merged Minetest
"8de51dae9", -- Fixed crash when attempting to access nonexistant inventory from Lua API
"a65251a7a", -- Fixed glowing GenericCAOs being rendered completely back when Fullbright is enabled
"eaec3645b", -- Added ClientObjectRef:get_hp()
"fb4d54ee3", -- Added minetest.register_on_play_sound
"50629cc6a", -- Improved Scaffold
"3d74e17cc", -- Added AutoSlip (-> Credit to Code-Sploit)
"f9c632466", -- Added JetPack and AutoHit (-> Credits to Code-Sploit and cora)
"843239c0b", -- Added Speed/Jump/Gravity Override
"598e9bdbc", -- Update Credits
"7d327def8", -- Improved AutoSneak
"82216e147", -- LocalPlayer:set_physics_override; minetest.register_on_recieve_physics_override
"4dd5ecfc5", -- Added setpitch & setyaw commands; AutoSprint
"b65db98bd", -- Added OnlyTracePlayers
"e16bbc1fb", -- Merge pull request #14 from corarona/master
"1780adeea", -- lua-api: fix get/set_pitch
"3e7c5d720", -- Possibility to use cheat menu while pressing other keys
"0aa63aafc", -- Fixed warning
"9db80fc6f", -- Run Lint Script
"91ad0d049", -- Merge pull request #10 from corarona/master
"6bda686c0", -- MapBlockMesh Performance Improvement
"1bab49049", -- add LUA_FCT
"6efa8a758", -- add g/s pitch and make_screenshot in lua api
"46237330d", -- Several Enhancements
"60a9ff6ff", -- api-screenshot: change function name to make_screenshot
"1f56317d5", -- Added NodeESP
"75ecaa217", -- Fix and run the Lint autocorrect script
"6ccb5835f", -- Revert "Make Lint Happy"
"244713971", -- Added script that automaticall corrects lint style
"07e61e115", -- Fix github build problems #3
"3af10766f", -- Fix github build problems #2
"16d302c9a", -- Fix github build problems
"ad148587d", -- Make Lint Happy
"1145b05ea", -- Updated Credits
"c9221730d", -- Updated Cheat Menu Color Design
"1799d5aa9", -- Cheat Menu Improvements Change
"fba7dc216", -- Merge pull request #8 from realOneplustwo/master
"a7dc1135e", -- Added CheatHUD
"f1d9ac014", -- Moved Killaura to Lua; Added ForceField; Added Friendlist; Added ClientObjectRef:is_local_player(); Documented LocalPlayer:get_object()
"06b72069d", -- Fixed ColorChat
"62958bd60", -- Reverted accidental commit in wrong repo
"00d51fbd5", -- Armor textures support
"7cbe42b1d", -- Re-Added Chat Effects
"28f6a7970", -- lua api: add set/get_pitch
"4f9797b6e", -- lua api: add core.take_screenshot()
"8e9e76a50", -- Revert "Add Block Formspec Hack"
"6652d7ac2", -- Add Block Formspec Hack
"8bc7d49b3", -- Added Nuke
"62cf9b466", -- Fix compile error
"519f98c65", -- Merge pull request #3 from JosiahWI/ui_revamp
"f236476af", -- Fix errors in cheatMenu.
"7af3dee31", -- Merge pull request #2 from JosiahWI/ui_revamp
"ea88dde4b", -- Added Strip, AutoRefill, indexing for InventoryActions and Wield Index starts at 1 now
"7aff09ab2", -- Fix overindent!
"aea9b36ef", -- Improved Colours
"1ef72ad9c", -- Fix indentation style.
"586241008", -- Add missing return.
"b211e90ff", -- Prepare cheatMenu::draw function for easier UI changes.
"e22e334e9", -- Merge pull request #1 from JosiahWI/ui_revamp
"f605308ee", -- Improve drawEntry.
"130d476f6", -- Changed Cheat Menu UI
"f1ff05bf5", -- Added ThroughWalls, InventoryActions API and AutoTotem
"1a7d3d818", -- Extended ClientObjectRef; Improved CrystalPvP
"1e4f35492", -- This is the last try for lint...
"7e0f8fba0", -- Another Lint commit
"151e5782e", -- Lint is still not happy...
"28a560684", -- Added the API additions from waspsaliva
"c1aea404b", -- Lint is bitch
"3a718f12b", -- Make lint happy; Remove stupid redirector
"3b596a96e", -- Fixed Github build problems
"847198edb", -- Edited .gitignore properly; fixed armor invulnarability in the server code.
"bbcd24954", -- New Mod System
"80f416d51", -- Added AttachmentFloat
"cb1915efa", -- Added minetest.drop_selected_item(), Improved AutoEject
"43ee069db", -- Improved X-Ray, added AutoEject
"faa32610e", -- Added ESP, fixed Tracers, improved Jesus
"ee88f4b94", -- Improved Tracers
"c36ff3edb", -- Added AutoSneak and improved X-Ray MapBlock updating
"0a2c90f4c", -- Only draw tracers to objects that are not attached (that fixes tracers to armor)
"044a12666", -- Added Tracers, NoSlow and NoForceRotate; GUI Colors changed
"b9f8f0a23", -- The Robot Update
"af085acbd", -- Added Schematicas
"0730ed216", -- Delete my stupid test mod lol
"772c9629e", -- Unrestricted HTTP API for Client, Server and Main Menu
"9b1030cac", -- Added minetest.get_inventory(location)
"2321e3da4", -- Removed console output spammed by minetest.find_node_near
"90f66dad8", -- Removed experimental code
"8b4d27141", -- Fixed typo in clientmods/inventory/mod.conf
"d8b8c1d31", -- Added Documentation for Additional API
"6e6c68ba0", -- Added Chat Spam, Replace and settingtypes.txt for Clientmods
"79d0314d7", -- Update Buildbots
"770bde9c6", -- idk
"e245151c5", -- Improved World hacks
"19205f6b3", -- Improved World Hacks, added API functions
"73b89703f", -- Improved World hacks, added fill
"248dedaba", -- Added floationg water to BlockWater
"9dc3eb777", -- Fixed broken Chatcommands
"80371bc16", -- Added .listwarps
"1c29f21e0", -- Imporoved set_wield_index() to include camera update
"3bed0981d", -- UI Update; Added AutoTool
"622d54726", -- Added DestroyWater (:P anon)
"9019e18b9", -- Some Updates
"107dec6c0", -- Added Coords
"f1760622e", -- Added BrightNight
"2675bcca1", -- Added more cheats
"3d980cf57", -- Improved Xray and Fullbright
"f7a042223", -- Added cheat Menu
"344fddc17", -- Improved Killaura and Chat position
"678559bb6", -- removed leagcy clientmods
"9194165cf", -- Added autodig, moved chat
"064c25caa", -- Added EntitySpeed
"5a8610c2f", -- Added customizable keybindings, improved freecam, added special inventory keybind (by default ender inventory)
"83f59484d", -- Fixed 5.4.0-dev build
"ffe3c2ae0", -- Update to minetest 5.4.0-dev
"45aa2516b", -- Added settings
"f22339ed8", -- Removed fast killaura
"408e39a1d", -- Added Anti Knockback
"eee0f960b", -- Removed minetest.conf.old
"39d7567c1", -- Fixed Crash
"305e0e0d3", -- Auto disable smooth lighting when fullbright is active
"6796baec6", -- Defaultsettings
"5a2bf6634", -- Added Clientmods
"e610149c0", -- Initial Commit
"68f9263a2", -- Hacked Client
"90d885506", -- GalwayGirl Client
}
--[[
To update commit list: save commit logs for master branches of minetest in mt.log and dragonfire in df.log
For example (assuming you have added dragonfire remote, adapt if not):
$ git log --oneline origin/master > mt.log; git log --oneline dragonfire/master > df.log
Find and drop commits that seems to exist in both remotes, print rest of it:
$ sort -k3 <(awk '{print NR" "$0}' df.log mt.log mt.log) | uniq -uf2 | sort -nk1 | sed -r 's/^[^ ]+ ([^ ]+) (.*)$/\t"\1", -- \2/'
Replace above entries with output
--]]
-- luacheck: pop
local function dfver(s)
-- loop into table of commmits and find the compared version
for _,v in ipairs(df) do
if string.find(v) then
return v
end
end
end
minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
local info = minetest.get_player_information(name)
local version = info.version_string
if not version then
-- version not available
return
end
local dfv = dfver(version)
if dfv then
local msg = "Unsupported client detected: " .. dfv .. " player: " .. name
minetest.log("action", "[beowulf] " .. msg)
if has_beerchat then
beerchat.send_on_channel("DF-Detect", beerchat.moderator_channel_name, msg)
end
-- if minetest.settings:get_bool("beowulf.dfdetect.enable_kick", false) then
-- minetest.kick_player(name, "Unsupported client")
-- end
end
end)

View File

@ -0,0 +1,65 @@
local PLAYERS_MSG = {}
local PLAYERS_FREQ = {}
local SPAM_SPEED = 5
local SPAM_SPEED_MSECS = SPAM_SPEED * 1e6
local SPAM_WARN = 5
-- In seconds
local SPAM_KICK = SPAM_WARN + 5
local RESET_TIME = 30
-- Convert to microsecs
local RESET_TIME_MSECS = RESET_TIME * 1e6
local WARNING_COLOR = minetest.get_color_escape_sequence"#FFBB33"
minetest.register_on_leaveplayer(function(player)
PLAYERS_MSG[player:get_player_name()] = nil
PLAYERS_FREQ[player:get_player_name()] = nil
end)
minetest.register_on_joinplayer(function(player)
PLAYERS_MSG[player:get_player_name()] = {}
end)
minetest.register_on_chat_message(function(name, message)
for msg, info in pairs(PLAYERS_MSG[name]) do
if minetest.get_us_time() - info[2] >= RESET_TIME_MSECS then PLAYERS_MSG[name][msg] = nil end
end
if PLAYERS_MSG[name][message] then
local amount = PLAYERS_MSG[name][message][1] + 1
PLAYERS_MSG[name][message][1] = amount
PLAYERS_MSG[name][message][2] = minetest.get_us_time()
if amount >= SPAM_KICK then minetest.kick_player(name, "Kicked for spamming.")
elseif amount >= SPAM_WARN then
minetest.chat_send_player(name, WARNING_COLOR .. "Warning! You've sent the message '" .. message .. "' too often. Wait at least " .. RESET_TIME .. " seconds before sending it again.")
end
else PLAYERS_MSG[name][message] = { 1, minetest.get_us_time() } end
if not PLAYERS_FREQ[name] then
PLAYERS_FREQ[name] = {
0,
0,
minetest.get_us_time(),
0
}
return
end
local warns = PLAYERS_FREQ[name][4]
local amount = PLAYERS_FREQ[name][2]
local speed = PLAYERS_FREQ[name][1]
local delay = minetest.get_us_time() - PLAYERS_FREQ[name][3]
speed = (speed * amount + delay) / (amount + 1)
if amount >= SPAM_WARN then
if warns + 1 == SPAM_KICK - SPAM_WARN then minetest.kick_player(name, "Kicked for spamming.")
elseif speed <= SPAM_SPEED_MSECS then
minetest.chat_send_player(name, WARNING_COLOR .. "Warning! You are sending messages too fast. Wait at least " .. SPAM_SPEED .. " seconds before sending another message.")
warns = warns + 1
speed = SPAM_SPEED_MSECS
amount = SPAM_WARN
else
speed = 0
amount = 0
warns = 0
end
end
PLAYERS_FREQ[name] = {
speed,
amount + 1,
minetest.get_us_time(),
warns
}
end)

144
mods/governing/commands.lua Normal file
View File

@ -0,0 +1,144 @@
-- mod governor by mckaygerhard - commands module
-- Copyright 2020
----------------------------------------------------------------------------
-- this program can be used free but cannot be used commertially or
-- modified for, licenced CC-BY-SA-NC 4.0 unless explicit permission
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
----------------------------------------------------------------------------
--[[ commands for killme implementation no matter of those mods ]]
if not governing.modkillme and not governing.modcommand then
minetest.register_chatcommand("killme", {
description = "Kill player or yourselft to respawn",
func = function(name)
local player = minetest.get_player_by_name(name)
if player then
if minetest.settings:get_bool("enable_damage") and player:is_player() then
player:set_hp(0)
return true
else
for _, callback in pairs(minetest.registered_on_respawnplayers) do
if callback(player) then
return true
end
end
-- There doesn't seem to be a way to get a default spawn pos from the lua API
return false, "No static_spawnpoint defined"
end
else
-- Show error message if used when not logged in, eg: from IRC mod
return false, "You need to be online to be killed!"
end
end
})
end
--[[ end of commands for killme implementation no matter of those mods ]]
-- -----------------------------------------------------------------------------------------
--[[ commands for geoip and ip location information ]]
if not governing.modgeoip then
minetest.register_chatcommand("geoip", {
params = "<playername>",
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 <playername>" end
if not minetest.get_player_ip then return true, "[geoip]: engine its too older, canot get ip of player." end
local ip = minetest.get_player_ip(param)
if not ip then return true, "[geoip] no ip available! seems "..param.." does not provide such info!" end
governing.lookup(ip, function(result)
local txt = format_result_geoip(result)
if not txt then return true, "[geoip]: "..param..":"..ip" error: "..(result.description or "unknown error") end
minetest.log("action", "[geoip] "..param..": "..txt)
minetest.chat_send_player(name, param..": "..txt)
end)
end
})
end
minetest.register_chatcommand("govip", {
params = "<playername>",
privs = {governing=true},
description = "Governing geoip lookup + net detection details on the given player",
func = function(name, param)
if not param then return true, "usage: /govip <playername>" end
if not minetest.get_player_ip then return true, "[governing]: engine its too older, canot get ip of player." end
local ip = minetest.get_player_ip(param)
if not ip then return true, "[governing] no ip available! seems "..param.." does not provide such info!" end
governing.checkip(ip, function(result)
local txt = format_result_checkip(result)
if not txt then return true, "[governing]: "..param..":"..ip" error: "..(result.description or "unknown error") end
minetest.log("action", "[governing] "..param..": "..txt)
minetest.chat_send_player(name, param..": "..txt)
end)
end
})
--[[ end of commands for geoip and ip location information ]]
--[[ commands for stamina or satiation based on existing mods ]]
if not governing.modhbhunger then
if governing.modhudbars and not hb.redo then
minetest.register_chatcommand("satiation", {
privs = {["server"]=true},
params = S("[<player>] <satiation>"),
description = S("Set satiation of player or yourself"),
func = function(name, param)
if minetest.settings:get_bool("enable_damage") == false then
return false, S("Not possible, damage is disabled.")
end
local targetname, satiation = string.match(param, "(%S+) (%S+)")
if not targetname then
satiation = param
end
satiation = tonumber(satiation)
if not satiation then
return false, S("Invalid satiation!")
end
if not targetname then
targetname = name
end
local target = minetest.get_player_by_name(targetname)
if target == nil then
return false, S("Player @1 does not exist.", targetname)
end
if satiation > hbhunger.SAT_MAX then
satiation = hbhunger.SAT_MAX
elseif satiation < 0 then
satiation = 0
end
hbhunger.hunger[targetname] = satiation
hbhunger.set_hunger_raw(target)
return true
end,
})
end
end
--[[ end commands for stamina or satiation based on existing mods ]]

View File

@ -0,0 +1,4 @@
default?
mail?
boneworld?
hudbars?

145
mods/governing/geoip.lua Normal file
View File

@ -0,0 +1,145 @@
-- mod governor by mckaygerhard, geoip specific code
-- Copyright 2023
----------------------------------------------------------------------------
-- this program can be used free but cannot be used commertially or
-- modified for, licenced CC-BY-SA-NC 4.0 unless explicit permission
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
----------------------------------------------------------------------------
function format_result_geoip(result)
local txt = " Place: "
if result then
if result.status == "success" and result.data and result.data.geo then
if result.data.geo.ip then
if result.data.geo.ip == "127.0.0.1" then return txt .. " seems localhost " ..".. <_< ." end
end
if result.data.geo.continent_name then
if result.data.geo.continent_name ~= "" then txt = txt .. result.data.geo.continent_name .."," end
end
if result.data.geo.country_name then
if result.data.geo.country_name ~= "" then txt = txt .. result.data.geo.country_name .."," end
end
if result.data.geo.region_name then
if result.data.geo.region_name ~= "" then txt = txt .. result.data.geo.region_name .. "," end
end
if result.data.geo.city then
if result.data.geo.city ~= "" then txt = txt .. result.data.geo.city .."" end
end
if result.data.geo.timezone then
if result.data.geo.timezone ~= "" then txt = txt .. " Timezone: " .. result.data.geo.timezone end
end
if result.data.geo.asn then
if result.data.geo.asn ~= "" then txt = txt .. " ASN: " .. result.data.geo.asn end
end
if result.data.geo.isp then
if result.data.geo.isp ~= "" then txt = txt .. " ISP: " .. result.data.geo.isp end
end
if result.data.geo.ip then
if result.data.geo.ip ~= "" then txt = txt .. " IP: " .. result.data.geo.ip end
end
return txt
else
return false
end
else
return false
end
end
function format_result_checkip(result)
local txt = " Place: "
local flg = ""
if result then
if result.message then
return result.message .. ".. <_< . if no key, use /geoip command"
end
if result.security then
if result.security.vpn then
if result.security.vpn ~= "true" then flg = flg .. "+VPN" end
end
if result.security.proxy then
if result.security.proxy ~= "true" then flg = flg .. "+PRX" end
end
if result.security.tor then
if result.security.tor ~= "true" then flg = flg .. "+TOR" end
end
if result.security.relay then
if result.security.tor ~= "true" then flg = flg .. "+REL" end
end
end
if result.location then
if result.location then
if result.location.continent ~= "" then txt = txt .. result.location.continent_name .."," end
end
if result.location.country then
if result.location.country ~= "" then txt = txt .. result.location.country .."," end
end
if result.location.region then
if result.location.region ~= "" then txt = txt .. result.location.region .. "," end
end
if result.location.city then
if result.location.city ~= "" then txt = txt .. result.location.city .." " end
end
if result.location.time_zone then
if result.location.time_zone ~= "" then txt = txt .. "Timezone: " .. result.location.time_zone end
end
end
if result.network then
if result.network.autonomous_system_number then
if result.network.autonomous_system_number ~= "" then txt = txt .. " ASN: " .. result.network.autonomous_system_number end
end
if result.network.autonomous_system_organization then
if result.network.autonomous_system_organization ~= "" then txt = txt .. " ISP: " .. result.network.autonomous_system_organization end
end
end
if result.ip then
if result.ip ~= "" then txt = txt .. " IP: " .. result.ip end
end
return flg .. txt
else
return false
end
end
governing.joinplayer_callback = function() end -- function(name, result)
--[[ init of call back on join of a player, ]]
minetest.register_on_joinplayer(function(player) -- query ip on join, record in logs and execute callback
if not player then return end
if not player:is_player() then return end
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
-- do log ip check: if not apikey then geoip from mod; if not mod then our own geoip
if governing.checkapikey ~= "" then
governing.checkip(ip, function(data) -- log, but TODO: record in storage log file
local txt = format_result_checkip(data)
if txt then minetest.log("warning", "[goberning/geoip] joined player, " .. name .. ":" .. ip .. "," .. txt)
else minetest.log("error", "[goberning/geoip] joined player, " .. name .. ":" .. ip .. ", seems fails")
end
governing.joinplayer_callback(name, data) -- execute callback
end)
else
if not governing.modgeoip then
governing.lookup(ip, function(data) -- log, but TODO: record in storage log file
local txt = format_result_checkip(data)
if txt then minetest.log("warning", "[goberning/geoip] joined player, " .. name .. ":" .. ip .. "," .. txt)
else minetest.log("error", "[goberning/geoip] joined player, " .. name .. ":" .. ip .. ", seems fails")
end
governing.joinplayer_callback(name, data) -- execute callback
end)
end
end
end)
--[[ end of call back on join of a player, ]]

Binary file not shown.

After

Width:  |  Height:  |  Size: 970 B

202
mods/governing/init.lua Normal file
View File

@ -0,0 +1,202 @@
-- mod governor by mckaygerhard
-- Copyright 2020
----------------------------------------------------------------------------
-- this program can be used free but cannot be used commertially or
-- modified for, licenced CC-BY-SA-NC 4.0
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
----------------------------------------------------------------------------
--[[ init - initialization of variables ]]
local modname = "governing" -- name of the mod , need to be used later in namespace mod variable
local modpath = minetest.get_modpath("governing") -- path of the mod
local modstor = minetest.get_mod_storage() -- request of storage for the mod, if valid, otherwise false/nil
local worlddir = minetest.get_worldpath() -- path of the world were the mod is running, otherwise false/nil
local modmail = minetest.get_modpath("mail") -- path of the mail mod if available for sending messages internaly on private, otherwise false/nil
local modgeoip = minetest.get_modpath("geoip") -- if available, their commands wil be used, otherwise we provided
local moddefault = minetest.get_modpath("default") -- path of default mod if available, otherwise false/nil
local modkillme = minetest.get_modpath("killme") -- if killme is present as mod if available, otherwise we use own
local modcommand = minetest.get_modpath("game_commands") -- updated killme is present as mod if available, otherwise we use own
local modcreative = minetest.get_modpath("creative") -- if creative is available, otherwise false/nil
local modantispawn = minetest.get_modpath("antispam") -- if rnd1 anticheat mod is loaded, cos only wolrs with mt4
local modanticheat = minetest.get_modpath("anticheat") -- if rnd1 anticheat mod is loaded, cos only wolrs with mt4
local modbeowulf = minetest.get_modpath("beowulf") -- if rnd1 anticheat mod is loaded, cos only wolrs with mt4
local modhudbars = minetest.get_modpath("hudbars") -- if the hudbars mod is loaded and working, from wuzzy
local modhbhunger = minetest.get_modpath("hbhunger") -- if the hudbars hunger mod is loaded and working, from wuzzy
local checkapikey = minetest.settings:get("governing.checkapikey") or "" -- need for geoip improved ip information, then geoip normal will be used
local is_46 = minetest.has_feature("add_entity_with_staticdata") -- detect minetest engine 4.0.16 or mayor
local is_50 = minetest.has_feature("object_use_texture_alpha") -- detect mineitest engine more modern than 5.0.0
local is_53 = minetest.has_feature("object_step_has_moveresult") -- detect mineitest engine more modern than 5.3.1
local is_54 = minetest.has_feature("direct_velocity_on_players") -- detect mineitest engine more modern than 5.4.0
local httpapi = minetest.request_http_api and minetest.request_http_api() -- Only works at init time and must be called from the mod's main scope (not from a function).
local creative_mode_cache = minetest.settings:get_bool("creative_mode") -- detection if game is running in main creative
local S
--[[ end - all local variables ]]
--[[ init - translation boilerplace, currently some issues with intlib mod ]]
if minetest.get_translator ~= nil then
S = minetest.get_translator(modname) -- 5.x translation function
else
if minetest.get_modpath("intllib") then
dofile(minetest.get_modpath("intllib") .. "/init.lua")
if intllib.make_gettext_pair then
gettext, ngettext = intllib.make_gettext_pair() -- new gettext method
else
gettext = intllib.Getter() -- old text file method
end
S = gettext
else -- boilerplate function
S = function(str, ...)
local args = {...}
return str:gsub("@%d+", function(match)
return args[tonumber(match:sub(2))]
end)
end
end
end
--[[ end - translation boilerplace, currently some issues with intlib mod ]]
--[[ init - namespace of the mod and varible usages ]]
governing = {}
governing.is_46 = is_46 -- detect minetest engine 4.0.16 or mayor
governing.is_50 = is_50 -- detect mineitest engine more modern than 5.0.0
governing.is_53 = is_53 -- detect mineitest engine more modern than 5.3.1
governing.is_54 = is_54 -- detect mineitest engine more modern than 5.4.0
governing.S = S -- translations if available
governing.httpapi = httpapi -- must be called early at the beggining to work
governing.modname = modname -- name of the mod
governing.modpath = modpath -- path of the mod
governing.modstor = modstor -- request of storage for the mod, otherwise false/nil
governing.worlddir = worlddir -- path of the world were the mod is running, otherwise false/nil
governing.modgeoip = modgeoip -- path of the geoip mod if available for sending messages internaly on private, otherwise false/nil
governing.modmail = modmail -- path of the mail mod if available for sending messages internaly on private, otherwise false/nil
governing.moddefault = moddefault -- path of default mod if available, otherwise false/nil
governing.modkillme = modkillme -- if killme is present as mod if available, otherwise we use own
governing.modcommand = modcommand -- if same killme and commands is present as mod if available, otherwise we use own
governing.modantispawn = modantispawn -- autodetect if older mod antispan by appguru are present
governing.modanticheat = modanticheat -- if rnd1 anticheat mod is present cos only works with mt4
governing.modbeowulf = modbeowulf -- if beowulf anticheat mod is present cos only works with mt5
governing.modhudbars = modhudbars -- if hudbars is present or the mproved hudbars redo
governing.modhbhunger = modhbhunger -- if hbhunger is present or the mproved hudbars redo
governing.checkapikey = checkapikey -- need for geoip improved ip information, then geoip normal will be used
--[[ end - namespace of the mod and varible usages ]]
--[[ init privileges registrations ]]
function governing.is_creative(name)
if creative then
return creative.is_creative(name)
else
return minetest.check_player_privs(name, {creative = true}) or creative_mode_cache
end
end
minetest.register_privilege("governing", {
description = "can do geoip lookups on players for governing",
give_to_singleplayer = false
})
if not governing.modgeoip then
minetest.register_privilege("geoip", {
description = "governing: ip checks + lookups on players",
give_to_singleplayer = false
})
end
--[[ end privileges registrations ]]
--[[ init http calls, must be only on main ]]
function governing.lookup(ip, callback)
if not httpapi then
minetest.log("error", "[governing/geoip] mod not in the trusted http mods!")
return
end
httpapi.fetch( {
url = "https://tools.keycdn.com/geo.json?host=" .. ip,
extra_headers = { "User-Agent: keycdn-tools:https://minetest.org" },
timeout = 5,
}, function(res)
if res.code == 200 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
function governing.checkip(ip, callback)
if not httpapi then
minetest.log("error", "[governing] mod not in the trusted http mods!")
return
end
httpapi.fetch( {
url = "https://vpnapi.io/api/" .. ip .. "?key==" .. governing.checkapikey,
extra_headers = { "User-Agent: VenenuX-minenux:https://git.minetest.io/minenux" },
timeout = 5,
}, function(res)
if res.code == 200 then
local data = minetest.parse_json(res.data)
callback(data)
else
minetest.log("warning", "[governing/ip] http request returned status: " .. res.code)
end
end)
end
--[[ end http calls, must be only on main ]]
--[[ include code files mod features ]]
dofile(governing.modpath.."/geoip.lua") -- format the geoip responses managed by "callback(data)"
dofile(governing.modpath.."/anticheats.lua") -- load anticheat mod that combined rnd + beowulf + fairplay
dofile(governing.modpath.."/antispawn.lua") -- load antispawn chat features only if mod antispan is not loaded
dofile(governing.modpath.."/commands.lua") -- must be at end. so relies on others functionalities
--[[ end of include code files mod features ]]
--[[ log files and finished of mod loading ]]
if governing.checkapikey == "" then minetest.log("warning", "[goberning] governing.checkapikey not set or empty, only basic geoip will work") end
print("[MOD] governing mod loaded" )

2
mods/governing/mod.conf Normal file
View File

@ -0,0 +1,2 @@
name = governing
optional_depends = default, mail, boneworld, hudbars

View File

@ -0,0 +1,4 @@
governing.checkapikey (The string need for use the https://vpnapi.io/ ip informacion with geolocation) string
governing.timestep (How many time will run checks in seconds) int 15 10 300
governing.timeagain (How many seconds checks again to compare if it is cheating the suspected player) int 120 10 300
governing.moderators (Comma separated list of name players that will be not checked, without spaces) string