Merge changes from dev branch (#27)

* Add API functions

Add API to allow other mods to access useful functions. (ban, unban, list bans, check if player is banned)
Add name caching to speed up access to frequent players id
Restructure the database tables for primary keys on names and ip addresses to reduce database access time
Track number of logins for individual names and ip addresses and the last login to provide a clearer account of each id's activity

* Create sban_update.sql

* Update README.md

* fix crash in prev commit

rogue string spread over multiple lines without concatenation

* fix errors preventing travis build

* Update schema.md

* Update LICENSE

* Process expired bans during server start

clean up expired bans on server start to reduce prejoin triggering for every banned player attempting to join

* fix typos

missing commas added and space removed

* Enhance the performance of formspec generation

* Fixes: crash parsing expired bans

Correct datatype handling for integer fields in the sql statements
Refactor code in update_ban_record() to use cached ban data
Use correct param for update_ban_record id_key

* Add annotation & ip caching

* Update README.md

* Fix travis errors

* Fix some travis warnings

* Fix travis warnings

* Fix travis warnings

* Fix crashes

Init cap variable
pass ip string instead of table to ip_key function when building the cache

* Add type checking for ban records

Prevent rogue text entries being added to id field on db update

* Fix crash in caching on first run

Check login exists when building the cache
Initialise cap outside the function

* Alter SQL to fix any text id entry in bans table

* Fix crash when showing ban record

* Fix ban_record command truncating output for admin

* Fix export to xban2

* Cosmetic format on ceateDb string

added primary keys to whitelist & violation tables

* Refactor process_expired_bans function

remove repetitive calls to update_ban_record()
add vacum to shrink the table

* Fix missing # symbols in process_expired_bans()

* Added db indexes to tables and merged with latest dev changes (#26)

* Added db indexes to tables - #25
Formatted and used consistent db column types as well as added various table indexes to the create db script and upgrade script. This prevents Sqlite from doing slow table scans. also fixed string formatting error caused by no default max ban expiry setting

* Fix minor issues

tab spacing
add dev bypass for owner
add expires zero check
remove tostring() cast on cache id
rename id_key to more appropriate id and change type in description
remove primary key in violation table (better structure needed)

* Remove white space preventing travis build

* Fix tabs and remove violation primary key

* Add id & ip cache for names on prejoin event

Simplify join method by caching id and ip on prejoin, removing the need
to call the functions in join. Uses a minetest.after() function call to
clean up

* Refactor join cache clearing mechanism

refactor the join cache clearing mechanism to manage orphaned entries
and work correctly

* Refactor violation functions

Change violations table structure so it can be indexed
Remove id size limit on integer primary keys
Add missing dev check in kick routine
Remove transaction statement; db:exec uses the method internally
Add primary key index to violations table
Remove primary key on expired id; column isn't unique
Initialise active expires on db update

* Modify api ban expires handling. Add api doc.

extend possible types and values for the api ban command to allow
alphanumerical time expression i.e. 1w1d12h30m30s as well as seconds to
expiry & UTC seconds value of expiry.
Create and add API documentation.

* Restructure config settings

Restructure db config table
Refactor config code
Add mod_version to first run initialisation
Rename fixed table to reflect it's temporary nature
Explicitly name table columns for the fix INSERT statement
Modify config INSERT statements to reflect new schema
Add missing last_login to address_tmp INSERT

* Fix Travis build warnings

* Add expired ban processing

Check and update expired bans in active, moving them to expired and
filling in the reqd fields.

* Modify debug bool for release
master
shivajiva101 2019-09-26 19:12:39 +01:00 committed by GitHub
parent ccfbb05320
commit 0464e32c52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 1771 additions and 1038 deletions

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2017 shivajiva101
Copyright (c) 2019 shivajiva101
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,15 +1,24 @@
# sban
[![Build Status](https://travis-ci.org/shivajiva101/sban.svg?branch=master)](https://travis-ci.org/shivajiva101/sban)
#### *** WARNING ***
As this is a dev branch the code is in a fluid state, feel free to test it as the API functions will be retained on merge. It will also spam the log with all db statements executed...you have been warned!
Existing users please note that to use this version you need to apply sban/tools/sban_update.sql so backup your database to somewhere safe and copy sban/tools/sban_update.sql to the world you want to appy the update to and in a terminal navigate to the world folder and use the commands:
sqlite3 sban.sqlite
.read sban_update.sql
.exit
This mod is based on the concepts introduced by xban2, and expands on them
by using an sql database instead of a serialised table file. This approach to
ban management:
* Offers API access to useful functions
* Improves the robustness of the data.
* Grants an enhanced view of player accounts and ban records.
* Provides tiered access to player record information.
* Provides automatic ban expiration.
* Provides optional automatic ban expiration.
* Provides the capability to pre-emptively ban players.
* Offers increased accessibility via SSH connections to the database with your
favourite database management gui.
@ -189,12 +198,20 @@ Returns all known accounts and ip addresses asociated with a player name.
You can add these optional settings to minetest.conf to adjust the sban mod's
behaviour.
#### sban.api
Controls loading of the API functions. Default is false.
sban.api = true
This would load the API functions and allow other mods access via the global sban table.
#### sban.display_max
Changes the maximum number of player records displayed when using the /ban_record
command.
Example: sban.display_max = 12
sban.display_max = 12
This would increase the number of records shown from the default 10 records to 12.
@ -203,24 +220,41 @@ This would increase the number of records shown from the default 10 records to 1
Allows server owners to set an expiry date for bans. It uses the same format for
durations as the /tempban command.
Example: sban.ban_max = 90D
sban.ban_max = 90D
In this example all permanent player bans created after the setting has been added
to minetest.conf, and after a server restart, will expire 90 days after the ban was
set. If required, longer ban durations can still be set with the tempban command.
Please note that if you delete or adjust the setting, after restarting the server, bans
created while the setting was active will not change and will retain their adjusted
expiry dates.
created while the setting was active will not change and will retain their original
expiry date.
#### sban.accounts_per_ip
Restricts accounts a player can make from an ip address.
Example: sban.accounts_per_ip = 5
sban.accounts_per_ip = 5
Please note this is optional and without the setting the player accounts are unrestricted.
#### sban.cache.max
Maximum cached name records.
sban.cache.max = 1000
If you don't add this setting sban will use the value above as the default.
#### sban.cache.ttl
Time in seconds to deduct from the last player to login as the cutoff point for pre caching names.
sban.cache.max = 86400
If you don't add this setting sban will use the value above as the default. Disable name caching by setting to -2
#### CREDITS
Thanks to:

39
api.md Normal file
View File

@ -0,0 +1,39 @@
# API functions
Sban has a few simple but powerful global functions you can access from your mods.
Ban
sban.ban(name, source, reason, expires)
@param name string - reqd
@param source string - reqd
@param reason string - reqd
@param expires alphanumerical duration string or integer
@return bool
@return msg string
Unban
sban.unban(name, source, reason)
@param name string
@param source name string
@param reason string
@return bool
@return msg string
Ban status
sban.ban_status(name_or_ip)
@param name_or_ip string
@return bool
Ban record
sban.ban_record(name_or_ip)
@param name_or_ip string
@return keypair table record OR nil
Active bans
sban.list_active()
@return keypair table of active bans

2393
init.lua

File diff suppressed because it is too large Load Diff

View File

@ -1,41 +1,57 @@
The database contains 5 tables;
CREATE TABLE active (
id INTEGER PRIMARY KEY,
name VARCHAR (50),
source VARCHAR (50),
created INTEGER,
reason VARCHAR (300),
expires INTEGER,
pos VARCHAR (50)
);
bans
playerdata
players
whitelist
version
CREATE TABLE address (
id INTEGER,
ip VARCHAR PRIMARY KEY,
created INTEGER,
last_login INTEGER,
login_count INTEGER DEFAULT (1),
violation BOOLEAN
);
The players table holds the uid for the player
CREATE TABLE config (
mod_version VARCHAR,
db_version VARCHAR
);
bans:
id INTEGER NOT NULL,
name VARCHAR (50),
source VARCHAR (50),
created INTEGER,
reason STRING (300),
expires INTEGER,
u_source VARCHAR (50),
u_date INTEGER,
active BOOLEAN,
last_pos VARCHAR (50)
CREATE TABLE expired (
id INTEGER,
name VARCHAR (50),
source VARCHAR (50),
created INTEGER,
reason VARCHAR (300),
expires INTEGER,
u_source VARCHAR (50),
u_reason VARCHAR (300),
u_date INTEGER,
last_pos VARCHAR (50)
);
players:
id INTEGER PRIMARY KEY AUTOINCREMENT,
ban BOOLEAN
CREATE TABLE name (
id INTEGER,
name VARCHAR (50) PRIMARY KEY,
created INTEGER,
last_login INTEGER,
login_count INTEGER (6) DEFAULT (1)
);
playerdata:
id INTEGER,
name VARCHAR (50),
ip VARCHAR (50),
created INTEGER,
last_login INTEGER
CREATE TABLE violation (
src_id INTEGER (10),
target_id INTEGER (10),
ip TEXT (20),
created INTEGER (30)
);
version:
rev VARCHAR(50)
whitelist:
name VARCHAR(50),
source VARCHAR(50),
created INTEGER
CREATE TABLE whitelist (
name VARCHAR (50),
source VARCHAR (50),
created INTEGER
);

243
tools/sban_update.sql Normal file
View File

@ -0,0 +1,243 @@
PRAGMA foreign_keys = OFF;
BEGIN TRANSACTION;
-- create new tables
-------------------------------------------------------
CREATE TABLE IF NOT EXISTS active (
id INTEGER PRIMARY KEY,
name VARCHAR(50),
source VARCHAR(50),
created INTEGER(30),
reason VARCHAR(300),
expires INTEGER(30),
pos VARCHAR(50)
);
CREATE TABLE IF NOT EXISTS expired (
id INTEGER,
name VARCHAR(50),
source VARCHAR(50),
created INTEGER(30),
reason VARCHAR(300),
expires INTEGER(30),
u_source VARCHAR(50),
u_reason VARCHAR(300),
u_date INTEGER(30),
last_pos VARCHAR(50)
);
CREATE INDEX IF NOT EXISTS idx_expired_id ON expired(id);
CREATE TABLE IF NOT EXISTS name (
id INTEGER,
name VARCHAR(50) PRIMARY KEY,
created INTEGER(30),
last_login INTEGER(30),
login_count INTEGER(8) DEFAULT(1)
);
CREATE INDEX IF NOT EXISTS idx_name_id ON name(id);
CREATE INDEX IF NOT EXISTS idx_name_lastlogin ON name(last_login);
CREATE TABLE IF NOT EXISTS address (
id INTEGER,
ip VARCHAR(50) PRIMARY KEY,
created INTEGER(30),
last_login INTEGER(30),
login_count INTEGER(8) DEFAULT(1),
violation BOOLEAN
);
CREATE INDEX IF NOT EXISTS idx_address_id ON address(id);
CREATE INDEX IF NOT EXISTS idx_address_lastlogin ON address(last_login);
CREATE TABLE IF NOT EXISTS whitelist (
name_or_ip VARCHAR(50) PRIMARY KEY,
source VARCHAR(50),
created INTEGER(30)
);
CREATE TABLE IF NOT EXISTS config (
setting VARCHAR PRIMARY KEY,
data VARCHAR
);
CREATE INDEX IF NOT EXISTS idx_config_data ON config(data);
CREATE TABLE IF NOT EXISTS violation (
id INTEGER PRIMARY KEY,
data VARCHAR
);
-- create temporary tables for transfering existing data
------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS address_tmp (
id INTEGER,
ip VARCHAR(50) PRIMARY KEY ON CONFLICT IGNORE,
created INTEGER(30),
last_login INTEGER(30),
login_count INTEGER(8) DEFAULT (1),
violation BOOLEAN
);
CREATE TABLE IF NOT EXISTS active_tmp (
id INTEGER PRIMARY KEY ON CONFLICT IGNORE,
name VARCHAR(50),
source VARCHAR(50),
created INTEGER(30),
reason VARCHAR(300),
expires INTEGER(30),
last_pos VARCHAR(50)
);
CREATE TABLE IF NOT EXISTS fix_tmp (
id INTEGER,
name VARCHAR(50),
source VARCHAR(50),
created INTEGER(30),
reason VARCHAR(300),
expires INTEGER(30),
u_source VARCHAR(50),
u_reason VARCHAR(300),
u_date INTEGER(30),
active BOOLEAN,
last_pos VARCHAR(50)
);
CREATE TABLE IF NOT EXISTS expired_tmp (
id INTEGER,
name VARCHAR (50),
source VARCHAR (50),
created INTEGER (30),
reason VARCHAR (300),
expires INTEGER (30),
u_source VARCHAR (50),
u_reason VARCHAR (300),
u_date INTEGER (30),
last_pos VARCHAR (50)
);
CREATE TABLE IF NOT EXISTS name_tmp (
id INTEGER,
name VARCHAR(50) PRIMARY KEY ON CONFLICT IGNORE,
created INTEGER(30),
last_login INTEGER(30),
login_count INTEGER(8) DEFAULT (1)
);
CREATE TABLE IF NOT EXISTS wl_tmp (
name VARCHAR,
source VARCHAR,
created INTEGER
);
-- fix whitelist name field
---------------------------------
INSERT INTO wl_tmp SELECT * FROM whitelist;
DROP TABLE whitelist;
CREATE TABLE whitelist (
name_or_ip VARCHAR(50) PRIMARY KEY,
source VARCHAR,
created INTEGER
);
INSERT INTO whitelist SELECT * FROM wl_tmp;
DROP TABLE wl_tmp;
-- fix text entry id's in bans table
------------------------------------
INSERT INTO fix_tmp SELECT
playerdata.id,
bans.name,
bans.source,
bans.created,
bans.reason,
bans.expires,
bans.u_source,
bans.u_reason,
bans.u_date,
bans.active,
bans.last_pos
FROM bans
INNER JOIN
playerdata ON playerdata.name = bans.name
WHERE typeof(bans.id) = 'text';
DELETE FROM bans WHERE typeof(bans.id) = 'text';
INSERT INTO bans SELECT * FROM fix_tmp;
-- transfer existing data to new tables
----------------------------------------------
-- insert the inactive bans into expired
INSERT INTO expired SELECT
id,
name,
source,
created,
reason,
expires,
u_source,
u_reason,
u_date,
last_pos
FROM bans WHERE active != 'true';
-- insert the active
INSERT INTO active_tmp SELECT
id,
name,
source,
created,
reason,
expires,
last_pos
FROM bans WHERE active = 'true';
-- initialise expires
UPDATE active SET expires = 0 WHERE expires = '';
-- initialise versions
INSERT INTO config VALUES('db_version', '0.2.1');
INSERT INTO config VALUES('mod_version', '0.2.0');
-- insert tmp table data
INSERT INTO address_tmp (id,ip,created,last_login)
SELECT DISTINCT id, ip, created, last_login FROM playerdata;
INSERT INTO name_tmp (id,name,created,last_login)
SELECT DISTINCT id, name, created, last_login FROM playerdata;
-- copy data from tmp tables
INSERT INTO address SELECT * FROM address_tmp;
INSERT INTO active SELECT * FROM active_tmp;
INSERT INTO name SELECT * FROM name_tmp;
-- process missed expired active entries
INSERT INTO expired_tmp (id,name,source,created,reason,expires,last_pos)
SELECT * FROM active WHERE expires < strftime('%s','now');
UPDATE expired_tmp SET
u_source = 'sban_update',
u_reason = 'ban expired',
u_date = strftime('%s','now');
INSERT INTO expired SELECT * FROM expired_tmp;
DELETE FROM active WHERE expires < strftime('%s','now');
-- clean up temporary tables
-----------------------------------------
DROP TABLE address_tmp;
DROP TABLE bans;
DROP TABLE active_tmp;
DROP TABLE name_tmp;
DROP TABLE players;
DROP TABLE playerdata;
DROP TABLE version;
DROP TABLE fix_tmp;
DROP TABLE expired_tmp;
COMMIT;
PRAGMA foreign_keys = ON;
-- compact db
VACUUM;