diff --git a/SQL/ban_conversion_2018-10-28.py b/SQL/ban_conversion_2018-10-28.py
new file mode 100644
index 00000000000..26d928bfd16
--- /dev/null
+++ b/SQL/ban_conversion_2018-10-28.py
@@ -0,0 +1,174 @@
+#Python 3+ Script for converting ban table format as of 2018-10-28 made by Jordie0608
+#
+#Before starting ensure you have installed the mysqlclient package https://github.com/PyMySQL/mysqlclient-python
+#It can be downloaded from command line with pip:
+#pip install mysqlclient
+#
+#You will also have to create a new ban table for inserting converted data to per the schema:
+#CREATE TABLE `ban` (
+# `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+# `bantime` DATETIME NOT NULL,
+# `server_ip` INT(10) UNSIGNED NOT NULL,
+# `server_port` SMALLINT(5) UNSIGNED NOT NULL,
+# `round_id` INT(11) UNSIGNED NOT NULL,
+# `role` VARCHAR(32) NULL DEFAULT NULL,
+# `expiration_time` DATETIME NULL DEFAULT NULL,
+# `applies_to_admins` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
+# `reason` VARCHAR(2048) NOT NULL,
+# `ckey` VARCHAR(32) NULL DEFAULT NULL,
+# `ip` INT(10) UNSIGNED NULL DEFAULT NULL,
+# `computerid` VARCHAR(32) NULL DEFAULT NULL,
+# `a_ckey` VARCHAR(32) NOT NULL,
+# `a_ip` INT(10) UNSIGNED NOT NULL,
+# `a_computerid` VARCHAR(32) NOT NULL,
+# `who` VARCHAR(2048) NOT NULL,
+# `adminwho` VARCHAR(2048) NOT NULL,
+# `edits` TEXT NULL DEFAULT NULL,
+# `unbanned_datetime` DATETIME NULL DEFAULT NULL,
+# `unbanned_ckey` VARCHAR(32) NULL DEFAULT NULL,
+# `unbanned_ip` INT(10) UNSIGNED NULL DEFAULT NULL,
+# `unbanned_computerid` VARCHAR(32) NULL DEFAULT NULL,
+# `unbanned_round_id` INT(11) UNSIGNED NULL DEFAULT NULL,
+# PRIMARY KEY (`id`),
+# KEY `idx_ban_isbanned` (`ckey`,`role`,`unbanned_datetime`,`expiration_time`),
+# KEY `idx_ban_isbanned_details` (`ckey`,`ip`,`computerid`,`role`,`unbanned_datetime`,`expiration_time`),
+# KEY `idx_ban_count` (`bantime`,`a_ckey`,`applies_to_admins`,`unbanned_datetime`,`expiration_time`)
+#) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+#This is to prevent the destruction of existing data and allow rollbacks to be performed in the event of an error during conversion
+#Once conversion is complete remember to rename the old and new ban tables; it's up to you if you want to keep the old table
+#
+#To view the parameters for this script, execute it with the argument --help
+#All the positional arguments are required, remember to include prefixes in your table names if you use them
+#An example of the command used to execute this script from powershell:
+#python ban_conversion_2018-10-28.py "localhost" "root" "password" "feedback" "SS13_ban" "SS13_ban_new"
+#I found that this script would complete conversion of 35000 rows in approximately 20 seconds, results will depend on the size of your ban table and computer used
+#
+#The script has been tested to complete with tgstation's ban table as of 2018-09-02 02:19:56
+#In the event of an error the new ban table is automatically truncated
+#The source table is never modified so you don't have to worry about losing any data due to errors
+#Some additional error correction is performed to fix problems specific to legacy and invalid data in tgstation's ban table, these operations are tagged with a 'TG:' comment
+#Even if you don't have any of these specific problems in your ban table the operations won't have matter as they have an insignificant effect on runtime
+#
+#While this script is safe to run with your game server(s) active, any bans created after the script has started won't be converted
+#You will also have to ensure that the code and table names are updated between rounds as neither will be compatible
+
+import MySQLdb
+import argparse
+import sys
+from datetime import datetime
+
+def parse_role(bantype, job):
+ if bantype in ("PERMABAN", "TEMPBAN", "ADMIN_PERMABAN", "ADMIN_TEMPBAN"):
+ role = "Server"
+ else:
+ #TG: Some legacy jobbans are missing the last character from their job string.
+ job_name_fixes = {"A":"AI", "Captai":"Captain", "Cargo Technicia":"Cargo Technician", "Chaplai":"Chaplain", "Che":"Chef", "Chemis":"Chemist", "Chief Enginee":"Chief Engineer", "Chief Medical Office":"Chief Medical Officer", "Cybor":"Cyborg", "Detectiv":"Detective", "Head of Personne":"Head of Personnel", "Head of Securit":"Head of Security", "Mim":"Mime", "pA":"pAI", "Quartermaste":"Quartermaster", "Research Directo":"Research Director", "Scientis":"Scientist", "Security Office":"Security Officer", "Station Enginee":"Station Engineer", "Syndicat":"Syndicate", "Warde":"Warden"}
+ keep_job_names = ("AI", "Head of Personnel", "Head of Security", "OOC", "pAI")
+ if job in job_name_fixes:
+ role = job_name_fixes[job]
+ #Some job names we want to keep the same as .title() would return a different string.
+ elif job in keep_job_names:
+ role = job
+ #And then there's this asshole.
+ elif job == "servant of Ratvar":
+ role = "Servant of Ratvar"
+ else:
+ role = job.title()
+ return role
+
+def parse_admin(bantype):
+ if bantype in ("ADMIN_PERMABAN", "ADMIN_TEMPBAN"):
+ return 1
+ else:
+ return 0
+
+def parse_datetime(bantype, expiration_time):
+ if bantype in ("PERMABAN", "JOB_PERMABAN", "ADMIN_PERMABAN"):
+ expiration_time = None
+ #TG: two bans with an invalid expiration_time due to admins setting the duration to approx. 19 billion years, I'm going to count them as permabans.
+ elif expiration_time == "0000-00-00 00:00:00":
+ expiration_time = None
+ elif not expiration_time:
+ expiration_time = None
+ return expiration_time
+
+def parse_not_null(field):
+ if not field:
+ field = 0
+ return field
+
+def parse_for_empty(field):
+ if not field:
+ field = None
+ #TG: Several bans from 2012, probably from clients disconnecting while a ban was being made.
+ elif field == "BLANK CKEY ERROR":
+ field = None
+ return field
+
+if sys.version_info[0] < 3:
+ raise Exception("Python must be at least version 3 for this script.")
+current_round = 0
+parser = argparse.ArgumentParser()
+parser.add_argument("address", help="MySQL server address (use localhost for the current computer)")
+parser.add_argument("username", help="MySQL login username")
+parser.add_argument("password", help="MySQL login username")
+parser.add_argument("database", help="Database name")
+parser.add_argument("curtable", help="Name of the current ban table (remember prefixes if you use them)")
+parser.add_argument("newtable", help="Name of the new table to insert to, can't be same as the source table (remember prefixes)")
+args = parser.parse_args()
+db=MySQLdb.connect(host=args.address, user=args.username, passwd=args.password, db=args.database)
+cursor=db.cursor()
+current_table = args.curtable
+new_table = args.newtable
+#TG: Due to deleted rows and a legacy ban import being inserted from id 3140 id order is not contiguous or in line with date order. While technically valid, it's confusing and I don't like that.
+#TG: So instead of just running through to MAX(id) we're going to reorder the records by bantime as we go.
+cursor.execute("SELECT id FROM " + current_table + " ORDER BY bantime ASC")
+id_list = cursor.fetchall()
+start_time = datetime.now()
+print("Beginning conversion at {0}".format(start_time.strftime("%Y-%m-%d %H:%M:%S")))
+try:
+ for current_id in id_list:
+ if current_id[0] % 5000 == 0:
+ cur_time = datetime.now()
+ print("Reached row ID {0} Duration: {1}".format(current_id[0], cur_time - start_time))
+ cursor.execute("SELECT * FROM " + current_table + " WHERE id = %s", [current_id[0]])
+ query_row = cursor.fetchone()
+ if not query_row:
+ continue
+ else:
+ #TG: bans with an empty reason which were somehow created with almost every field being null or empty, we can't do much but skip this
+ if not query_row[6]:
+ continue
+ bantime = query_row[1]
+ server_ip = query_row[2]
+ server_port = query_row[3]
+ round_id = query_row[4]
+ applies_to_admins = parse_admin(query_row[5])
+ reason = query_row[6]
+ role = parse_role(query_row[5], query_row[7])
+ expiration_time = parse_datetime(query_row[5], query_row[9])
+ ckey = parse_for_empty(query_row[10])
+ computerid = parse_for_empty(query_row[11])
+ ip = parse_for_empty(query_row[12])
+ a_ckey = parse_not_null(query_row[13])
+ a_computerid = parse_not_null(query_row[14])
+ a_ip = parse_not_null(query_row[15])
+ who = query_row[16]
+ adminwho = query_row[17]
+ edits = parse_for_empty(query_row[18])
+ unbanned_datetime = parse_datetime(None, query_row[20])
+ unbanned_ckey = parse_for_empty(query_row[21])
+ unbanned_computerid = parse_for_empty(query_row[22])
+ unbanned_ip = parse_for_empty(query_row[23])
+ cursor.execute("INSERT INTO " + new_table + " (bantime, server_ip, server_port, round_id, role, expiration_time, applies_to_admins, reason, ckey, ip, computerid, a_ckey, a_ip, a_computerid, who, adminwho, edits, unbanned_datetime, unbanned_ckey, unbanned_ip, unbanned_computerid) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)", (bantime, server_ip, server_port, round_id, role, expiration_time, applies_to_admins, reason, ckey, ip, computerid, a_ckey, a_ip, a_computerid, who, adminwho, edits, unbanned_datetime, unbanned_ckey, unbanned_ip, unbanned_computerid))
+ db.commit()
+ end_time = datetime.now()
+ print("Conversion completed at {0}".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
+ print("Script duration: {0}".format(end_time - start_time))
+except Exception as e:
+ end_time = datetime.now()
+ print("Error encountered on row ID {0} at {1}".format(current_id[0], datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
+ print("Script duration: {0}".format(end_time - start_time))
+ cursor.execute("TRUNCATE {0} ".format(new_table))
+ raise e
+cursor.close()
diff --git a/SQL/database_changelog.txt b/SQL/database_changelog.txt
index 56f05e84f10..24ad3f1a659 100644
--- a/SQL/database_changelog.txt
+++ b/SQL/database_changelog.txt
@@ -2,14 +2,52 @@ Any time you make a change to the schema files, remember to increment the databa
The latest database version is 4.7; The query to update the schema revision table is:
-INSERT INTO `schema_revision` (`major`, `minor`) VALUES (4, 7);
+INSERT INTO `schema_revision` (`major`, `minor`) VALUES (5, 0);
or
-INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (4, 7);
+INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (5, 0);
In any query remember to add a prefix to the table names if you use one.
----------------------------------------------------
+Version 5.0, 28 October 2018, by Jordie0608
+Modified ban table to remove the need for the `bantype` column, a python script is used to migrate data to this new format.
+
+See the file 'ban_conversion_2018-10-28.py' for instructions on how to use the script.
+
+A new ban table can be created with the query:
+CREATE TABLE `ban` (
+ `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `bantime` DATETIME NOT NULL,
+ `server_ip` INT(10) UNSIGNED NOT NULL,
+ `server_port` SMALLINT(5) UNSIGNED NOT NULL,
+ `round_id` INT(11) UNSIGNED NOT NULL,
+ `role` VARCHAR(32) NULL DEFAULT NULL,
+ `expiration_time` DATETIME NULL DEFAULT NULL,
+ `applies_to_admins` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
+ `reason` VARCHAR(2048) NOT NULL,
+ `ckey` VARCHAR(32) NULL DEFAULT NULL,
+ `ip` INT(10) UNSIGNED NULL DEFAULT NULL,
+ `computerid` VARCHAR(32) NULL DEFAULT NULL,
+ `a_ckey` VARCHAR(32) NOT NULL,
+ `a_ip` INT(10) UNSIGNED NOT NULL,
+ `a_computerid` VARCHAR(32) NOT NULL,
+ `who` VARCHAR(2048) NOT NULL,
+ `adminwho` VARCHAR(2048) NOT NULL,
+ `edits` TEXT NULL DEFAULT NULL,
+ `unbanned_datetime` DATETIME NULL DEFAULT NULL,
+ `unbanned_ckey` VARCHAR(32) NULL DEFAULT NULL,
+ `unbanned_ip` INT(10) UNSIGNED NULL DEFAULT NULL,
+ `unbanned_computerid` VARCHAR(32) NULL DEFAULT NULL,
+ `unbanned_round_id` INT(11) UNSIGNED NULL DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `idx_ban_isbanned` (`ckey`,`role`,`unbanned_datetime`,`expiration_time`),
+ KEY `idx_ban_isbanned_details` (`ckey`,`ip`,`computerid`,`role`,`unbanned_datetime`,`expiration_time`),
+ KEY `idx_ban_count` (`bantime`,`a_ckey`,`applies_to_admins`,`unbanned_datetime`,`expiration_time`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+----------------------------------------------------
+
Version 4.7, 18 August 2018, by CitrusGender
Modified table `messages`, adding column `severity` to classify notes based on their severity.
diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql
index dc0861220ae..6127c5b37de 100644
--- a/SQL/tgstation_schema.sql
+++ b/SQL/tgstation_schema.sql
@@ -67,34 +67,33 @@ DROP TABLE IF EXISTS `ban`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `ban` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `bantime` datetime NOT NULL,
- `server_ip` int(10) unsigned NOT NULL,
- `server_port` smallint(5) unsigned NOT NULL,
- `round_id` int(11) NOT NULL,
- `bantype` enum('PERMABAN','TEMPBAN','JOB_PERMABAN','JOB_TEMPBAN','ADMIN_PERMABAN','ADMIN_TEMPBAN') NOT NULL,
- `reason` varchar(2048) NOT NULL,
- `job` varchar(32) DEFAULT NULL,
- `duration` int(11) NOT NULL,
- `expiration_time` datetime NOT NULL,
- `ckey` varchar(32) NOT NULL,
- `computerid` varchar(32) NOT NULL,
- `ip` int(10) unsigned NOT NULL,
- `a_ckey` varchar(32) NOT NULL,
- `a_computerid` varchar(32) NOT NULL,
- `a_ip` int(10) unsigned NOT NULL,
- `who` varchar(2048) NOT NULL,
- `adminwho` varchar(2048) NOT NULL,
- `edits` text,
- `unbanned` tinyint(3) unsigned DEFAULT NULL,
- `unbanned_datetime` datetime DEFAULT NULL,
- `unbanned_ckey` varchar(32) DEFAULT NULL,
- `unbanned_computerid` varchar(32) DEFAULT NULL,
- `unbanned_ip` int(10) unsigned DEFAULT NULL,
+ `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `bantime` DATETIME NOT NULL,
+ `server_ip` INT(10) UNSIGNED NOT NULL,
+ `server_port` SMALLINT(5) UNSIGNED NOT NULL,
+ `round_id` INT(11) UNSIGNED NOT NULL,
+ `role` VARCHAR(32) NULL DEFAULT NULL,
+ `expiration_time` DATETIME NULL DEFAULT NULL,
+ `applies_to_admins` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
+ `reason` VARCHAR(2048) NOT NULL,
+ `ckey` VARCHAR(32) NULL DEFAULT NULL,
+ `ip` INT(10) UNSIGNED NULL DEFAULT NULL,
+ `computerid` VARCHAR(32) NULL DEFAULT NULL,
+ `a_ckey` VARCHAR(32) NOT NULL,
+ `a_ip` INT(10) UNSIGNED NOT NULL,
+ `a_computerid` VARCHAR(32) NOT NULL,
+ `who` VARCHAR(2048) NOT NULL,
+ `adminwho` VARCHAR(2048) NOT NULL,
+ `edits` TEXT NULL DEFAULT NULL,
+ `unbanned_datetime` DATETIME NULL DEFAULT NULL,
+ `unbanned_ckey` VARCHAR(32) NULL DEFAULT NULL,
+ `unbanned_ip` INT(10) UNSIGNED NULL DEFAULT NULL,
+ `unbanned_computerid` VARCHAR(32) NULL DEFAULT NULL,
+ `unbanned_round_id` INT(11) UNSIGNED NULL DEFAULT NULL,
PRIMARY KEY (`id`),
- KEY `idx_ban_checkban` (`ckey`,`bantype`,`expiration_time`,`unbanned`,`job`),
- KEY `idx_ban_isbanned` (`ckey`,`ip`,`computerid`,`bantype`,`expiration_time`,`unbanned`),
- KEY `idx_ban_count` (`id`,`a_ckey`,`bantype`,`expiration_time`,`unbanned`)
+ KEY `idx_ban_isbanned` (`ckey`,`role`,`unbanned_datetime`,`expiration_time`),
+ KEY `idx_ban_isbanned_details` (`ckey`,`ip`,`computerid`,`role`,`unbanned_datetime`,`expiration_time`),
+ KEY `idx_ban_count` (`bantime`,`a_ckey`,`applies_to_admins`,`unbanned_datetime`,`expiration_time`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql
index 5cb57a9582e..e17ef712472 100644
--- a/SQL/tgstation_schema_prefixed.sql
+++ b/SQL/tgstation_schema_prefixed.sql
@@ -67,34 +67,33 @@ DROP TABLE IF EXISTS `SS13_ban`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `SS13_ban` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `bantime` datetime NOT NULL,
- `server_ip` int(10) unsigned NOT NULL,
- `server_port` smallint(5) unsigned NOT NULL,
- `round_id` int(11) NOT NULL,
- `bantype` enum('PERMABAN','TEMPBAN','JOB_PERMABAN','JOB_TEMPBAN','ADMIN_PERMABAN','ADMIN_TEMPBAN') NOT NULL,
- `reason` varchar(2048) NOT NULL,
- `job` varchar(32) DEFAULT NULL,
- `duration` int(11) NOT NULL,
- `expiration_time` datetime NOT NULL,
- `ckey` varchar(32) NOT NULL,
- `computerid` varchar(32) NOT NULL,
- `ip` int(10) unsigned NOT NULL,
- `a_ckey` varchar(32) NOT NULL,
- `a_computerid` varchar(32) NOT NULL,
- `a_ip` int(10) unsigned NOT NULL,
- `who` varchar(2048) NOT NULL,
- `adminwho` varchar(2048) NOT NULL,
- `edits` text,
- `unbanned` tinyint(3) unsigned DEFAULT NULL,
- `unbanned_datetime` datetime DEFAULT NULL,
- `unbanned_ckey` varchar(32) DEFAULT NULL,
- `unbanned_computerid` varchar(32) DEFAULT NULL,
- `unbanned_ip` int(10) unsigned DEFAULT NULL,
+ `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `bantime` DATETIME NOT NULL,
+ `server_ip` INT(10) UNSIGNED NOT NULL,
+ `server_port` SMALLINT(5) UNSIGNED NOT NULL,
+ `round_id` INT(11) UNSIGNED NOT NULL,
+ `role` VARCHAR(32) NULL DEFAULT NULL,
+ `expiration_time` DATETIME NULL DEFAULT NULL,
+ `applies_to_admins` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
+ `reason` VARCHAR(2048) NOT NULL,
+ `ckey` VARCHAR(32) NULL DEFAULT NULL,
+ `ip` INT(10) UNSIGNED NULL DEFAULT NULL,
+ `computerid` VARCHAR(32) NULL DEFAULT NULL,
+ `a_ckey` VARCHAR(32) NOT NULL,
+ `a_ip` INT(10) UNSIGNED NOT NULL,
+ `a_computerid` VARCHAR(32) NOT NULL,
+ `who` VARCHAR(2048) NOT NULL,
+ `adminwho` VARCHAR(2048) NOT NULL,
+ `edits` TEXT NULL DEFAULT NULL,
+ `unbanned_datetime` DATETIME NULL DEFAULT NULL,
+ `unbanned_ckey` VARCHAR(32) NULL DEFAULT NULL,
+ `unbanned_ip` INT(10) UNSIGNED NULL DEFAULT NULL,
+ `unbanned_computerid` VARCHAR(32) NULL DEFAULT NULL,
+ `unbanned_round_id` INT(11) UNSIGNED NULL DEFAULT NULL,
PRIMARY KEY (`id`),
- KEY `idx_ban_checkban` (`ckey`,`bantype`,`expiration_time`,`unbanned`,`job`),
- KEY `idx_ban_isbanned` (`ckey`,`ip`,`computerid`,`bantype`,`expiration_time`,`unbanned`),
- KEY `idx_ban_count` (`id`,`a_ckey`,`bantype`,`expiration_time`,`unbanned`)
+ KEY `idx_ban_isbanned` (`ckey`,`role`,`unbanned_datetime`,`expiration_time`),
+ KEY `idx_ban_isbanned_details` (`ckey`,`ip`,`computerid`,`role`,`unbanned_datetime`,`expiration_time`),
+ KEY `idx_ban_count` (`bantime`,`a_ckey`,`applies_to_admins`,`unbanned_datetime`,`expiration_time`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index b694d101761..edf8af92f81 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -6,35 +6,35 @@
//These are synced with the Database, if you change the values of the defines
//then you MUST update the database!
-#define ROLE_SYNDICATE "Syndicate"
-#define ROLE_TRAITOR "traitor"
-#define ROLE_OPERATIVE "operative"
-#define ROLE_CHANGELING "changeling"
-#define ROLE_WIZARD "wizard"
-#define ROLE_MALF "malf AI"
-#define ROLE_REV "revolutionary"
-#define ROLE_REV_HEAD "Head Revolutionary"
-#define ROLE_ALIEN "xenomorph"
-#define ROLE_PAI "pAI"
-#define ROLE_CULTIST "cultist"
-#define ROLE_BLOB "blob"
-#define ROLE_NINJA "space ninja"
-#define ROLE_MONKEY "monkey"
-#define ROLE_ABDUCTOR "abductor"
-#define ROLE_REVENANT "revenant"
-#define ROLE_DEVIL "devil"
-#define ROLE_SERVANT_OF_RATVAR "servant of Ratvar"
-#define ROLE_BROTHER "blood brother"
-#define ROLE_BRAINWASHED "brainwashed victim"
-#define ROLE_OVERTHROW "syndicate mutineer"
-#define ROLE_HIVE "hivemind host"
-#define ROLE_SENTIENCE "sentience potion spawn"
-#define ROLE_MIND_TRANSFER "mind transfer potion"
-#define ROLE_POSIBRAIN "posibrain"
-#define ROLE_DRONE "drone"
-#define ROLE_DEATHSQUAD "deathsquad"
-#define ROLE_LAVALAND "lavaland"
-#define ROLE_INTERNAL_AFFAIRS "internal affairs agent"
+#define ROLE_SYNDICATE "Syndicate"
+#define ROLE_TRAITOR "Traitor"
+#define ROLE_OPERATIVE "Operative"
+#define ROLE_CHANGELING "Changeling"
+#define ROLE_WIZARD "Wizard"
+#define ROLE_MALF "Malf AI"
+#define ROLE_REV "Revolutionary"
+#define ROLE_REV_HEAD "Head Revolutionary"
+#define ROLE_ALIEN "Xenomorph"
+#define ROLE_PAI "pAI"
+#define ROLE_CULTIST "Cultist"
+#define ROLE_BLOB "Blob"
+#define ROLE_NINJA "Space Ninja"
+#define ROLE_MONKEY "Monkey"
+#define ROLE_ABDUCTOR "Abductor"
+#define ROLE_REVENANT "Revenant"
+#define ROLE_DEVIL "Devil"
+#define ROLE_SERVANT_OF_RATVAR "Servant of Ratvar"
+#define ROLE_BROTHER "Blood Brother"
+#define ROLE_BRAINWASHED "Brainwashed Victim"
+#define ROLE_OVERTHROW "Syndicate Mutineer"
+#define ROLE_HIVE "Hivemind Host"
+#define ROLE_SENTIENCE "Sentience Potion Spawn"
+#define ROLE_MIND_TRANSFER "Mind Transfer Potion"
+#define ROLE_POSIBRAIN "Posibrain"
+#define ROLE_DRONE "Drone"
+#define ROLE_DEATHSQUAD "Deathsquad"
+#define ROLE_LAVALAND "Lavaland"
+#define ROLE_INTERNAL_AFFAIRS "Internal Affairs Agent"
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 39da6d14099..89f281678a8 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -1,7 +1,7 @@
//Update this whenever the db schema changes
//make sure you add an update to the schema_version stable in the db changelog
-#define DB_MAJOR_VERSION 4
-#define DB_MINOR_VERSION 7
+#define DB_MAJOR_VERSION 5
+#define DB_MINOR_VERSION 0
//Timing subsystem
//Don't run if there is an identical unique timer active
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index 0655e8f53e8..62cff3e6bb7 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -433,7 +433,7 @@
if(!gametypeCheck.age_check(M.client))
continue
if(jobbanType)
- if(jobban_isbanned(M, jobbanType) || QDELETED(M) || jobban_isbanned(M, ROLE_SYNDICATE) || QDELETED(M))
+ if(is_banned_from(M.ckey, list(jobbanType, ROLE_SYNDICATE)) || QDELETED(M))
continue
showCandidatePollWindow(M, poll_time, Question, result, ignore_category, time_passed, flashwindow)
@@ -494,7 +494,7 @@
if(!C || (!C.prefs.windowflashing && !ignorepref))
return
winset(C, "mainwindow", "flash=5")
-
+
//Recursively checks if an item is inside a given type, even through layers of storage. Returns the atom if it finds it.
/proc/recursive_loc_check(atom/movable/target, type)
var/atom/A = target
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index f37269a1024..27b7eb75a94 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -203,7 +203,7 @@ Turf and target are separate in case you want to teleport some distance from a t
var/loop = 1
var/safety = 0
- var/banned = jobban_isbanned(src, "appearance")
+ var/banned = is_banned_from(C.ckey, "Appearance")
while(loop && safety < 5)
if(C && C.prefs.custom_names[role] && !safety && !banned)
diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm
index b73f2bdebba..807b7209ff0 100644
--- a/code/controllers/configuration/entries/general.dm
+++ b/code/controllers/configuration/entries/general.dm
@@ -153,9 +153,6 @@
/datum/config_entry/flag/usewhitelist
-/datum/config_entry/flag/ban_legacy_system //Defines whether the server uses the legacy banning system with the files in /data or the SQL system.
- protection = CONFIG_ENTRY_LOCKED
-
/datum/config_entry/flag/use_age_restriction_for_jobs //Do jobs use account age restrictions? --requires database
/datum/config_entry/flag/use_account_age_for_jobs //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected.
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index ab6cf5124c5..e56bf79e797 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -79,7 +79,7 @@ SUBSYSTEM_DEF(job)
var/datum/job/job = GetJob(rank)
if(!job)
return FALSE
- if(jobban_isbanned(player, rank) || QDELETED(player))
+ if(is_banned_from(player.ckey, rank) || QDELETED(player))
return FALSE
if(!job.player_old_enough(player.client))
return FALSE
@@ -101,7 +101,7 @@ SUBSYSTEM_DEF(job)
JobDebug("Running FOC, Job: [job], Level: [level], Flag: [flag]")
var/list/candidates = list()
for(var/mob/dead/new_player/player in unassigned)
- if(jobban_isbanned(player, job.title) || QDELETED(player))
+ if(is_banned_from(player.ckey, job.title) || QDELETED(player))
JobDebug("FOC isbanned failed, Player: [player]")
continue
if(!job.player_old_enough(player.client))
@@ -134,7 +134,7 @@ SUBSYSTEM_DEF(job)
if(job.title in GLOB.command_positions) //If you want a command position, select it!
continue
- if(jobban_isbanned(player, job.title) || QDELETED(player))
+ if(is_banned_from(player.ckey, job.title) || QDELETED(player))
if(QDELETED(player))
JobDebug("GRJ isbanned failed, Player deleted")
break
@@ -311,7 +311,7 @@ SUBSYSTEM_DEF(job)
if(!job)
continue
- if(jobban_isbanned(player, job.title))
+ if(is_banned_from(player.ckey, job.title))
JobDebug("DO isbanned failed, Player: [player], Job:[job.title]")
continue
@@ -360,7 +360,7 @@ SUBSYSTEM_DEF(job)
if(PopcapReached())
RejectPlayer(player)
else if(player.client.prefs.joblessrole == BEOVERFLOW)
- var/allowed_to_be_a_loser = !jobban_isbanned(player, SSjob.overflow_role)
+ var/allowed_to_be_a_loser = !is_banned_from(player.ckey, SSjob.overflow_role)
if(QDELETED(player) || !allowed_to_be_a_loser)
RejectPlayer(player)
else
@@ -489,7 +489,7 @@ SUBSYSTEM_DEF(job)
for(var/mob/dead/new_player/player in GLOB.player_list)
if(!(player.ready == PLAYER_READY_TO_PLAY && player.mind && !player.mind.assigned_role))
continue //This player is not ready
- if(jobban_isbanned(player, job.title) || QDELETED(player))
+ if(is_banned_from(player.ckey, job.title) || QDELETED(player))
banned++
continue
if(!job.player_old_enough(player.client))
diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm
index 9dde4f01577..51abd1f47ac 100644
--- a/code/datums/diseases/transformation.dm
+++ b/code/datums/diseases/transformation.dm
@@ -61,7 +61,7 @@
affected_mob.dropItemToGround(I)
var/mob/living/new_mob = new new_form(affected_mob.loc)
if(istype(new_mob))
- if(bantype && jobban_isbanned(affected_mob, bantype))
+ if(bantype && is_banned_from(affected_mob.ckey, bantype))
replace_banned_player(new_mob)
new_mob.a_intent = INTENT_HARM
if(affected_mob.mind)
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index 98c9a0bfc91..a7f6065bc10 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -84,7 +84,7 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th
return
if(changelings.len <= (changelingcap - 2) || prob(100 - (csc * 2)))
if(ROLE_CHANGELING in character.client.prefs.be_special)
- if(!jobban_isbanned(character, ROLE_CHANGELING) && !QDELETED(character) && !jobban_isbanned(character, ROLE_SYNDICATE) && !QDELETED(character))
+ if(!is_banned_from(character.ckey, list(ROLE_CHANGELING, ROLE_SYNDICATE)) && !QDELETED(character))
if(age_check(character.client))
if(!(character.job in restricted_jobs))
character.mind.make_Changeling()
diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm
index 9f6fe524cbe..70c04cb008f 100644
--- a/code/game/gamemodes/changeling/traitor_chan.dm
+++ b/code/game/gamemodes/changeling/traitor_chan.dm
@@ -70,7 +70,7 @@
return
if(changelings.len <= (changelingcap - 2) || prob(100 / (csc * 4)))
if(ROLE_CHANGELING in character.client.prefs.be_special)
- if(!jobban_isbanned(character, ROLE_CHANGELING) && !QDELETED(character) && !jobban_isbanned(character, ROLE_SYNDICATE) && !QDELETED(character))
+ if(!is_banned_from(character.ckey, list(ROLE_CHANGELING, ROLE_SYNDICATE)) && !QDELETED(character))
if(age_check(character.client))
if(!(character.job in restricted_jobs))
character.mind.make_Changeling()
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 3fbeb5f754c..e1945ea4d8e 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -368,7 +368,7 @@
for(var/mob/dead/new_player/player in players)
if(player.client && player.ready == PLAYER_READY_TO_PLAY)
if(role in player.client.prefs.be_special)
- if(!jobban_isbanned(player, ROLE_SYNDICATE) && !QDELETED(player) && !jobban_isbanned(player, role) && !QDELETED(player)) //Nodrak/Carn: Antag Job-bans
+ if(!is_banned_from(player.ckey, list(role, ROLE_SYNDICATE)) && !QDELETED(player))
if(age_check(player.client)) //Must be older than the minimum age
candidates += player.mind // Get a list of all the people who want to be the antagonist for this round
@@ -382,7 +382,7 @@
for(var/mob/dead/new_player/player in players)
if(player.client && player.ready == PLAYER_READY_TO_PLAY)
if(!(role in player.client.prefs.be_special)) // We don't have enough people who want to be antagonist, make a separate list of people who don't want to be one
- if(!jobban_isbanned(player, ROLE_SYNDICATE) && !QDELETED(player) && !jobban_isbanned(player, role) && !QDELETED(player) ) //Nodrak/Carn: Antag Job-bans
+ if(!is_banned_from(player.ckey, list(role, ROLE_SYNDICATE)) && !QDELETED(player))
drafted += player.mind
if(restricted_jobs)
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index a00797bde49..fe8948ed0d6 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -86,7 +86,7 @@
return
if((SSticker.mode.traitors.len + pre_traitors.len) <= (traitorcap - 2) || prob(100 / (tsc * 2)))
if(antag_flag in character.client.prefs.be_special)
- if(!jobban_isbanned(character, ROLE_TRAITOR) && !QDELETED(character) && !jobban_isbanned(character, ROLE_SYNDICATE) && !QDELETED(character))
+ if(!is_banned_from(character.ckey, list(ROLE_TRAITOR, ROLE_SYNDICATE)) && !QDELETED(character))
if(age_check(character.client))
if(!(character.job in restricted_jobs))
add_latejoin_traitor(character.mind)
@@ -97,4 +97,4 @@
/datum/game_mode/traitor/generate_report()
return "Although more specific threats are commonplace, you should always remain vigilant for Syndicate agents aboard your station. Syndicate communications have implied that many \
- Nanotrasen employees are Syndicate agents with hidden memories that may be activated at a moment's notice, so it's possible that these agents might not even know their positions."
\ No newline at end of file
+ Nanotrasen employees are Syndicate agents with hidden memories that may be activated at a moment's notice, so it's possible that these agents might not even know their positions."
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index 5538493d717..e4d7c3384d8 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -262,7 +262,7 @@
to_chat(user, "The MMI indicates that the brain is damaged! ")
return
- if(jobban_isbanned(BM, "Cyborg") || QDELETED(src) || QDELETED(BM) || QDELETED(user) || QDELETED(M) || !Adjacent(user))
+ if(is_banned_from(BM.ckey, "Cyborg") || QDELETED(src) || QDELETED(BM) || QDELETED(user) || QDELETED(M) || !Adjacent(user))
if(!QDELETED(M))
to_chat(user, "This [M.name] does not seem to fit! ")
return
diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm
index fd71fb26aee..390e28893d8 100644
--- a/code/game/objects/structures/ai_core.dm
+++ b/code/game/objects/structures/ai_core.dm
@@ -195,7 +195,7 @@
to_chat(user, "Sticking an inactive [M.name] into the frame would sort of defeat the purpose. ")
return
- if(!CONFIG_GET(flag/allow_ai) || (jobban_isbanned(M.brainmob, "AI") && !QDELETED(src) && !QDELETED(user) && !QDELETED(M) && !QDELETED(user) && Adjacent(user)))
+ if(!CONFIG_GET(flag/allow_ai) || (is_banned_from(M.brainmob.ckey, "AI") && !QDELETED(src) && !QDELETED(user) && !QDELETED(M) && !QDELETED(user) && Adjacent(user)))
if(!QDELETED(M))
to_chat(user, "This [M.name] does not seem to fit! ")
return
diff --git a/code/game/world.dm b/code/game/world.dm
index f293db27d0d..e1e75a87c7a 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -36,7 +36,6 @@ GLOBAL_VAR_INIT(bypass_tgs_reboot, world.system_type == UNIX && world.byond_buil
LoadVerbs(/datum/verbs/menu)
if(CONFIG_GET(flag/usewhitelist))
load_whitelist()
- LoadBans()
GLOB.timezoneOffset = text2num(time2text(0,"hh")) * 36000
diff --git a/code/modules/admin/DB_ban/functions.dm b/code/modules/admin/DB_ban/functions.dm
deleted file mode 100644
index f60ec22489a..00000000000
--- a/code/modules/admin/DB_ban/functions.dm
+++ /dev/null
@@ -1,561 +0,0 @@
-#define MAX_ADMIN_BANS_PER_ADMIN 1
-#define MAX_ADMIN_BANS_PER_HEADMIN 3
-
-//Either pass the mob you wish to ban in the 'banned_mob' attribute, or the banckey, banip and bancid variables. If both are passed, the mob takes priority! If a mob is not passed, banckey is the minimum that needs to be passed! banip and bancid are optional.
-/datum/admins/proc/DB_ban_record(bantype, mob/banned_mob, duration = -1, reason, job = "", bankey = null, banip = null, bancid = null)
-
- if(!check_rights(R_BAN))
- return
-
- if(!SSdbcore.Connect())
- to_chat(src, "Failed to establish database connection. ")
- return
-
- var/bantype_pass = 0
- var/bantype_str
- var/maxadminbancheck //Used to limit the number of active bans of a certein type that each admin can give. Used to protect against abuse or mutiny.
- var/announceinirc //When set, it announces the ban in irc. Intended to be a way to raise an alarm, so to speak.
- var/blockselfban //Used to prevent the banning of yourself.
- var/kickbannedckey //Defines whether this proc should kick the banned person, if they are connected (if banned_mob is defined).
- //some ban types kick players after this proc passes (tempban, permaban), but some are specific to db_ban, so
- //they should kick within this proc.
- switch(bantype)
- if(BANTYPE_PERMA)
- bantype_str = "PERMABAN"
- duration = -1
- bantype_pass = 1
- blockselfban = 1
- if(BANTYPE_TEMP)
- bantype_str = "TEMPBAN"
- bantype_pass = 1
- blockselfban = 1
- if(BANTYPE_JOB_PERMA)
- bantype_str = "JOB_PERMABAN"
- duration = -1
- bantype_pass = 1
- if(BANTYPE_JOB_TEMP)
- bantype_str = "JOB_TEMPBAN"
- bantype_pass = 1
- if(BANTYPE_ADMIN_PERMA)
- bantype_str = "ADMIN_PERMABAN"
- duration = -1
- bantype_pass = 1
- maxadminbancheck = 1
- announceinirc = 1
- blockselfban = 1
- kickbannedckey = 1
- if(BANTYPE_ADMIN_TEMP)
- bantype_str = "ADMIN_TEMPBAN"
- bantype_pass = 1
- maxadminbancheck = 1
- announceinirc = 1
- blockselfban = 1
- kickbannedckey = 1
- if( !bantype_pass )
- return
- if( !istext(reason) )
- return
- if( !isnum(duration) )
- return
-
- var/ckey
- var/computerid
- var/ip
-
- if(ismob(banned_mob))
- ckey = banned_mob.ckey
- bankey = banned_mob.key
- if(banned_mob.client)
- computerid = banned_mob.client.computer_id
- ip = banned_mob.client.address
- else
- computerid = banned_mob.computer_id
- ip = banned_mob.lastKnownIP
- else if(bankey)
- ckey = ckey(bankey)
- computerid = bancid
- ip = banip
-
- var/had_banned_mob = banned_mob != null
- var/client/banned_client = banned_mob?.client
- var/banned_mob_guest_key = had_banned_mob && IsGuestKey(banned_mob.key)
- banned_mob = null
- var/sql_ckey = sanitizeSQL(ckey)
- var/datum/DBQuery/query_add_ban_get_ckey = SSdbcore.NewQuery("SELECT 1 FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'")
- if(!query_add_ban_get_ckey.warn_execute())
- qdel(query_add_ban_get_ckey)
- return
- var/seen_before = query_add_ban_get_ckey.NextRow()
- qdel(query_add_ban_get_ckey)
- if(!seen_before)
- if(!had_banned_mob || (had_banned_mob && !banned_mob_guest_key))
- if(alert(usr, "[bankey] has not been seen before, are you sure you want to create a ban for them?", "Unknown ckey", "Yes", "No", "Cancel") != "Yes")
- return
-
- var/a_key
- var/a_ckey
- var/a_computerid
- var/a_ip
-
- if(istype(owner))
- a_key = owner.key
- a_ckey = owner.ckey
- a_computerid = owner.computer_id
- a_ip = owner.address
-
- if(blockselfban)
- if(a_ckey == ckey)
- to_chat(usr, "You cannot apply this ban type on yourself. ")
- return
-
- var/who
- for(var/client/C in GLOB.clients)
- if(!who)
- who = "[C]"
- else
- who += ", [C]"
-
- var/adminwho
- for(var/client/C in GLOB.admins)
- if(!adminwho)
- adminwho = "[C]"
- else
- adminwho += ", [C]"
-
- reason = sanitizeSQL(reason)
- var/sql_a_ckey = sanitizeSQL(a_ckey)
- if(maxadminbancheck)
- var/datum/DBQuery/query_check_adminban_amt = SSdbcore.NewQuery("SELECT count(id) AS num FROM [format_table_name("ban")] WHERE (a_ckey = '[sql_a_ckey]') AND (bantype = 'ADMIN_PERMABAN' OR (bantype = 'ADMIN_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
- if(!query_check_adminban_amt.warn_execute())
- qdel(query_check_adminban_amt)
- return
- if(query_check_adminban_amt.NextRow())
- var/adm_bans = text2num(query_check_adminban_amt.item[1])
- var/max_bans = MAX_ADMIN_BANS_PER_ADMIN
- if (check_rights(R_PERMISSIONS, FALSE))
- max_bans = MAX_ADMIN_BANS_PER_HEADMIN
- if(adm_bans >= max_bans)
- to_chat(usr, "You already logged [max_bans] admin ban(s) or more. Do not abuse this function! ")
- qdel(query_check_adminban_amt)
- return
- qdel(query_check_adminban_amt)
- if(!computerid)
- computerid = "0"
- if(!ip)
- ip = "0.0.0.0"
- var/sql_job = sanitizeSQL(job)
- var/sql_computerid = sanitizeSQL(computerid)
- var/sql_ip = sanitizeSQL(ip)
- var/sql_a_computerid = sanitizeSQL(a_computerid)
- var/sql_a_ip = sanitizeSQL(a_ip)
- var/sql = "INSERT INTO [format_table_name("ban")] (`bantime`,`server_ip`,`server_port`,`round_id`,`bantype`,`reason`,`job`,`duration`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`) VALUES (Now(), INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]', '[bantype_str]', '[reason]', '[sql_job]', [(duration)?"[duration]":"0"], Now() + INTERVAL [(duration>0) ? duration : 0] MINUTE, '[sql_ckey]', '[sql_computerid]', INET_ATON('[sql_ip]'), '[sql_a_ckey]', '[sql_a_computerid]', INET_ATON('[sql_a_ip]'), '[who]', '[adminwho]')"
- var/datum/DBQuery/query_add_ban = SSdbcore.NewQuery(sql)
- if(!query_add_ban.warn_execute())
- qdel(query_add_ban)
- return
- qdel(query_add_ban)
- to_chat(usr, "Ban saved to database. ")
- var/msg = "[key_name_admin(usr)] has added a [bantype_str] for [bankey] [(job)?"([job])":""] [(duration > 0)?"([DisplayTimeText(duration MINUTES)])":""] with the reason: \"[reason]\" to the ban database."
- message_admins(msg,1)
- var/datum/admin_help/AH = admin_ticket_log(ckey, msg)
-
- if(announceinirc)
- send2irc("BAN ALERT","[a_key] applied a [bantype_str] on [bankey]")
-
- if(kickbannedckey)
- if(AH)
- AH.Resolve() //with prejudice
- if(banned_client && banned_client.ckey == ckey)
- qdel(banned_client)
- return 1
-
-/datum/admins/proc/DB_ban_unban(ckey, bantype, job = "")
-
- if(!check_rights(R_BAN))
- return
-
- var/bantype_str
- if(bantype)
- var/bantype_pass = 0
- switch(bantype)
- if(BANTYPE_PERMA)
- bantype_str = "PERMABAN"
- bantype_pass = 1
- if(BANTYPE_TEMP)
- bantype_str = "TEMPBAN"
- bantype_pass = 1
- if(BANTYPE_JOB_PERMA)
- bantype_str = "JOB_PERMABAN"
- bantype_pass = 1
- if(BANTYPE_JOB_TEMP)
- bantype_str = "JOB_TEMPBAN"
- bantype_pass = 1
- if(BANTYPE_ADMIN_PERMA)
- bantype_str = "ADMIN_PERMABAN"
- bantype_pass = 1
- if(BANTYPE_ADMIN_TEMP)
- bantype_str = "ADMIN_TEMPBAN"
- bantype_pass = 1
- if(BANTYPE_ANY_FULLBAN)
- bantype_str = "ANY"
- bantype_pass = 1
- if(BANTYPE_ANY_JOB)
- bantype_str = "ANYJOB"
- bantype_pass = 1
- if( !bantype_pass )
- return
-
- var/bantype_sql
- if(bantype_str == "ANY")
- bantype_sql = "(bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now() ) )"
- else if(bantype_str == "ANYJOB")
- bantype_sql = "(bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now() ) )"
- else
- bantype_sql = "bantype = '[bantype_str]'"
- var/sql_ckey = sanitizeSQL(ckey)
- var/sql = "SELECT id FROM [format_table_name("ban")] WHERE ckey = '[sql_ckey]' AND [bantype_sql] AND (unbanned is null OR unbanned = false)"
- if(job)
- var/sql_job = sanitizeSQL(job)
- sql += " AND job = '[sql_job]'"
-
- if(!SSdbcore.Connect())
- return
-
- var/ban_id
- var/ban_number = 0 //failsafe
-
- var/datum/DBQuery/query_unban_get_id = SSdbcore.NewQuery(sql)
- if(!query_unban_get_id.warn_execute())
- qdel(query_unban_get_id)
- return
- while(query_unban_get_id.NextRow())
- ban_id = query_unban_get_id.item[1]
- ban_number++;
- qdel(query_unban_get_id)
-
- if(ban_number == 0)
- to_chat(usr, "Database update failed due to no bans fitting the search criteria. If this is not a legacy ban you should contact the database admin. ")
- return
-
- if(ban_number > 1)
- to_chat(usr, "Database update failed due to multiple bans fitting the search criteria. Note down the ckey, job and current time and contact the database admin. ")
- return
-
- if(istext(ban_id))
- ban_id = text2num(ban_id)
- if(!isnum(ban_id))
- to_chat(usr, "Database update failed due to a ban ID mismatch. Contact the database admin. ")
- return
-
- DB_ban_unban_by_id(ban_id)
-
-/datum/admins/proc/DB_ban_edit(banid = null, param = null)
-
- if(!check_rights(R_BAN))
- return
-
- if(!isnum(banid) || !istext(param))
- to_chat(usr, "Cancelled")
- return
-
- var/datum/DBQuery/query_edit_ban_get_details = SSdbcore.NewQuery("SELECT IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey), duration, reason FROM [format_table_name("ban")] WHERE id = [banid]")
- if(!query_edit_ban_get_details.warn_execute())
- qdel(query_edit_ban_get_details)
- return
-
- var/e_key = usr.key //Editing admin key
- var/p_key //(banned) Player key
- var/duration //Old duration
- var/reason //Old reason
-
- if(query_edit_ban_get_details.NextRow())
- p_key = query_edit_ban_get_details.item[1]
- duration = query_edit_ban_get_details.item[2]
- reason = query_edit_ban_get_details.item[3]
- else
- to_chat(usr, "Invalid ban id. Contact the database admin")
- qdel(query_edit_ban_get_details)
- return
- qdel(query_edit_ban_get_details)
-
- reason = sanitizeSQL(reason)
- var/value
-
- switch(param)
- if("reason")
- if(!value)
- value = input("Insert the new reason for [p_key]'s ban", "New Reason", "[reason]", null) as null|text
- value = sanitizeSQL(value)
- if(!value)
- to_chat(usr, "Cancelled")
- return
-
- var/datum/DBQuery/query_edit_ban_reason = SSdbcore.NewQuery("UPDATE [format_table_name("ban")] SET reason = '[value]', edits = CONCAT(edits,'- [e_key] changed ban reason from \\\"[reason]\\\" to \\\"[value]\\\" ') WHERE id = [banid]")
- if(!query_edit_ban_reason.warn_execute())
- qdel(query_edit_ban_reason)
- return
- qdel(query_edit_ban_reason)
- message_admins("[key_name_admin(usr)] has edited a ban for [p_key]'s reason from [reason] to [value]")
- if("duration")
- if(!value)
- value = input("Insert the new duration (in minutes) for [p_key]'s ban", "New Duration", "[duration]", null) as null|num
- if(!isnum(value) || !value)
- to_chat(usr, "Cancelled")
- return
-
- var/datum/DBQuery/query_edit_ban_duration = SSdbcore.NewQuery("UPDATE [format_table_name("ban")] SET duration = [value], edits = CONCAT(edits,'- [e_key] changed ban duration from [duration] to [value] '), expiration_time = DATE_ADD(bantime, INTERVAL [value] MINUTE) WHERE id = [banid]")
- if(!query_edit_ban_duration.warn_execute())
- qdel(query_edit_ban_duration)
- return
- qdel(query_edit_ban_duration)
- message_admins("[key_name_admin(usr)] has edited a ban for [p_key]'s duration from [DisplayTimeText(duration MINUTES)] to [DisplayTimeText(value MINUTES)]")
- if("unban")
- if(alert("Unban [p_key]?", "Unban?", "Yes", "No") == "Yes")
- DB_ban_unban_by_id(banid)
- return
- else
- to_chat(usr, "Cancelled")
- return
- else
- to_chat(usr, "Cancelled")
- return
-
-/datum/admins/proc/DB_ban_unban_by_id(id)
-
- if(!check_rights(R_BAN))
- return
-
- var/sql = "SELECT IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey) FROM [format_table_name("ban")] WHERE id = [id]"
-
- if(!SSdbcore.Connect())
- return
-
- var/ban_number = 0 //failsafe
-
- var/p_key
- var/datum/DBQuery/query_unban_get_ckey = SSdbcore.NewQuery(sql)
- if(!query_unban_get_ckey.warn_execute())
- qdel(query_unban_get_ckey)
- return
- while(query_unban_get_ckey.NextRow())
- p_key = query_unban_get_ckey.item[1]
- ban_number++;
- qdel(query_unban_get_ckey)
-
- if(ban_number == 0)
- to_chat(usr, "Database update failed due to a ban id not being present in the database. ")
- return
-
- if(ban_number > 1)
- to_chat(usr, "Database update failed due to multiple bans having the same ID. Contact the database admin. ")
- return
-
- if(!istype(owner))
- return
-
- var/unban_ckey = owner.ckey
- var/unban_computerid = owner.computer_id
- var/unban_ip = owner.address
-
- var/sql_update = "UPDATE [format_table_name("ban")] SET unbanned = 1, unbanned_datetime = Now(), unbanned_ckey = '[unban_ckey]', unbanned_computerid = '[unban_computerid]', unbanned_ip = INET_ATON('[unban_ip]') WHERE id = [id]"
- var/datum/DBQuery/query_unban = SSdbcore.NewQuery(sql_update)
- if(!query_unban.warn_execute())
- qdel(query_unban)
- return
- qdel(query_unban)
- message_admins("[key_name_admin(usr)] has lifted [p_key]'s ban.")
-
-/client/proc/DB_ban_panel()
- set category = "Admin"
- set name = "Banning Panel"
- set desc = "Edit admin permissions"
-
- if(!holder)
- return
-
- holder.DB_ban_panel()
-
-
-/datum/admins/proc/DB_ban_panel(playerckey, adminckey, ip, cid, page = 0)
- if(!usr.client)
- return
-
- if(!check_rights(R_BAN))
- return
-
- if(!SSdbcore.Connect())
- to_chat(usr, "Failed to establish database connection. ")
- return
-
- var/output = "
"
-
- output += ""
- output += "Banning panel "
- output += " "
-
- output += ""
-
- output += ""
-
- output += " "
- output += " "
- output += "
"
-
- output += "
Search: "
- output += " "
- output += HrefTokenFormField()
- output += "Ckey: "
- output += "Admin ckey: "
- output += "IP: "
- output += "CID: "
- output += " "
- output += ""
- output += "Please note that all jobban bans or unbans are in-effect the following round."
-
- if(adminckey || playerckey || ip || cid)
- var/list/searchlist = list()
- if(playerckey)
- searchlist += "ckey = '[sanitizeSQL(ckey(playerckey))]'"
- if(adminckey)
- searchlist += "a_ckey = '[sanitizeSQL(ckey(adminckey))]'"
- if(ip)
- searchlist += "ip = INET_ATON('[sanitizeSQL(ip)]')"
- if(cid)
- searchlist += "computerid = '[sanitizeSQL(cid)]'"
- var/search = searchlist.Join(" AND ")
- var/bancount = 0
- var/bansperpage = 15
- var/pagecount = 0
- page = text2num(page)
- var/datum/DBQuery/query_count_bans = SSdbcore.NewQuery("SELECT COUNT(id) FROM [format_table_name("ban")] WHERE [search]")
- if(!query_count_bans.warn_execute())
- qdel(query_count_bans)
- return
- if(query_count_bans.NextRow())
- bancount = text2num(query_count_bans.item[1])
- qdel(query_count_bans)
- if(bancount > bansperpage)
- output += "
Page: "
- while(bancount > 0)
- output+= "|
[pagecount == page ? "\[[pagecount]\] " : "\[[pagecount]\]"] "
- bancount -= bansperpage
- pagecount++
- output += "|"
- var/blcolor = "#ffeeee" //banned light
- var/bdcolor = "#ffdddd" //banned dark
- var/ulcolor = "#eeffee" //unbanned light
- var/udcolor = "#ddffdd" //unbanned dark
-
- output += "
"
- output += ""
- output += "TYPE "
- output += "CKEY "
- output += "TIME APPLIED "
- output += "ADMIN "
- output += "OPTIONS "
- output += " "
- var/limit = " LIMIT [bansperpage * page], [bansperpage]"
- var/datum/DBQuery/query_search_bans = SSdbcore.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), a_ckey), unbanned, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].unbanned_ckey), unbanned_ckey), unbanned_datetime, edits, round_id FROM [format_table_name("ban")] WHERE [search] ORDER BY bantime DESC[limit]")
- if(!query_search_bans.warn_execute())
- qdel(query_search_bans)
- return
-
- while(query_search_bans.NextRow())
- var/banid = query_search_bans.item[1]
- var/bantime = query_search_bans.item[2]
- var/bantype = query_search_bans.item[3]
- var/reason = query_search_bans.item[4]
- var/job = query_search_bans.item[5]
- var/duration = text2num(query_search_bans.item[6])
- var/expiration = query_search_bans.item[7]
- var/ban_key = query_search_bans.item[8]
- var/a_key = query_search_bans.item[9]
- var/unbanned = query_search_bans.item[10]
- var/unban_key = query_search_bans.item[11]
- var/unbantime = query_search_bans.item[12]
- var/edits = query_search_bans.item[13]
- var/round_id = query_search_bans.item[14]
-
- var/lcolor = blcolor
- var/dcolor = bdcolor
- if(unbanned)
- lcolor = ulcolor
- dcolor = udcolor
-
- var/typedesc =""
- switch(bantype)
- if("PERMABAN")
- typedesc = "PERMABAN "
- if("TEMPBAN")
- typedesc = "TEMPBAN ([DisplayTimeText(duration MINUTES)] [(unbanned) ? "" : "(Edit ))"] Expires [expiration] "
- if("JOB_PERMABAN")
- typedesc = "JOBBAN ([job])"
- if("JOB_TEMPBAN")
- typedesc = "TEMP JOBBAN ([job]) ([DisplayTimeText(duration MINUTES)] [(unbanned) ? "" : "(Edit ))"] Expires [expiration]"
- if("ADMIN_PERMABAN")
- typedesc = "ADMIN PERMABAN "
- if("ADMIN_TEMPBAN")
- typedesc = "ADMIN TEMPBAN ([DisplayTimeText(duration MINUTES)] [(unbanned) ? "" : "(Edit ))"] Expires [expiration] "
-
- output += ""
- output += "[typedesc] "
- output += "[ban_key] "
- output += "[bantime] (Round ID: [round_id]) "
- output += "[a_key] "
- output += "[(unbanned) ? "" : "Unban "] "
- output += " "
- output += ""
- output += "Reason: [(unbanned) ? "" : "(Edit )"] \"[reason]\" "
- output += " "
- if(edits)
- output += ""
- output += "EDITS "
- output += " "
- output += ""
- output += "[edits] "
- output += " "
- if(unbanned)
- output += ""
- output += "UNBANNED by admin [unban_key] on [unbantime] "
- output += " "
- output += ""
- output += "  "
- output += " "
- qdel(query_search_bans)
- output += "
"
-
- usr << browse(output,"window=lookupbans;size=900x500")
diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm
index 8fd9e815b79..9840bf72fc9 100644
--- a/code/modules/admin/IsBanned.dm
+++ b/code/modules/admin/IsBanned.dm
@@ -46,79 +46,34 @@
if(!real_bans_only && extreme_popcap && living_player_count() >= extreme_popcap && !admin)
log_access("Failed Login: [key] - Population cap reached")
return list("reason"="popcap", "desc"= "\nReason: [CONFIG_GET(string/extreme_popcap_message)]")
-
- if(CONFIG_GET(flag/ban_legacy_system))
-
- //Ban Checking
- . = CheckBan(ckey, computer_id, address )
- if(.)
- if (admin)
- log_admin("The admin [key] has been allowed to bypass a matching ban on [.["key"]]")
- message_admins("The admin [key] has been allowed to bypass a matching ban on [.["key"]] ")
- addclientmessage(ckey,"You have been allowed to bypass a matching ban on [.["key"]] ")
- else
- log_access("Failed Login: [key] [computer_id] [address] - Banned [.["reason"]]")
- return .
-
- else
+ if(CONFIG_GET(flag/sql_enabled))
if(!SSdbcore.Connect())
var/msg = "Ban database connection failure. Key [ckey] not checked"
log_world(msg)
message_admins(msg)
- return
-
- var/ipquery = ""
- var/cidquery = ""
- if(address)
- ipquery = " OR ip = INET_ATON('[address]') "
-
- if(computer_id)
- cidquery = " OR computerid = '[computer_id]' "
-
- var/datum/DBQuery/query_ban_check = SSdbcore.NewQuery("SELECT IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), a_ckey), reason, expiration_time, duration, bantime, bantype, id, round_id FROM [format_table_name("ban")] WHERE (ckey = '[ckey]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR bantype = 'ADMIN_PERMABAN' OR ((bantype = 'TEMPBAN' OR bantype = 'ADMIN_TEMPBAN') AND expiration_time > Now())) AND isnull(unbanned)")
- if(!query_ban_check.Execute(async = TRUE))
- qdel(query_ban_check)
- return
- while(query_ban_check.NextRow())
- var/pkey = query_ban_check.item[1]
- var/akey = query_ban_check.item[2]
- var/reason = query_ban_check.item[3]
- var/expiration = query_ban_check.item[4]
- var/duration = text2num(query_ban_check.item[5])
- var/bantime = query_ban_check.item[6]
- var/bantype = query_ban_check.item[7]
- var/banid = query_ban_check.item[8]
- var/ban_round_id = query_ban_check.item[9]
- if (bantype == "ADMIN_PERMABAN" || bantype == "ADMIN_TEMPBAN")
- //admin bans MUST match on ckey to prevent cid-spoofing attacks
- // as well as dynamic ip abuse
- if (ckey(pkey) != ckey)
- continue
- if (admin)
- if (bantype == "ADMIN_PERMABAN" || bantype == "ADMIN_TEMPBAN")
- log_admin("The admin [key] is admin banned (#[banid]), and has been disallowed access")
- message_admins("The admin [key] is admin banned (#[banid]), and has been disallowed access ")
- else
- log_admin("The admin [key] has been allowed to bypass a matching ban on [pkey] (#[banid])")
- message_admins("The admin [key] has been allowed to bypass a matching ban on [pkey] (#[banid]) ")
- addclientmessage(ckey,"You have been allowed to bypass a matching ban on [pkey] (#[banid]) ")
- continue
- var/expires = ""
- if(duration > 0)
- expires = "\nThe ban is for [DisplayTimeText(duration MINUTES)] and expires on [expiration] (server time)." //convert from minutes into deciseconds to display the amount of time in days, hours, minutes, ect.
- else
- expires = "\nThis is a permanent ban."
-
- var/desc = "\nReason: You, or another user of this computer or connection ([pkey]) is banned from playing here. The ban reason is:\n[reason]\nThis ban (BanID #[banid]) was applied by [akey] on [bantime] during round ID [ban_round_id]. [expires]"
-
- . = list("reason"="[bantype]", "desc"="[desc]")
-
-
- log_access("Failed Login: [key] [computer_id] [address] - Banned (#[banid]) [.["reason"]]")
- qdel(query_ban_check)
- return .
- qdel(query_ban_check)
-
+ else
+ var/list/ban_details = is_banned_from_with_details(ckey, address, computer_id, "Server")
+ for(var/i in ban_details)
+ if(admin)
+ if(text2num(i["applies_to_admins"]))
+ var/msg = "Admin [key] is admin banned, and has been disallowed access."
+ log_admin(msg)
+ message_admins(msg)
+ else
+ var/msg = "Admin [key] has been allowed to bypass a matching non-admin ban on [i["key"]] [i["ip"]]-[i["computerid"]]."
+ log_admin(msg)
+ message_admins(msg)
+ addclientmessage(ckey,"Admin [key] has been allowed to bypass a matching non-admin ban on [i["key"]] [i["ip"]]-[i["computerid"]]. ")
+ continue
+ var/expires = "This is a permanent ban."
+ if(i["expiration_time"])
+ expires = " The ban is for [DisplayTimeText(text2num(i["duration"]) MINUTES)] and expires on [i["expiration_time"]] (server time)."
+ var/desc = {"You, or another user of this computer or connection ([i["key"]]) is banned from playing here.
+ The ban reason is: [i["reason"]]
+ This ban (BanID #[i["id"]]) was applied by [i["admin_key"]] on [i["bantime"]] during round ID [i["round_id"]].
+ [expires]"}
+ log_access("Failed Login: [key] [computer_id] [address] - Banned (#[i["id"]])")
+ return list("reason"="Banned","desc"="[desc]")
var/list/ban = ..() //default pager ban stuff
if (ban)
var/bannedckey = "ERROR"
diff --git a/code/modules/admin/NewBan.dm b/code/modules/admin/NewBan.dm
deleted file mode 100644
index 94e52ef3c9b..00000000000
--- a/code/modules/admin/NewBan.dm
+++ /dev/null
@@ -1,235 +0,0 @@
-GLOBAL_VAR(CMinutes)
-GLOBAL_DATUM(Banlist, /savefile)
-GLOBAL_PROTECT(Banlist)
-
-
-/proc/CheckBan(ckey, id, address)
- if(!GLOB.Banlist) // if Banlist cannot be located for some reason
- LoadBans() // try to load the bans
- if(!GLOB.Banlist) // uh oh, can't find bans!
- return 0 // ABORT ABORT ABORT
-
- . = list()
- var/appeal
- var/bran = CONFIG_GET(string/banappeals)
- if(bran)
- appeal = "\nFor more information on your ban, or to appeal, head to [bran] "
- GLOB.Banlist.cd = "/base"
- if( "[ckey][id]" in GLOB.Banlist.dir )
- GLOB.Banlist.cd = "[ckey][id]"
- if (GLOB.Banlist["temp"])
- if (!GetExp(GLOB.Banlist["minutes"]))
- ClearTempbans()
- return 0
- else
- .["desc"] = "\nReason: [GLOB.Banlist["reason"]]\nExpires: [GetExp(GLOB.Banlist["minutes"])]\nBy: [GLOB.Banlist["bannedby"]] during round ID [GLOB.Banlist["roundid"]][appeal]"
- else
- GLOB.Banlist.cd = "/base/[ckey][id]"
- .["desc"] = "\nReason: [GLOB.Banlist["reason"]]\nExpires: PERMANENT \nBy: [GLOB.Banlist["bannedby"]] during round ID [GLOB.Banlist["roundid"]][appeal]"
- .["reason"] = "ckey/id"
- return .
- else
- for (var/A in GLOB.Banlist.dir)
- GLOB.Banlist.cd = "/base/[A]"
- var/matches
- if( ckey == GLOB.Banlist["key"] )
- matches += "ckey"
- if( id == GLOB.Banlist["id"] )
- if(matches)
- matches += "/"
- matches += "id"
- if( address == GLOB.Banlist["ip"] )
- if(matches)
- matches += "/"
- matches += "ip"
-
- if(matches)
- if(GLOB.Banlist["temp"])
- if (!GetExp(GLOB.Banlist["minutes"]))
- ClearTempbans()
- return 0
- else
- .["desc"] = "\nReason: [GLOB.Banlist["reason"]]\nExpires: [GetExp(GLOB.Banlist["minutes"])]\nBy: [GLOB.Banlist["bannedby"]] during round ID [GLOB.Banlist["roundid"]][appeal]"
- else
- .["desc"] = "\nReason: [GLOB.Banlist["reason"]]\nExpires: PERMENANT \nBy: [GLOB.Banlist["bannedby"]] during round ID [GLOB.Banlist["roundid"]][appeal]"
- .["reason"] = matches
- return .
- return 0
-
-/proc/UpdateTime() //No idea why i made this a proc.
- GLOB.CMinutes = (world.realtime / 10) / 60
- return 1
-
-/proc/LoadBans()
- if(!CONFIG_GET(flag/ban_legacy_system))
- return
-
- GLOB.Banlist = new("data/banlist.bdb")
- log_admin("Loading Banlist")
-
- if (!length(GLOB.Banlist.dir))
- log_admin("Banlist is empty.")
-
- if (!GLOB.Banlist.dir.Find("base"))
- log_admin("Banlist missing base dir.")
- GLOB.Banlist.dir.Add("base")
- GLOB.Banlist.cd = "/base"
- else if (GLOB.Banlist.dir.Find("base"))
- GLOB.Banlist.cd = "/base"
-
- ClearTempbans()
- return 1
-
-/proc/ClearTempbans()
- UpdateTime()
-
- GLOB.Banlist.cd = "/base"
- for (var/A in GLOB.Banlist.dir)
- GLOB.Banlist.cd = "/base/[A]"
- if (!GLOB.Banlist["key"] || !GLOB.Banlist["id"])
- RemoveBan(A)
- log_admin("Invalid Ban.")
- message_admins("Invalid Ban.")
- continue
-
- if (!GLOB.Banlist["temp"])
- continue
- if (GLOB.CMinutes >= GLOB.Banlist["minutes"])
- RemoveBan(A)
-
- return 1
-
-
-/proc/AddBan(key, computerid, reason, bannedby, temp, minutes, address)
- if(!CONFIG_GET(flag/ban_legacy_system))
- return
- var/bantimestamp
- var/ban_ckey = ckey(key)
- if (temp)
- UpdateTime()
- bantimestamp = GLOB.CMinutes + minutes
-
- GLOB.Banlist.cd = "/base"
- if ( GLOB.Banlist.dir.Find("[ban_ckey][computerid]") )
- to_chat(usr, text("Ban already exists. "))
- return 0
- else
- GLOB.Banlist.dir.Add("[ban_ckey][computerid]")
- GLOB.Banlist.cd = "/base/[ban_ckey][computerid]"
- WRITE_FILE(GLOB.Banlist["key"], ban_ckey)
- WRITE_FILE(GLOB.Banlist["id"], computerid)
- WRITE_FILE(GLOB.Banlist["ip"], address)
- WRITE_FILE(GLOB.Banlist["reason"], reason)
- WRITE_FILE(GLOB.Banlist["bannedby"], bannedby)
- WRITE_FILE(GLOB.Banlist["temp"], temp)
- WRITE_FILE(GLOB.Banlist["roundid"], GLOB.round_id)
- if (temp)
- WRITE_FILE(GLOB.Banlist["minutes"], bantimestamp)
- return 1
-
-/proc/RemoveBan(foldername)
- var/key
- var/id
-
- GLOB.Banlist.cd = "/base/[foldername]"
- GLOB.Banlist["key"] >> key
- GLOB.Banlist["id"] >> id
- GLOB.Banlist.cd = "/base"
-
- if (!GLOB.Banlist.dir.Remove(foldername))
- return 0
-
- if(!usr)
- log_admin_private("Ban Expired: [key]")
- message_admins("Ban Expired: [key]")
- else
- ban_unban_log_save("[key_name(usr)] unbanned [key]")
- log_admin_private("[key_name(usr)] unbanned [key]")
- message_admins("[key_name_admin(usr)] unbanned: [key]")
- usr.client.holder.DB_ban_unban( ckey(key), BANTYPE_ANY_FULLBAN)
- for (var/A in GLOB.Banlist.dir)
- GLOB.Banlist.cd = "/base/[A]"
- if (key == GLOB.Banlist["key"] /*|| id == Banlist["id"]*/)
- GLOB.Banlist.cd = "/base"
- GLOB.Banlist.dir.Remove(A)
- continue
-
- return 1
-
-/proc/GetExp(minutes as num)
- UpdateTime()
- var/exp = minutes - GLOB.CMinutes
- if (exp <= 0)
- return 0
- else
- var/timeleftstring
- if (exp >= 1440) //1440 = 1 day in minutes
- timeleftstring = "[round(exp / 1440, 0.1)] Days"
- else if (exp >= 60) //60 = 1 hour in minutes
- timeleftstring = "[round(exp / 60, 0.1)] Hours"
- else
- timeleftstring = "[exp] Minutes"
- return timeleftstring
-
-/datum/admins/proc/unbanpanel()
- var/count = 0
- var/dat
- GLOB.Banlist.cd = "/base"
- for (var/A in GLOB.Banlist.dir)
- count++
- GLOB.Banlist.cd = "/base/[A]"
- var/ref = "[REF(src)]"
- var/key = GLOB.Banlist["key"]
- var/id = GLOB.Banlist["id"]
- var/ip = GLOB.Banlist["ip"]
- var/reason = GLOB.Banlist["reason"]
- var/by = GLOB.Banlist["bannedby"]
- var/expiry
- if(GLOB.Banlist["temp"])
- expiry = GetExp(GLOB.Banlist["minutes"])
- if(!expiry)
- expiry = "Removal Pending"
- else
- expiry = "Permaban"
-
- dat += text("(U) (E) Key: [key] ComputerID: [id] IP: [ip] [expiry] (By: [by]) (Reason: [reason]) ")
-
- dat += ""
- dat = "Bans: (U) = Unban , (E) = Edit Ban - ([count] Bans) [dat]"
- usr << browse(dat, "window=unbanp;size=875x400")
-
-//////////////////////////////////// DEBUG ////////////////////////////////////
-
-/proc/CreateBans()
-
- UpdateTime()
-
- var/i
- var/last
-
- for(i=0, i<1001, i++)
- var/a = pick(1,0)
- var/b = pick(1,0)
- if(b)
- GLOB.Banlist.cd = "/base"
- GLOB.Banlist.dir.Add("trash[i]trashid[i]")
- GLOB.Banlist.cd = "/base/trash[i]trashid[i]"
- WRITE_FILE(GLOB.Banlist["key"], "trash[i]")
- else
- GLOB.Banlist.cd = "/base"
- GLOB.Banlist.dir.Add("[last]trashid[i]")
- GLOB.Banlist.cd = "/base/[last]trashid[i]"
- WRITE_FILE(GLOB.Banlist["key"], last)
- WRITE_FILE(GLOB.Banlist["id"], "trashid[i]")
- WRITE_FILE(GLOB.Banlist["reason"], "Trashban[i].")
- WRITE_FILE(GLOB.Banlist["temp"], a)
- WRITE_FILE(GLOB.Banlist["minutes"], GLOB.CMinutes + rand(1,2000))
- WRITE_FILE(GLOB.Banlist["bannedby"], "trashmin")
- last = "trash[i]"
-
- GLOB.Banlist.cd = "/base"
-
-/proc/ClearAllBans()
- GLOB.Banlist.cd = "/base"
- for (var/A in GLOB.Banlist.dir)
- RemoveBan(A)
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 2bc2ba9b205..7d1d2167a29 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -78,22 +78,7 @@
body += "Mob type = [M.type] "
body += "Kick | "
- body += "Ban | "
- body += "Jobban | "
- body += "Identity Ban | "
- var/rm = REF(M)
- if(jobban_isbanned(M, "OOC"))
- body+= "OOCBan | "
- else
- body+= "OOCBan | "
- if(QDELETED(M) || QDELETED(usr))
- return
- if(jobban_isbanned(M, "emote"))
- body+= "EmoteBan | "
- else
- body+= "Emoteban | "
- if(QDELETED(M) || QDELETED(usr))
- return
+ body += "Ban | "
body += "Notes | Messages | Watchlist | "
if(M.client)
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index ae4a9bd9c5c..3d391767c6c 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -75,7 +75,7 @@ GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin())
/datum/admins/proc/open_borgopanel
)
GLOBAL_PROTECT(admin_verbs_ban)
-GLOBAL_LIST_INIT(admin_verbs_ban, list(/client/proc/unban_panel, /client/proc/DB_ban_panel, /client/proc/stickybanpanel))
+GLOBAL_LIST_INIT(admin_verbs_ban, list(/client/proc/unban_panel, /client/proc/ban_panel, /client/proc/stickybanpanel))
GLOBAL_PROTECT(admin_verbs_sounds)
GLOBAL_LIST_INIT(admin_verbs_sounds, list(/client/proc/play_local_sound, /client/proc/play_sound, /client/proc/set_round_end_sound))
GLOBAL_PROTECT(admin_verbs_fun)
@@ -378,15 +378,21 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
message_admins("[key_name_admin(usr)] checked antagonists.")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Check Antagonists") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-/client/proc/unban_panel()
- set name = "Unban Panel"
+/client/proc/ban_panel()
+ set name = "Banning Panel"
set category = "Admin"
- if(holder)
- if(CONFIG_GET(flag/ban_legacy_system))
- holder.unbanpanel()
- else
- holder.DB_ban_panel()
- SSblackbox.record_feedback("tally", "admin_verb", 1, "Unban Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ if(!check_rights(R_BAN))
+ return
+ holder.ban_panel()
+ SSblackbox.record_feedback("tally", "admin_verb", 1, "Banning Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/unban_panel()
+ set name = "Unbanning Panel"
+ set category = "Admin"
+ if(!check_rights(R_BAN))
+ return
+ holder.unban_panel()
+ SSblackbox.record_feedback("tally", "admin_verb", 1, "Unbanning Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/game_panel()
set name = "Game Panel"
diff --git a/code/modules/admin/banjob.dm b/code/modules/admin/banjob.dm
deleted file mode 100644
index 20a7228fb5c..00000000000
--- a/code/modules/admin/banjob.dm
+++ /dev/null
@@ -1,40 +0,0 @@
-//returns a reason if M is banned from rank, returns FALSE otherwise
-/proc/jobban_isbanned(mob/M, rank)
- if(!M || !istype(M) || !M.ckey)
- return FALSE
-
- if(!M.client) //no cache. fallback to a datum/DBQuery
- var/datum/DBQuery/query_jobban_check_ban = SSdbcore.NewQuery("SELECT reason FROM [format_table_name("ban")] WHERE ckey = '[sanitizeSQL(M.ckey)]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned) AND job = '[sanitizeSQL(rank)]'")
- if(!query_jobban_check_ban.warn_execute())
- qdel(query_jobban_check_ban)
- return
- if(query_jobban_check_ban.NextRow())
- var/reason = query_jobban_check_ban.item[1]
- qdel(query_jobban_check_ban)
- return reason ? reason : TRUE //we don't want to return "" if there is no ban reason, as that would evaluate to false
- qdel(query_jobban_check_ban)
- return FALSE
-
- if(!M.client.jobbancache)
- jobban_buildcache(M.client)
-
- if(rank in M.client.jobbancache)
- var/reason = M.client.jobbancache[rank]
- return (reason) ? reason : TRUE //see above for why we need to do this
- return FALSE
-
-/proc/jobban_buildcache(client/C)
- if(!SSdbcore.Connect())
- return
- if(C && istype(C))
- C.jobbancache = list()
- var/datum/DBQuery/query_jobban_build_cache = SSdbcore.NewQuery("SELECT job, reason FROM [format_table_name("ban")] WHERE ckey = '[sanitizeSQL(C.ckey)]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
- if(!query_jobban_build_cache.warn_execute())
- qdel(query_jobban_build_cache)
- return
- while(query_jobban_build_cache.NextRow())
- C.jobbancache[query_jobban_build_cache.item[1]] = query_jobban_build_cache.item[2]
- qdel(query_jobban_build_cache)
-
-/proc/ban_unban_log_save(var/formatted_log)
- text2file(formatted_log,"data/ban_unban_log.txt")
diff --git a/code/modules/admin/sql_ban_system.dm b/code/modules/admin/sql_ban_system.dm
new file mode 100644
index 00000000000..179bfddfccb
--- /dev/null
+++ b/code/modules/admin/sql_ban_system.dm
@@ -0,0 +1,713 @@
+#define MAX_ADMINBANS_PER_ADMIN 1
+#define MAX_ADMINBANS_PER_HEADMIN 3
+
+//checks client ban cache or DB ban table if ckey is banned from one or more roles
+//doesn't return any details, use only for if statements
+/proc/is_banned_from(player_ckey, roles)
+ if(!player_ckey)
+ return
+ var/client/C = GLOB.directory[player_ckey]
+ if(C)
+ if(!C.ban_cache)
+ build_ban_cache(C)
+ if(islist(roles))
+ for(var/R in roles)
+ if(R in C.ban_cache)
+ return TRUE //they're banned from at least one role, no need to keep checking
+ else if(roles in C.ban_cache)
+ return TRUE
+ else
+ player_ckey = sanitizeSQL(player_ckey)
+ var/admin_where
+ if(GLOB.admin_datums[player_ckey] || GLOB.deadmins[player_ckey])
+ admin_where = " AND applies_to_admins = 1"
+ var/sql_roles
+ if(islist(roles))
+ sql_roles = jointext(roles, "', '")
+ else
+ sql_roles = roles
+ sql_roles = sanitizeSQL(sql_roles)
+ var/datum/DBQuery/query_check_ban = SSdbcore.NewQuery("SELECT 1 FROM [format_table_name("ban")] WHERE ckey = '[player_ckey]' AND role IN ('[sql_roles]') AND unbanned_datetime IS NULL AND (expiration_time IS NULL OR expiration_time > NOW())[admin_where]")
+ if(!query_check_ban.warn_execute())
+ qdel(query_check_ban)
+ return
+ if(query_check_ban.NextRow())
+ qdel(query_check_ban)
+ return TRUE
+ qdel(query_check_ban)
+
+//checks DB ban table if a ckey, ip and/or cid is banned from a specific role
+//returns an associative nested list of each matching row's ban id, bantime, ban round id, expiration time, ban duration, applies to admins, reason, key, ip, cid and banning admin's key in that order
+/proc/is_banned_from_with_details(player_ckey, player_ip, player_cid, role)
+ if(!player_ckey && !player_ip && !player_cid)
+ return
+ role = sanitizeSQL(role)
+ var/list/where_list = list()
+ if(player_ckey)
+ player_ckey = sanitizeSQL(player_ckey)
+ where_list += "ckey = '[player_ckey]'"
+ if(player_ip)
+ player_ip = sanitizeSQL(player_ip)
+ where_list += "ip = INET_ATON('[player_ip]')"
+ if(player_cid)
+ player_cid = sanitizeSQL(player_cid)
+ where_list += "computerid = '[player_cid]'"
+ var/where = "([where_list.Join(" OR ")])"
+ var/datum/DBQuery/query_check_ban = SSdbcore.NewQuery("SELECT id, bantime, round_id, expiration_time, TIMESTAMPDIFF(MINUTE, bantime, expiration_time), applies_to_admins, reason, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey), INET_NTOA(ip), computerid, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), a_ckey) FROM [format_table_name("ban")] WHERE role = '[role]' AND [where] AND unbanned_datetime IS NULL AND (expiration_time IS NULL OR expiration_time > NOW()) ORDER BY bantime DESC")
+ if(!query_check_ban.warn_execute())
+ qdel(query_check_ban)
+ return
+ . = list()
+ while(query_check_ban.NextRow())
+ . += list(list("id" = query_check_ban.item[1], "bantime" = query_check_ban.item[2], "round_id" = query_check_ban.item[3], "expiration_time" = query_check_ban.item[4], "duration" = query_check_ban.item[5], "applies_to_admins" = query_check_ban.item[6], "reason" = query_check_ban.item[7], "key" = query_check_ban.item[8], "ip" = query_check_ban.item[9], "computerid" = query_check_ban.item[10], "admin_key" = query_check_ban.item[11]))
+ qdel(query_check_ban)
+
+/proc/build_ban_cache(client/C)
+ if(!SSdbcore.Connect())
+ return
+ if(C && istype(C))
+ C.ban_cache = list()
+ var/player_key = sanitizeSQL(C.ckey)
+ var/is_admin = FALSE
+ if(GLOB.admin_datums[C.ckey] || GLOB.deadmins[C.ckey])
+ is_admin = TRUE
+ var/datum/DBQuery/query_build_ban_cache = SSdbcore.NewQuery("SELECT role, applies_to_admins FROM [format_table_name("ban")] WHERE ckey = '[player_key]' AND unbanned_datetime IS NULL AND (expiration_time IS NULL OR expiration_time > NOW())")
+ if(!query_build_ban_cache.warn_execute())
+ qdel(query_build_ban_cache)
+ return
+ while(query_build_ban_cache.NextRow())
+ if(is_admin && !text2num(query_build_ban_cache.item[2]))
+ continue
+ C.ban_cache[query_build_ban_cache.item[1]] = TRUE
+ qdel(query_build_ban_cache)
+
+/datum/admins/proc/ban_panel(player_key, player_ip, player_cid, role, duration = 1440, applies_to_admins, reason, edit_id, page, admin_key)
+ var/panel_height = 620
+ if(edit_id)
+ panel_height = 240
+ var/datum/browser/panel = new(usr, "banpanel", "Banning Panel", 910, panel_height)
+ panel.add_stylesheet("banpanelcss", 'html/admin/banpanel.css')
+ panel.add_script("banpaneljs", 'html/admin/banpanel.js')
+ var/list/output = list("[HrefTokenFormField()]")
+ output += {"
+ Key:
+
+
+
+ IP:
+
+
+
+ CID:
+
+
+
+
+ Use IP and CID from last connection of key
+
+
+ Applies to Admins
+
+
+
+
+
+
+ Duration type
+
+
Permanent
+
+
+
+
Temporary
+
+
+
+
+
+ Seconds
+ Minutes
+ Hours
+ Days
+ Weeks
+ Months
+ Years
+
+
+
+
+ Ban type
+
+
Server
+
+
+
+
Role
+
+
+
+
+
+ Reason
+
+ [reason]
+
+
+ "}
+ if(edit_id)
+ output += {"Mirror edits to matching bans
+
+
+
+
+
+
+
+
+
+
+
+
+ When ticked, edits here will also affect bans created with matching ckey, IP, CID and time. Use this to edit all role bans which were made at the same time.
+ "}
+ else
+ output += " "
+ //there's not always a client to use the bancache of so to avoid many individual queries from using is_banned_form we'll build a cache to use here
+ var/banned_from = list()
+ if(player_key)
+ var/player_ckey = sanitizeSQL(ckey(player_key))
+ var/datum/DBQuery/query_get_banned_roles = SSdbcore.NewQuery("SELECT role FROM [format_table_name("ban")] WHERE ckey = '[player_ckey]' AND role <> 'server' AND unbanned_datetime IS NULL AND (expiration_time IS NULL OR expiration_time > NOW())")
+ if(!query_get_banned_roles.warn_execute())
+ qdel(query_get_banned_roles)
+ return
+ while(query_get_banned_roles.NextRow())
+ banned_from += query_get_banned_roles.item[1]
+ qdel(query_get_banned_roles)
+ var/break_counter = 0
+ output += ""
+ //standard deparments all have identical handling
+ var/list/job_lists = list("Security" = GLOB.security_positions,
+ "Engineering" = GLOB.engineering_positions,
+ "Medical" = GLOB.medical_positions,
+ "Science" = GLOB.science_positions,
+ "Supply" = GLOB.supply_positions,
+ "Silicon" = GLOB.nonhuman_positions) //another cheat for simplicity
+ for(var/department in job_lists)
+ //the first element is the department head so they need the same javascript call as above
+ output += "
"
+ var/list/long_job_lists = list("Civilian" = GLOB.civilian_positions,
+ "Ghost and Other Roles" = list("Appearance", ROLE_BRAINWASHED, ROLE_DEATHSQUAD, ROLE_DRONE, "Emote", ROLE_LAVALAND, ROLE_MIND_TRANSFER, "OOC", ROLE_POSIBRAIN, ROLE_SENTIENCE),
+ "Antagonist Positions" = list(ROLE_ABDUCTOR, ROLE_ALIEN, ROLE_BLOB,
+ ROLE_BROTHER, ROLE_CHANGELING, ROLE_CULTIST,
+ ROLE_DEVIL, ROLE_INTERNAL_AFFAIRS, ROLE_MALF,
+ ROLE_MONKEY, ROLE_NINJA, ROLE_OPERATIVE,
+ ROLE_OVERTHROW, ROLE_REV, ROLE_REVENANT,
+ ROLE_REV_HEAD, ROLE_SERVANT_OF_RATVAR, ROLE_SYNDICATE,
+ ROLE_TRAITOR, ROLE_WIZARD)) //ROLE_REV_HEAD is excluded from this because rev jobbans are handled by ROLE_REV
+ for(var/department in long_job_lists)
+ output += "
"
+ output += "
"
+ output += " "
+ panel.set_content(jointext(output, ""))
+ panel.open()
+
+/datum/admins/proc/ban_parse_href(list/href_list)
+ if(!check_rights(R_BAN))
+ return
+ if(!SSdbcore.Connect())
+ to_chat(usr, "Failed to establish database connection. ")
+ return
+ var/list/error_state = list()
+ var/player_key
+ var/player_ip
+ var/player_cid
+ var/use_last_connection = FALSE
+ var/applies_to_admins = FALSE
+ var/duration
+ var/interval
+ var/severity
+ var/reason
+ var/mirror_edit
+ var/edit_id
+ var/old_key
+ var/old_ip
+ var/old_cid
+ var/old_applies
+ var/page
+ var/admin_key
+ var/list/changes = list()
+ var/list/roles_to_ban = list()
+ if(href_list["keycheck"])
+ player_key = href_list["keytext"]
+ if(!player_key)
+ error_state += "Key was ticked but none was provided."
+ if(href_list["lastconn"])
+ use_last_connection = TRUE
+ if(!player_key)
+ error_state += "A key must be provided to use IP and CID from last connection."
+ else
+ if(href_list["ipcheck"])
+ player_ip = href_list["iptext"]
+ if(!player_ip)
+ error_state += "IP was ticked but none was provided."
+ if(href_list["cidcheck"])
+ player_cid = href_list["cidtext"]
+ if(!player_cid)
+ error_state += "CID was ticked but none was provided."
+ if(!use_last_connection && !player_ip && !player_cid && !player_key)
+ error_state += "At least a key, IP or CID must be provided."
+ if(href_list["applyadmins"])
+ applies_to_admins = TRUE
+ switch(href_list["radioduration"])
+ if("permanent")
+ duration = null
+ if("temporary")
+ duration = href_list["duration"]
+ interval = href_list["intervaltype"]
+ if(!duration)
+ error_state += "Temporary ban was selected but no duration was provided."
+ else
+ error_state += "No duration was selected."
+ reason = href_list["reason"]
+ if(!reason)
+ error_state += "No reason was provided."
+ if(href_list["editid"])
+ edit_id = href_list["editid"]
+ if(href_list["mirroredit"])
+ mirror_edit = TRUE
+ old_key = href_list["oldkey"]
+ old_ip = href_list["oldip"]
+ old_cid = href_list["oldcid"]
+ page = href_list["page"]
+ admin_key = href_list["adminkey"]
+ if(player_key != old_key)
+ changes += list("Key" = "[old_key] to [player_key]")
+ if(player_ip != old_ip)
+ changes += list("IP" = "[old_ip] to [player_ip]")
+ if(player_cid != old_cid)
+ changes += list("CID" = "[old_cid] to [player_cid]")
+ old_applies = text2num(href_list["oldapplies"])
+ if(applies_to_admins != old_applies)
+ changes += list("Applies to admins" = "[old_applies] to [applies_to_admins]")
+ if(duration != href_list["oldduration"])
+ changes += list("Duration" = "[href_list["oldduration"]] MINUTE to [duration] [interval]")
+ if(reason != href_list["oldreason"])
+ changes += list("Reason" = "[href_list["oldreason"]] to [reason]")
+ if(!changes.len)
+ error_state += "No changes were detected."
+ else
+ severity = href_list["radioseverity"]
+ if(!severity)
+ error_state += "No severity was selected."
+ switch(href_list["radioban"])
+ if("server")
+ roles_to_ban += "Server"
+ if("role")
+ if(href_list[href_list.len] == "roleban_delimiter")
+ error_state += "Role ban was selected but no roles to ban were selected."
+ else
+ href_list.Remove("Command", "Security", "Engineering", "Medical", "Science", "Supply", "Silicon", "Civilian", "Ghost and Other Roles", "Antagonist Positions") //remove the role banner hidden input values
+ var/delimiter_pos = href_list.Find("roleban_delimiter")
+ href_list.Cut(1, delimiter_pos+1)//remove every list element before and including roleban_delimiter so we have a list of only the roles to ban
+ for(var/key in href_list) //flatten into a list of only unique keys
+ roles_to_ban |= key
+ else
+ error_state += "No ban type was selected."
+ if(error_state.len)
+ to_chat(usr, "Ban not [edit_id ? "edited" : "created"] because the following errors were present:\n[error_state.Join("\n")] ")
+ return
+ if(edit_id)
+ edit_ban(edit_id, player_key, player_ip, player_cid, use_last_connection, applies_to_admins, duration, interval, reason, mirror_edit, old_key, old_ip, old_cid, old_applies, page, admin_key, changes)
+ else
+ create_ban(player_key, player_ip, player_cid, use_last_connection, applies_to_admins, duration, interval, severity, reason, roles_to_ban)
+
+/datum/admins/proc/create_ban(player_key, player_ip, player_cid, use_last_connection, applies_to_admins, duration, interval, severity, reason, list/roles_to_ban)
+ if(!check_rights(R_BAN))
+ return
+ if(!SSdbcore.Connect())
+ to_chat(usr, "Failed to establish database connection. ")
+ return
+ var/player_ckey = sanitizeSQL(ckey(player_key))
+ player_ip = sanitizeSQL(player_ip)
+ player_cid = sanitizeSQL(player_cid)
+ var/datum/DBQuery/query_create_ban_get_player = SSdbcore.NewQuery("SELECT byond_key, INET_NTOA(ip), computerid FROM [format_table_name("player")] WHERE ckey = '[player_ckey]'")
+ if(!query_create_ban_get_player.warn_execute())
+ qdel(query_create_ban_get_player)
+ return
+ if(query_create_ban_get_player.NextRow())
+ player_key = query_create_ban_get_player.item[1]
+ if(use_last_connection)
+ player_ip = query_create_ban_get_player.item[2]
+ player_cid = query_create_ban_get_player.item[3]
+ else
+ if(use_last_connection)
+ to_chat(usr, "Ban not created. [player_key]/([player_ckey]) hasn't been seen before, unable to use IP and CID from last connection. ")
+ qdel(query_create_ban_get_player)
+ return
+ else
+ if(alert(usr, "[player_key]/([player_ckey]) has not been seen before, are you sure you want to create a ban for them?", "Unknown key", "Yes", "No", "Cancel") != "Yes")
+ qdel(query_create_ban_get_player)
+ return
+ qdel(query_create_ban_get_player)
+ var/admin_ckey = sanitizeSQL(usr.client.ckey)
+ if(applies_to_admins)
+ var/datum/DBQuery/query_check_adminban_count = SSdbcore.NewQuery("SELECT COUNT(DISTINCT bantime) FROM [format_table_name("ban")] WHERE a_ckey = '[admin_ckey]' AND applies_to_admins = 1 AND unbanned_datetime IS NULL AND (expiration_time IS NULL OR expiration_time > NOW())")
+ if(!query_check_adminban_count.warn_execute()) //count distinct bantime to treat rolebans made at the same time as one ban
+ qdel(query_check_adminban_count)
+ return
+ if(query_check_adminban_count.NextRow())
+ var/adminban_count = text2num(query_check_adminban_count.item[1])
+ var/max_adminbans = MAX_ADMINBANS_PER_ADMIN
+ if(R_EVERYTHING && !(R_EVERYTHING & rank.can_edit_rights)) //edit rights are a more effective way to check hierarchical rank since many non-headmins have R_PERMISSIONS now
+ max_adminbans = MAX_ADMINBANS_PER_HEADMIN
+ if(adminban_count >= max_adminbans)
+ to_chat(usr, "You've already logged [max_adminbans] admin ban(s) or more. Do not abuse this function! ")
+ qdel(query_check_adminban_count)
+ return
+ qdel(query_check_adminban_count)
+ var/admin_ip = sanitizeSQL(usr.client.address)
+ var/admin_cid = sanitizeSQL(usr.client.computer_id)
+ duration = text2num(duration)
+ if(interval)
+ interval = sanitizeSQL(interval)
+ else
+ interval = "MINUTE"
+ reason = sanitizeSQL(reason)
+ var/list/clients_online = GLOB.clients.Copy()
+ var/list/admins_online = list()
+ for(var/client/C in clients_online)
+ if(C.holder) //deadmins aren't included since they wouldn't show up on adminwho
+ admins_online += C
+ var/who = clients_online.Join(", ")
+ var/adminwho = admins_online.Join(", ")
+ var/kn = key_name(usr)
+ var/kna = key_name_admin(usr)
+ var/sql_ban
+ for(var/role in roles_to_ban)
+ sql_ban += list(list("bantime" = "NOW()",
+ "server_ip" = "INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]'))",
+ "server_port" = sanitizeSQL(world.port),
+ "round_id" = sanitizeSQL(GLOB.round_id),
+ "role" = "'[sanitizeSQL(role)]'",
+ "expiration_time" = "IF('[duration]' LIKE '', NULL, NOW() + INTERVAL [duration ? "[duration]" : "0"] [interval])",
+ "applies_to_admins" = sanitizeSQL(applies_to_admins),
+ "reason" = "'[reason]'",
+ "ckey" = "IF('[player_ckey]' LIKE '', NULL, '[player_ckey]')",
+ "ip" = "INET_ATON(IF('[player_ip]' LIKE '', NULL, '[player_ip]'))",
+ "computerid" = "IF('[player_cid]' LIKE '', NULL, '[player_cid]')",
+ "a_ckey" = "'[admin_ckey]'",
+ "a_ip" = "INET_ATON(IF('[admin_ip]' LIKE '', NULL, '[admin_ip]'))",
+ "a_computerid" = "'[admin_cid]'",
+ "who" = "'[who]'",
+ "adminwho" = "'[adminwho]'"
+ ))
+ if(!SSdbcore.MassInsert(format_table_name("ban"), sql_ban, warn = 1))
+ return
+ var/time_message = "[duration] [lowertext(interval)]" //no DisplayTimeText because our duration is of variable interval type
+ if(duration > 1) //pluralize the interval if necessary
+ time_message += "s"
+ var/msg = "has created a [isnull(duration) ? "permanent" : "temporary [time_message]"] [applies_to_admins ? "admin " : ""][roles_to_ban[1] == "Server" ? "server ban" : "role ban from [roles_to_ban.len] roles"] for [player_key]."
+ log_admin_private("[kn] [msg][roles_to_ban[1] == "Server" ? "" : " Roles: [roles_to_ban.Join(", ")]"]")
+ message_admins("[kna] [msg][roles_to_ban[1] == "Server" ? "" : " Roles: [roles_to_ban.Join("\n")]"]")
+ if(applies_to_admins)
+ send2irc("BAN ALERT","[kn] [msg]")
+ create_message("note", player_ckey, null, reason, null, null, 0, 0, null, 0, severity)
+ var/client/C = GLOB.directory[player_ckey]
+ var/datum/admin_help/AH = admin_ticket_log(player_ckey, msg)
+ var/appeal_url = "No ban appeal url set!"
+ appeal_url = CONFIG_GET(string/banappeals)
+ if(C)
+ build_ban_cache(C)
+ to_chat(C, "You have been [applies_to_admins ? "admin " : ""]banned by [usr.client.key] from [roles_to_ban[1] == "Server" ? "the server" : " Roles: [roles_to_ban.Join(", ")]"].\nReason: [reason] This ban is [isnull(duration) ? "permanent." : "temporary, it will be removed in [time_message]."] The round ID is [GLOB.round_id]. To appeal this ban go to [appeal_url] ")
+ if(roles_to_ban[1] == "Server")
+ if(AH)
+ AH.Resolve()
+ qdel(C)
+ for(var/client/i in GLOB.clients - C)
+ if(i.address == player_ip || i.computer_id == player_cid)
+ build_ban_cache(i)
+ to_chat(i, "You have been [applies_to_admins ? "admin " : ""]banned by [usr.client.key] from [roles_to_ban[1] == "Server" ? "the server" : " Roles: [roles_to_ban.Join(", ")]"].\nReason: [reason] This ban is [isnull(duration) ? "permanent." : "temporary, it will be removed in [time_message]."] The round ID is [GLOB.round_id]. To appeal this ban go to [appeal_url] ")
+ if(roles_to_ban[1] == "Server")
+ qdel(i)
+
+/datum/admins/proc/unban_panel(player_key, admin_key, player_ip, player_cid, page = 0)
+ if(!check_rights(R_BAN))
+ return
+ if(!SSdbcore.Connect())
+ to_chat(usr, "Failed to establish database connection. ")
+ return
+ var/datum/browser/unban_panel = new(usr, "unbanpanel", "Unbanning Panel", 850, 600)
+ unban_panel.add_stylesheet("unbanpanelcss", 'html/admin/unbanpanel.css')
+ var/list/output = list("")
+ output += {"
[HrefTokenFormField()]
+
+ Key:
+ Admin Key:
+ IP:
+ CID:
+
+
+
+
+ "}
+ if(player_key || admin_key || player_ip || player_cid)
+ var/list/searchlist = list()
+ if(player_key)
+ searchlist += "ckey = '[sanitizeSQL(ckey(player_key))]'"
+ if(admin_key)
+ searchlist += "a_ckey = '[sanitizeSQL(ckey(admin_key))]'"
+ if(player_ip)
+ searchlist += "ip = INET_ATON('[sanitizeSQL(player_ip)]')"
+ if(player_cid)
+ searchlist += "computerid = '[sanitizeSQL(player_cid)]'"
+ var/search = searchlist.Join(" AND ")
+ var/bancount = 0
+ var/bansperpage = 10
+ page = text2num(page)
+ var/datum/DBQuery/query_unban_count_bans = SSdbcore.NewQuery("SELECT COUNT(id) FROM [format_table_name("ban")] WHERE [search]")
+ if(!query_unban_count_bans.warn_execute())
+ qdel(query_unban_count_bans)
+ return
+ if(query_unban_count_bans.NextRow())
+ bancount = text2num(query_unban_count_bans.item[1])
+ qdel(query_unban_count_bans)
+ if(bancount > bansperpage)
+ output += "
Page: "
+ var/pagecount = 1
+ var/list/pagelist = list()
+ while(bancount > 0)
+ pagelist += "
[pagecount == page ? "\[[pagecount]\] " : "\[[pagecount]\]"] "
+ bancount -= bansperpage
+ pagecount++
+ output += pagelist.Join(" | ")
+ var/limit = " LIMIT [bansperpage * page], [bansperpage]"
+ var/datum/DBQuery/query_unban_search_bans = SSdbcore.NewQuery({"SELECT id, bantime, round_id, role, expiration_time, TIMESTAMPDIFF(MINUTE, bantime, expiration_time), IF(expiration_time < NOW(), 1, NULL), applies_to_admins, reason, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey), INET_NTOA(ip), computerid, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), a_ckey), IF(edits IS NOT NULL, 1, NULL), unbanned_datetime, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].unbanned_ckey), unbanned_ckey), unbanned_round_id FROM [format_table_name("ban")] WHERE [search] ORDER BY id DESC[limit]"})
+ if(!query_unban_search_bans.warn_execute())
+ qdel(query_unban_search_bans)
+ return
+ while(query_unban_search_bans.NextRow())
+ var/ban_id = query_unban_search_bans.item[1]
+ var/ban_datetime = query_unban_search_bans.item[2]
+ var/ban_round_id = query_unban_search_bans.item[3]
+ var/role = query_unban_search_bans.item[4]
+ //make the href for unban here so only the search parameters are passed
+ var/unban_href = "
Unban "
+ var/expiration_time = query_unban_search_bans.item[5]
+ //we don't cast duration as num because if the duration is large enough to be converted to scientific notation by byond then the + character gets lost when passed through href causing SQL to interpret '4.321e 007' as '4'
+ var/duration = query_unban_search_bans.item[6]
+ var/expired = query_unban_search_bans.item[7]
+ var/applies_to_admins = text2num(query_unban_search_bans.item[8])
+ var/reason = query_unban_search_bans.item[9]
+ player_key = query_unban_search_bans.item[10]
+ player_ip = query_unban_search_bans.item[11]
+ player_cid = query_unban_search_bans.item[12]
+ admin_key = query_unban_search_bans.item[13]
+ var/edits = query_unban_search_bans.item[14]
+ var/unban_datetime = query_unban_search_bans.item[15]
+ var/unban_key = query_unban_search_bans.item[16]
+ var/unban_round_id = query_unban_search_bans.item[17]
+ output += "
[reason]
"
+ if(!expired && !unban_datetime)
+ output += "
Edit [unban_href]"
+ if(edits)
+ output += "
Edit log "
+ output += "
"
+ qdel(query_unban_search_bans)
+ output += "
"
+ unban_panel.set_content(jointext(output, ""))
+ unban_panel.open()
+
+/datum/admins/proc/unban(ban_id, player_key, player_ip, player_cid, role, page, admin_key)
+ if(!check_rights(R_BAN))
+ return
+ if(!SSdbcore.Connect())
+ to_chat(usr, "Failed to establish database connection. ")
+ return
+ if(alert(usr, "Please confirm unban of [player_key] from [role].", "Unban confirmation", "Yes", "No") == "No")
+ return
+ ban_id = sanitizeSQL(ban_id)
+ var/admin_ckey = sanitizeSQL(usr.client.ckey)
+ var/admin_ip = sanitizeSQL(usr.client.address)
+ var/admin_cid = sanitizeSQL(usr.client.computer_id)
+ var/kn = key_name(usr)
+ var/kna = key_name_admin(usr)
+ var/datum/DBQuery/query_unban = SSdbcore.NewQuery("UPDATE [format_table_name("ban")] SET unbanned_datetime = NOW(), unbanned_ckey = '[admin_ckey]', unbanned_ip = INET_ATON('[admin_ip]'), unbanned_computerid = '[admin_cid]', unbanned_round_id = '[GLOB.round_id]' WHERE id = [ban_id]")
+ if(!query_unban.warn_execute())
+ qdel(query_unban)
+ return
+ qdel(query_unban)
+ log_admin_private("[kn] has unbanned [player_key] from [role].")
+ message_admins("[kna] has unbanned [player_key] from [role].")
+ var/client/C = GLOB.directory[player_key]
+ if(C)
+ build_ban_cache(C)
+ to_chat(C, "[usr.client.key] has removed a ban from [role] for your key.")
+ for(var/client/i in GLOB.clients - C)
+ if(i.address == player_ip || i.computer_id == player_cid)
+ build_ban_cache(i)
+ to_chat(i, "[usr.client.key] has removed a ban from [role] for your IP or CID.")
+ unban_panel(player_key, admin_key, player_ip, player_cid, page)
+
+/datum/admins/proc/edit_ban(ban_id, player_key, player_ip, player_cid, use_last_connection, applies_to_admins, duration, interval, reason, mirror_edit, old_key, old_ip, old_cid, old_applies, admin_key, page, list/changes)
+ if(!check_rights(R_BAN))
+ return
+ if(!SSdbcore.Connect())
+ to_chat(usr, "Failed to establish database connection. ")
+ return
+ ban_id = sanitizeSQL(ban_id)
+ var/player_ckey = sanitizeSQL(ckey(player_key))
+ player_ip = sanitizeSQL(player_ip)
+ player_cid = sanitizeSQL(player_cid)
+ var/bantime
+ var/datum/DBQuery/query_edit_ban_get_player = SSdbcore.NewQuery("SELECT byond_key, (SELECT bantime FROM [format_table_name("ban")] WHERE id = [ban_id]), ip, computerid FROM [format_table_name("player")] WHERE ckey = '[player_ckey]'")
+ if(!query_edit_ban_get_player.warn_execute())
+ qdel(query_edit_ban_get_player)
+ return
+ if(query_edit_ban_get_player.NextRow())
+ player_key = query_edit_ban_get_player.item[1]
+ bantime = query_edit_ban_get_player.item[2]
+ if(use_last_connection)
+ player_ip = query_edit_ban_get_player.item[3]
+ player_cid = query_edit_ban_get_player.item[4]
+ else
+ if(use_last_connection)
+ to_chat(usr, "Ban not edited. [player_key]/([player_ckey]) hasn't been seen before, unable to use IP and CID from last connection. ")
+ qdel(query_edit_ban_get_player)
+ return
+ qdel(query_edit_ban_get_player)
+ if(applies_to_admins && (applies_to_admins != old_applies))
+ var/admin_ckey = sanitizeSQL(usr.client.ckey)
+ var/datum/DBQuery/query_check_adminban_count = SSdbcore.NewQuery("SELECT COUNT(DISTINCT bantime) FROM [format_table_name("ban")] WHERE a_ckey = '[admin_ckey]' AND applies_to_admins = 1 AND unbanned_datetime IS NULL AND (expiration_time IS NULL OR expiration_time > NOW())")
+ if(!query_check_adminban_count.warn_execute()) //count distinct bantime to treat rolebans made at the same time as one ban
+ qdel(query_check_adminban_count)
+ return
+ if(query_check_adminban_count.NextRow())
+ var/adminban_count = text2num(query_check_adminban_count.item[1])
+ var/max_adminbans = MAX_ADMINBANS_PER_ADMIN
+ if(R_EVERYTHING && !(R_EVERYTHING & rank.can_edit_rights)) //edit rights are a more effective way to check hierarchical rank since many non-headmins have R_PERMISSIONS now
+ max_adminbans = MAX_ADMINBANS_PER_HEADMIN
+ if(adminban_count >= max_adminbans)
+ to_chat(usr, "You've already logged [max_adminbans] admin ban(s) or more. Do not abuse this function! ")
+ qdel(query_check_adminban_count)
+ return
+ qdel(query_check_adminban_count)
+ applies_to_admins = sanitizeSQL(applies_to_admins)
+ duration = sanitizeSQL(duration)
+ if(interval)
+ interval = sanitizeSQL(interval)
+ else
+ interval = "MINUTE"
+ reason = sanitizeSQL(reason)
+ var/kn = key_name(usr)
+ var/kna = key_name_admin(usr)
+ var/list/changes_text= list()
+ var/list/changes_keys = list()
+ for(var/i in changes)
+ changes_text += "[i]: [changes[i]]"
+ changes_keys += i
+ var/where = "id = [sanitizeSQL(ban_id)]"
+ if(text2num(mirror_edit))
+ var/list/wherelist = list("bantime = '[bantime]'")
+ if(old_key)
+ wherelist += "ckey = '[sanitizeSQL(ckey(old_key))]'"
+ if(old_ip)
+ old_ip = sanitizeSQL(old_ip)
+ wherelist += "ip = INET_ATON(IF('[old_ip]' LIKE '', NULL, '[old_ip]'))"
+ if(old_cid)
+ wherelist += "computerid = '[sanitizeSQL(old_cid)]'"
+ where = wherelist.Join(" AND ")
+ var/datum/DBQuery/query_edit_ban = SSdbcore.NewQuery("UPDATE [format_table_name("ban")] SET expiration_time = IF('[duration]' LIKE '', NULL, bantime + INTERVAL [duration ? "[duration]" : "0"] [interval]), applies_to_admins = [applies_to_admins], reason = '[reason]', ckey = IF('[player_ckey]' LIKE '', NULL, '[player_ckey]'), ip = INET_ATON(IF('[player_ip]' LIKE '', NULL, '[player_ip]')), computerid = IF('[player_cid]' LIKE '', NULL, '[player_cid]'), edits = CONCAT(IFNULL(edits,''),'[sanitizeSQL(usr.client.key)] edited the following [jointext(changes_text, ", ")] ') WHERE [where]")
+ if(!query_edit_ban.warn_execute())
+ qdel(query_edit_ban)
+ return
+ qdel(query_edit_ban)
+ var/changes_keys_text = jointext(changes_keys, ", ")
+ log_admin_private("[kn] has edited the [changes_keys_text] of a ban for [old_key ? "[old_key]" : "[old_ip]-[old_cid]"].") //if a ban doesn't have a key it must have an ip and/or a cid to have reached this point normally
+ message_admins("[kna] has edited the [changes_keys_text] of a ban for [old_key ? "[old_key]" : "[old_ip]-[old_cid]"].")
+ if(changes["Applies to admins"])
+ send2irc("BAN ALERT","[kn] has edited a ban for [old_key ? "[old_key]" : "[old_ip]-[old_cid]"] to [applies_to_admins ? "" : "not"]affect admins")
+ var/client/C = GLOB.directory[old_key]
+ if(C)
+ build_ban_cache(C)
+ to_chat(C, "[usr.client.key] has edited the [changes_keys_text] of a ban for your key.")
+ for(var/client/i in GLOB.clients - C)
+ if(i.address == old_ip || i.computer_id == old_cid)
+ build_ban_cache(i)
+ to_chat(i, "[usr.client.key] has edited the [changes_keys_text] of a ban for your IP or CID.")
+ unban_panel(player_key, null, null, null, page)
+
+/datum/admins/proc/ban_log(ban_id)
+ if(!check_rights(R_BAN))
+ return
+ if(!SSdbcore.Connect())
+ to_chat(usr, "Failed to establish database connection. ")
+ return
+ ban_id = sanitizeSQL(ban_id)
+ var/datum/DBQuery/query_get_ban_edits = SSdbcore.NewQuery("SELECT edits FROM [format_table_name("ban")] WHERE id = '[ban_id]'")
+ if(!query_get_ban_edits.warn_execute())
+ qdel(query_get_ban_edits)
+ return
+ if(query_get_ban_edits.NextRow())
+ var/edits = query_get_ban_edits.item[1]
+ var/datum/browser/edit_log = new(usr, "baneditlog", "Ban edit log")
+ edit_log.set_content(edits)
+ edit_log.open()
+ qdel(query_get_ban_edits)
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 1777476d582..62d3ac29a2c 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -183,94 +183,6 @@
log_admin("[key_name(usr)] has triggered an event. ([E.name])")
return
- else if(href_list["dbsearchckey"] || href_list["dbsearchadmin"] || href_list["dbsearchip"] || href_list["dbsearchcid"])
- var/adminckey = href_list["dbsearchadmin"]
- var/playerckey = href_list["dbsearchckey"]
- var/ip = href_list["dbsearchip"]
- var/cid = href_list["dbsearchcid"]
- var/page = href_list["dbsearchpage"]
-
- DB_ban_panel(playerckey, adminckey, ip, cid, page)
- return
-
- else if(href_list["dbbanedit"])
- var/banedit = href_list["dbbanedit"]
- var/banid = text2num(href_list["dbbanid"])
- if(!banedit || !banid)
- return
-
- DB_ban_edit(banid, banedit)
- return
-
- else if(href_list["dbbanaddtype"])
- if(!check_rights(R_BAN))
- return
- var/bantype = text2num(href_list["dbbanaddtype"])
- var/bankey = href_list["dbbanaddkey"]
- var/banckey = ckey(bankey)
- var/banip = href_list["dbbanaddip"]
- var/bancid = href_list["dbbanaddcid"]
- var/banduration = text2num(href_list["dbbaddduration"])
- var/banjob = href_list["dbbanaddjob"]
- var/banreason = href_list["dbbanreason"]
- var/banseverity = href_list["dbbanaddseverity"]
-
- switch(bantype)
- if(BANTYPE_PERMA)
- if(!banckey || !banreason || !banseverity)
- to_chat(usr, "Not enough parameters (Requires ckey, severity, and reason).")
- return
- banduration = null
- banjob = null
- if(BANTYPE_TEMP)
- if(!banckey || !banreason || !banduration || !banseverity)
- to_chat(usr, "Not enough parameters (Requires ckey, reason, severity and duration).")
- return
- banjob = null
- if(BANTYPE_JOB_PERMA)
- if(!banckey || !banreason || !banjob || !banseverity)
- to_chat(usr, "Not enough parameters (Requires ckey, severity, reason and job).")
- return
- banduration = null
- if(BANTYPE_JOB_TEMP)
- if(!banckey || !banreason || !banjob || !banduration || !banseverity)
- to_chat(usr, "Not enough parameters (Requires ckey, severity, reason and job).")
- return
- if(BANTYPE_ADMIN_PERMA)
- if(!banckey || !banreason || !banseverity)
- to_chat(usr, "Not enough parameters (Requires ckey, severity and reason).")
- return
- banduration = null
- banjob = null
- if(BANTYPE_ADMIN_TEMP)
- if(!banckey || !banreason || !banduration || !banseverity)
- to_chat(usr, "Not enough parameters (Requires ckey, severity, reason and duration).")
- return
- banjob = null
-
- var/mob/playermob
-
- for(var/mob/M in GLOB.player_list)
- if(M.ckey == banckey)
- playermob = M
- break
-
-
- banreason = "(MANUAL BAN) "+banreason
-
- if(!playermob)
- if(banip)
- banreason = "[banreason] (CUSTOM IP)"
- if(bancid)
- banreason = "[banreason] (CUSTOM CID)"
- else
- message_admins("Ban process: A mob matching [playermob.key] was found at location [playermob.x], [playermob.y], [playermob.z]. Custom ip and computer id fields replaced with the ip and computer id from the located mob.")
-
- if(!DB_ban_record(bantype, playermob, banduration, banreason, banjob, bankey, banip, bancid ))
- to_chat(usr, "Failed to apply ban. ")
- return
- create_message("note", bankey, null, banreason, null, null, 0, 0, null, 0, banseverity)
-
else if(href_list["editrightsbrowser"])
edit_admin_permissions(0)
@@ -502,585 +414,6 @@
if("shade")
M.change_mob_type( /mob/living/simple_animal/shade , null, null, delmob )
-
- /////////////////////////////////////new ban stuff
- else if(href_list["unbanf"])
- if(!check_rights(R_BAN))
- return
-
- var/banfolder = href_list["unbanf"]
- GLOB.Banlist.cd = "/base/[banfolder]"
- var/key = GLOB.Banlist["key"]
- if(alert(usr, "Are you sure you want to unban [key]?", "Confirmation", "Yes", "No") == "Yes")
- if(RemoveBan(banfolder))
- unbanpanel()
- else
- alert(usr, "This ban has already been lifted / does not exist.", "Error", "Ok")
- unbanpanel()
-
- else if(href_list["unbane"])
- if(!check_rights(R_BAN))
- return
-
- UpdateTime()
- var/reason
-
- var/banfolder = href_list["unbane"]
- GLOB.Banlist.cd = "/base/[banfolder]"
- var/reason2 = GLOB.Banlist["reason"]
- var/temp = GLOB.Banlist["temp"]
-
- var/minutes = GLOB.Banlist["minutes"]
-
- var/banned_key = GLOB.Banlist["key"]
- GLOB.Banlist.cd = "/base"
-
- var/duration
-
- switch(alert("Temporary Ban for [banned_key]?",,"Yes","No"))
- if("Yes")
- temp = 1
- var/mins = 0
- if(minutes > GLOB.CMinutes)
- mins = minutes - GLOB.CMinutes
- mins = input(usr,"How long (in minutes)? (Default: 1440)","Ban time",mins ? mins : 1440) as num|null
- if(mins <= 0)
- to_chat(usr, "[mins] is not a valid duration. ")
- return
- minutes = GLOB.CMinutes + mins
- duration = GetExp(minutes)
- reason = input(usr,"Please State Reason For Banning [banned_key].","Reason",reason2) as message|null
- if(!reason)
- return
- if("No")
- temp = 0
- duration = "Perma"
- reason = input(usr,"Please State Reason For Banning [banned_key].","Reason",reason2) as message|null
- if(!reason)
- return
-
- log_admin_private("[key_name(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [duration]")
- ban_unban_log_save("[key_name(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [duration]")
- message_admins("[key_name_admin(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [duration] ")
- GLOB.Banlist.cd = "/base/[banfolder]"
- WRITE_FILE(GLOB.Banlist["reason"], reason)
- WRITE_FILE(GLOB.Banlist["temp"], temp)
- WRITE_FILE(GLOB.Banlist["minutes"], minutes)
- WRITE_FILE(GLOB.Banlist["bannedby"], usr.ckey)
- GLOB.Banlist.cd = "/base"
- unbanpanel()
-
- /////////////////////////////////////new ban stuff
-
- else if(href_list["appearanceban"])
- if(!check_rights(R_BAN))
- return
- var/mob/M = locate(href_list["appearanceban"])
- if(!ismob(M))
- to_chat(usr, "This can only be used on instances of type /mob")
- return
- if(!M.ckey) //sanity
- to_chat(usr, "This mob has no ckey")
- return
-
-
- if(jobban_isbanned(M, "appearance"))
- switch(alert("Remove appearance ban?","Please Confirm","Yes","No"))
- if("Yes")
- ban_unban_log_save("[key_name(usr)] removed [key_name(M)]'s appearance ban.")
- log_admin_private("[key_name(usr)] removed [key_name(M)]'s appearance ban.")
- DB_ban_unban(M.ckey, BANTYPE_ANY_JOB, "appearance")
- if(M.client)
- jobban_buildcache(M.client)
- message_admins("[key_name_admin(usr)] removed [key_name_admin(M)]'s appearance ban. ")
- to_chat(M, "[usr.client.key] has removed your appearance ban. ")
-
- else switch(alert("Appearance ban [M.key]?",,"Yes","No", "Cancel"))
- if("Yes")
- var/reason = input(usr,"Please State Reason.","Reason") as message|null
- if(!reason)
- return
- var/severity = input("Set the severity of the note/ban.", "Severity", null, null) as null|anything in list("High", "Medium", "Minor", "None")
- if(!severity)
- return
- if(!DB_ban_record(BANTYPE_JOB_PERMA, M, -1, reason, "appearance"))
- to_chat(usr, "Failed to apply ban. ")
- return
- if(M.client)
- jobban_buildcache(M.client)
- ban_unban_log_save("[key_name(usr)] appearance banned [key_name(M)]. reason: [reason]")
- log_admin_private("[key_name(usr)] appearance banned [key_name(M)]. \nReason: [reason]")
- create_message("note", M.key, null, "Appearance banned - [reason]", null, null, 0, 0, null, 0, severity)
- message_admins("[key_name_admin(usr)] appearance banned [key_name_admin(M)]. ")
- to_chat(M, "You have been appearance banned by [usr.client.key]. ")
- to_chat(M, "The reason is: [reason] ")
- to_chat(M, "Appearance ban can be lifted only upon request. ")
- var/bran = CONFIG_GET(string/banappeals)
- if(bran)
- to_chat(M, "To try to resolve this matter head to [bran] ")
- else
- to_chat(M, "No ban appeals URL has been set. ")
- if("No")
- return
-
- else if(href_list["jobban2"])
- if(!check_rights(R_BAN))
- return
- var/mob/M = locate(href_list["jobban2"])
- if(!ismob(M))
- to_chat(usr, "This can only be used on instances of type /mob.")
- return
-
- if(!M.ckey) //sanity
- to_chat(usr, "This mob has no ckey.")
- return
-
- var/dat = "Job-Ban Panel: [key_name(M)] "
-
- /***********************************WARNING!************************************
- The jobban stuff looks mangled and disgusting
- But it looks beautiful in-game
- -Nodrak
- ************************************WARNING!***********************************/
- var/counter = 0
-//Regular jobs
- //Command (Blue)
- dat += ""
- dat += "Command Positions "
- for(var/jobPos in GLOB.command_positions)
- if(!jobPos)
- continue
- if(jobban_isbanned(M, jobPos))
- dat += "[jobPos] "
- counter++
- else
- dat += "[jobPos] "
- counter++
-
- if(counter >= 6) //So things dont get squiiiiished!
- dat += " "
- counter = 0
- dat += "
"
-
- //Security (Red)
- counter = 0
- dat += ""
- dat += "Security Positions "
- for(var/jobPos in GLOB.security_positions)
- if(!jobPos)
- continue
- if(jobban_isbanned(M, jobPos))
- dat += "[jobPos] "
- counter++
- else
- dat += "[jobPos] "
- counter++
-
- if(counter >= 5) //So things dont get squiiiiished!
- dat += " "
- counter = 0
- dat += "
"
-
- //Engineering (Yellow)
- counter = 0
- dat += ""
- dat += "Engineering Positions "
- for(var/jobPos in GLOB.engineering_positions)
- if(!jobPos)
- continue
- if(jobban_isbanned(M, jobPos))
- dat += "[jobPos] "
- counter++
- else
- dat += "[jobPos] "
- counter++
-
- if(counter >= 5) //So things dont get squiiiiished!
- dat += " "
- counter = 0
- dat += "
"
-
- //Medical (White)
- counter = 0
- dat += ""
- dat += "Medical Positions "
- for(var/jobPos in GLOB.medical_positions)
- if(!jobPos)
- continue
- if(jobban_isbanned(M, jobPos))
- dat += "[jobPos] "
- counter++
- else
- dat += "[jobPos] "
- counter++
-
- if(counter >= 5) //So things dont get squiiiiished!
- dat += " "
- counter = 0
- dat += "
"
-
- //Science (Purple)
- counter = 0
- dat += ""
- dat += "Science Positions "
- for(var/jobPos in GLOB.science_positions)
- if(!jobPos)
- continue
- if(jobban_isbanned(M, jobPos))
- dat += "[jobPos] "
- counter++
- else
- dat += "[jobPos] "
- counter++
-
- if(counter >= 5) //So things dont get squiiiiished!
- dat += " "
- counter = 0
- dat += "
"
-
- //Supply (Brown)
- counter = 0
- dat += ""
- dat += "Supply Positions "
- for(var/jobPos in GLOB.supply_positions)
- if(!jobPos)
- continue
- if(jobban_isbanned(M, jobPos))
- dat += "[jobPos] "
- counter++
- else
- dat += "[jobPos] "
- counter++
-
- if(counter >= 5) //So things dont get COPYPASTE!
- dat += " "
- counter = 0
- dat += "
"
-
- //Civilian (Grey)
- counter = 0
- dat += ""
- dat += "Civilian Positions "
- for(var/jobPos in GLOB.civilian_positions)
- if(!jobPos)
- continue
- if(jobban_isbanned(M, jobPos))
- dat += "[jobPos] "
- counter++
- else
- dat += "[jobPos] "
- counter++
-
- if(counter >= 5) //So things dont get squiiiiished!
- dat += " "
- counter = 0
- dat += "
"
-
- //Non-Human (Green)
- counter = 0
- dat += ""
- dat += "Non-human Positions "
- for(var/jobPos in GLOB.nonhuman_positions)
- if(!jobPos)
- continue
- if(jobban_isbanned(M, jobPos))
- dat += "[jobPos] "
- counter++
- else
- dat += "[jobPos] "
- counter++
-
- if(counter >= 5) //So things dont get squiiiiished!
- dat += " "
- counter = 0
-
- dat += "
"
-
- //Ghost Roles (light light gray)
- dat += ""
- dat += "Ghost Roles "
-
- //pAI
- if(jobban_isbanned(M, ROLE_PAI))
- dat += "pAI "
- else
- dat += "pAI "
-
-
- //Drones
- if(jobban_isbanned(M, ROLE_DRONE))
- dat += "Drone "
- else
- dat += "Drone "
-
-
- //Positronic Brains
- if(jobban_isbanned(M, ROLE_POSIBRAIN))
- dat += "Posibrain "
- else
- dat += "Posibrain "
-
- //Sentience Potion Spawn
- if(jobban_isbanned(M, ROLE_SENTIENCE))
- dat += "Sentience Potion Spawn "
- else
- dat += "Sentience Potion Spawn "
-
- //Deathsquad
- if(jobban_isbanned(M, ROLE_DEATHSQUAD))
- dat += "Deathsquad "
- else
- dat += "Deathsquad "
-
- //Lavaland roles
- if(jobban_isbanned(M, ROLE_LAVALAND))
- dat += "Lavaland "
- else
- dat += "Lavaland "
-
- dat += "
"
-
- //Antagonist (Orange)
- var/isbanned_dept = jobban_isbanned(M, ROLE_SYNDICATE)
- dat += ""
- dat += "Antagonist Positions | "
- dat += "Team Antagonists | "
- dat += "Conversion Antagonists "
-
- //Traitor
- if(jobban_isbanned(M, ROLE_TRAITOR) || isbanned_dept)
- dat += "Traitor "
- else
- dat += "Traitor "
-
- //Changeling
- if(jobban_isbanned(M, ROLE_CHANGELING) || isbanned_dept)
- dat += "Changeling "
- else
- dat += "Changeling "
-
- //Nuke Operative
- if(jobban_isbanned(M, ROLE_OPERATIVE) || isbanned_dept)
- dat += "Nuke Operative "
- else
- dat += "Nuke Operative "
-
- //Revolutionary
- if(jobban_isbanned(M, ROLE_REV) || isbanned_dept)
- dat += "Revolutionary "
- else
- dat += "Revolutionary "
-
- //Cultist
- if(jobban_isbanned(M, ROLE_CULTIST) || isbanned_dept)
- dat += "Cultist "
- else
- dat += "Cultist "
-
- dat += " " //So things dont get squished.
-
- //Servant of Ratvar
- if(jobban_isbanned(M, ROLE_SERVANT_OF_RATVAR) || isbanned_dept)
- dat += "Servant "
- else
- dat += "Servant "
-
- //Wizard
- if(jobban_isbanned(M, ROLE_WIZARD) || isbanned_dept)
- dat += "Wizard "
- else
- dat += "Wizard "
-
- //Abductor
- if(jobban_isbanned(M, ROLE_ABDUCTOR) || isbanned_dept)
- dat += "Abductor "
- else
- dat += "Abductor "
-
- //Alien
- if(jobban_isbanned(M, ROLE_ALIEN) || isbanned_dept)
- dat += "Alien "
- else
- dat += "Alien "
-
- //Other Roles (black)
- dat += ""
- usr << browse(dat, "window=jobban2;size=800x450")
- return
-
- //JOBBAN'S INNARDS
- else if(href_list["jobban3"])
- if(!check_rights(R_BAN))
- return
- var/mob/M = locate(href_list["jobban4"])
- if(!ismob(M))
- to_chat(usr, "This can only be used on instances of type /mob")
- return
- if(!SSjob)
- to_chat(usr, "Jobs subsystem not initialized yet!")
- return
- //get jobs for department if specified, otherwise just return the one job in a list.
- var/list/joblist = list()
- switch(href_list["jobban3"])
- if("commanddept")
- for(var/jobPos in GLOB.command_positions)
- if(!jobPos)
- continue
- joblist += jobPos
- if("securitydept")
- for(var/jobPos in GLOB.security_positions)
- if(!jobPos)
- continue
- joblist += jobPos
- if("engineeringdept")
- for(var/jobPos in GLOB.engineering_positions)
- if(!jobPos)
- continue
- joblist += jobPos
- if("medicaldept")
- for(var/jobPos in GLOB.medical_positions)
- if(!jobPos)
- continue
- joblist += jobPos
- if("sciencedept")
- for(var/jobPos in GLOB.science_positions)
- if(!jobPos)
- continue
- joblist += jobPos
- if("supplydept")
- for(var/jobPos in GLOB.supply_positions)
- if(!jobPos)
- continue
- joblist += jobPos
- if("civiliandept")
- for(var/jobPos in GLOB.civilian_positions)
- if(!jobPos)
- continue
- joblist += jobPos
- if("nonhumandept")
- for(var/jobPos in GLOB.nonhuman_positions)
- if(!jobPos)
- continue
- joblist += jobPos
- if("ghostroles")
- joblist += list(ROLE_PAI, ROLE_POSIBRAIN, ROLE_DRONE , ROLE_DEATHSQUAD, ROLE_LAVALAND, ROLE_SENTIENCE)
- if("teamantags")
- joblist += list(ROLE_OPERATIVE, ROLE_REV, ROLE_CULTIST, ROLE_SERVANT_OF_RATVAR, ROLE_ABDUCTOR, ROLE_ALIEN)
- if("convertantags")
- joblist += list(ROLE_REV, ROLE_CULTIST, ROLE_SERVANT_OF_RATVAR, ROLE_ALIEN)
- if("otherroles")
- joblist += list(ROLE_MIND_TRANSFER)
- else
- joblist += href_list["jobban3"]
-
- //Create a list of unbanned jobs within joblist
- var/list/notbannedlist = list()
- for(var/job in joblist)
- if(!jobban_isbanned(M, job))
- notbannedlist += job
-
- //Banning comes first
- if(notbannedlist.len) //at least 1 unbanned job exists in joblist so we have stuff to ban.
- var/severity = null
- switch(alert("Temporary Ban for [M.key]?",,"Yes","No", "Cancel"))
- if("Yes")
- var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null
- if(mins <= 0)
- to_chat(usr, "[mins] is not a valid duration. ")
- return
- var/reason = input(usr,"Please State Reason For Banning [M.key].","Reason") as message|null
- if(!reason)
- return
- severity = input("Set the severity of the note/ban.", "Severity", null, null) as null|anything in list("High", "Medium", "Minor", "None")
- if(!severity)
- return
- var/msg
- var/fancy_jobban_duration = DisplayTimeText(mins MINUTES)
- for(var/job in notbannedlist)
- if(!DB_ban_record(BANTYPE_JOB_TEMP, M, mins, reason, job))
- to_chat(usr, "Failed to apply ban. ")
- return
- if(M.client)
- jobban_buildcache(M.client)
- ban_unban_log_save("[key_name(usr)] temp-jobbanned [key_name(M)] from [job] for [fancy_jobban_duration]. reason: [reason]")
- log_admin_private("[key_name(usr)] temp-jobbanned [key_name(M)] from [job] for [fancy_jobban_duration].")
- if(!msg)
- msg = job
- else
- msg += ", [job]"
- create_message("note", M.key, null, "Banned from [msg] - [reason]", null, null, 0, 0, null, 0, severity)
- message_admins("[key_name_admin(usr)] banned [key_name_admin(M)] from [msg] for [fancy_jobban_duration]. ")
- to_chat(M, "You have been [(msg == ("ooc" || "appearance")) ? "banned" : "jobbanned"] by [usr.client.key] from: [msg]. ")
- to_chat(M, "The reason is: [reason] ")
- to_chat(M, "This jobban will be lifted in [fancy_jobban_duration]. ")
- href_list["jobban2"] = 1 // lets it fall through and refresh
- return 1
- if("No")
- var/reason = input(usr,"Please State Reason For Banning [M.key].","Reason") as message|null
- severity = input("Set the severity of the note/ban.", "Severity", null, null) as null|anything in list("High", "Medium", "Minor", "None")
- if(!severity)
- return
- if(reason)
- var/msg
- for(var/job in notbannedlist)
- if(!DB_ban_record(BANTYPE_JOB_PERMA, M, -1, reason, job))
- to_chat(usr, "Failed to apply ban. ")
- return
- if(M.client)
- jobban_buildcache(M.client)
- ban_unban_log_save("[key_name(usr)] perma-jobbanned [key_name(M)] from [job]. reason: [reason]")
- log_admin_private("[key_name(usr)] perma-banned [key_name(M)] from [job]")
- if(!msg)
- msg = job
- else
- msg += ", [job]"
- create_message("note", M.key, null, "Banned from [msg] - [reason]", null, null, 0, 0, null, 0, severity)
- message_admins("[key_name_admin(usr)] banned [key_name_admin(M)] from [msg]. ")
- to_chat(M, "You have been [(msg == ("ooc" || "appearance")) ? "banned" : "jobbanned"] by [usr.client.key] from: [msg]. ")
- to_chat(M, "The reason is: [reason] ")
- to_chat(M, "Jobban can be lifted only upon request. ")
- href_list["jobban2"] = 1 // lets it fall through and refresh
- return 1
- if("Cancel")
- return
-
- //Unbanning joblist
- //all jobs in joblist are banned already OR we didn't give a reason (implying they shouldn't be banned)
- if(joblist.len) //at least 1 banned job exists in joblist so we have stuff to unban.
- var/msg
- for(var/job in joblist)
- var/reason = jobban_isbanned(M, job)
- if(!reason)
- continue //skip if it isn't jobbanned anyway
- switch(alert("Job: '[job]' Reason: '[reason]' Un-jobban?","Please Confirm","Yes","No"))
- if("Yes")
- ban_unban_log_save("[key_name(usr)] unjobbanned [key_name(M)] from [job]")
- log_admin_private("[key_name(usr)] unbanned [key_name(M)] from [job]")
- DB_ban_unban(M.ckey, BANTYPE_ANY_JOB, job)
- if(M.client)
- jobban_buildcache(M.client)
- if(!msg)
- msg = job
- else
- msg += ", [job]"
- else
- continue
- if(msg)
- message_admins("[key_name_admin(usr)] unbanned [key_name_admin(M)] from [msg]. ")
- to_chat(M, "You have been un-jobbanned by [usr.client.key] from [msg]. ")
- href_list["jobban2"] = 1 // lets it fall through and refresh
- return 1
- return 0 //we didn't do anything!
-
else if(href_list["boot2"])
if(!check_rights(R_ADMIN))
return
@@ -1255,80 +588,6 @@
browser.open()
qdel(query_get_message_edits)
- else if(href_list["newban"])
- if(!check_rights(R_BAN))
- return
-
- var/mob/M = locate(href_list["newban"])
- if(!ismob(M))
- return
-
- if(M.client && M.client.holder)
- return //admins cannot be banned. Even if they could, the ban doesn't affect them anyway
-
- switch(alert("Temporary Ban for [M.key]?",,"Yes","No", "Cancel"))
- if("Yes")
- var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null
- if(mins <= 0)
- to_chat(usr, "[mins] is not a valid duration. ")
- return
- var/reason = input(usr,"Please State Reason For Banning [M.key].","Reason") as message|null
- if(!reason)
- return
- if(!DB_ban_record(BANTYPE_TEMP, M, mins, reason))
- to_chat(usr, "Failed to apply ban. ")
- return
- AddBan(M.ckey, M.computer_id, reason, usr.ckey, 1, mins)
- var/ban_duration = "[DisplayTimeText(mins MINUTES)]" //convert from minutes into deciseconds to display the amount of time in days, hours, minutes.
- create_message("note", ckey(M.ckey), usr.ckey, "Banned for [ban_duration] - [reason]", null, null, 0, 0, null, 0, 0)
- ban_unban_log_save("[key_name(usr)] has banned [key_name(M)]. - Reason: [reason] - This will be removed in [ban_duration].")
- to_chat(M, "You have been banned by [usr.client.key].\nReason: [reason] ")
- to_chat(M, "This is a temporary ban, it will be removed in [ban_duration]. The round ID is [GLOB.round_id]. ")
- var/bran = CONFIG_GET(string/banappeals)
- if(bran)
- to_chat(M, "To try to resolve this matter head to [bran] ")
- else
- to_chat(M, "No ban appeals URL has been set. ")
- log_admin_private("[key_name(usr)] has banned [key_name(M)]. - Reason: [key_name(M)] - This will be removed in [ban_duration].")
- var/msg = "[key_name_admin(usr)] has banned [key_name_admin(M)]. - Reason: [reason] - This will be removed in [ban_duration]. "
- message_admins(msg)
- var/datum/admin_help/AH = M.client ? M.client.current_ticket : null
- if(AH)
- AH.Resolve()
- qdel(M.client)
- if("No")
- var/reason = input(usr,"Please State Reason For Banning [M.key].","Reason") as message|null
- if(!reason)
- return
- switch(alert(usr,"IP ban?",,"Yes","No","Cancel"))
- if("Cancel")
- return
- if("Yes")
- AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0, M.lastKnownIP)
- if("No")
- AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0)
- create_message("note", ckey(M.ckey), usr.ckey, "Permanently banned - [reason]", null, null, 0, 0, null, 0, 0)
- to_chat(M, "You have been banned by [usr.client.key].\nReason: [reason] ")
- to_chat(M, "This is a permanent ban. The round ID is [GLOB.round_id]. ")
- var/bran = CONFIG_GET(string/banappeals)
- if(bran)
- to_chat(M, "To try to resolve this matter head to [bran] ")
- else
- to_chat(M, "No ban appeals URL has been set. ")
- if(!DB_ban_record(BANTYPE_PERMA, M, -1, reason))
- to_chat(usr, "Failed to apply ban. ")
- return
- ban_unban_log_save("[key_name(usr)] has permabanned [key_name(M)]. - Reason: [reason] - This is a permanent ban.")
- log_admin_private("[key_name(usr)] has banned [key_name(M)]. - Reason: [reason] - This is a permanent ban.")
- var/msg = "[key_name_admin(usr)] has banned [key_name_admin(M)]. - Reason: [reason] - This is a permanent ban. "
- message_admins(msg)
- var/datum/admin_help/AH = M.client ? M.client.current_ticket : null
- if(AH)
- AH.Resolve()
- qdel(M.client)
- if("Cancel")
- return
-
else if(href_list["mute"])
if(!check_rights(R_ADMIN))
return
@@ -2565,6 +1824,59 @@
T.admin_remove_member(usr,M)
check_teams()
+ else if(href_list["newbankey"])
+ var/player_key = href_list["newbankey"]
+ var/player_ip = href_list["newbanip"]
+ var/player_cid = href_list["newbancid"]
+ ban_panel(player_key, player_ip, player_cid)
+
+ else if(href_list["intervaltype"]) //check for ban panel, intervaltype is used as it's the only value which will always be present
+ if(href_list["roleban_delimiter"])
+ ban_parse_href(href_list)
+ else
+ ban_parse_href(href_list, TRUE)
+
+ else if(href_list["searchunbankey"] || href_list["searchunbanadminkey"] || href_list["searchunbanip"] || href_list["searchunbancid"])
+ var/player_key = href_list["searchunbankey"]
+ var/admin_key = href_list["searchunbanadminkey"]
+ var/player_ip = href_list["searchunbanip"]
+ var/player_cid = href_list["searchunbancid"]
+ unban_panel(player_key, admin_key, player_ip, player_cid)
+
+ else if(href_list["unbanpagecount"])
+ var/page = href_list["unbanpagecount"]
+ var/player_key = href_list["unbankey"]
+ var/admin_key = href_list["unbanadminkey"]
+ var/player_ip = href_list["unbanip"]
+ var/player_cid = href_list["unbancid"]
+ unban_panel(player_key, admin_key, player_ip, player_cid, page)
+
+ else if(href_list["editbanid"])
+ var/edit_id = href_list["editbanid"]
+ var/player_key = href_list["editbankey"]
+ var/player_ip = href_list["editbanip"]
+ var/player_cid = href_list["editbancid"]
+ var/role = href_list["editbanrole"]
+ var/duration = href_list["editbanduration"]
+ var/applies_to_admins = text2num(href_list["editbanadmins"])
+ var/reason = href_list["editbanreason"]
+ var/page = href_list["editbanpage"]
+ var/admin_key = href_list["editbanadminkey"]
+ ban_panel(player_key, player_ip, player_cid, role, duration, applies_to_admins, reason, edit_id, page, admin_key)
+
+ else if(href_list["unbanid"])
+ var/ban_id = href_list["unbanid"]
+ var/player_key = href_list["unbankey"]
+ var/player_ip = href_list["unbanip"]
+ var/player_cid = href_list["unbancid"]
+ var/role = href_list["unbanrole"]
+ var/page = href_list["unbanpage"]
+ var/admin_key = href_list["unbanadminkey"]
+ unban(ban_id, player_key, player_ip, player_cid, role, page, admin_key)
+
+ else if(href_list["unbanlog"])
+ var/ban_id = href_list["unbanlog"]
+ ban_log(ban_id)
/datum/admins/proc/HandleCMode()
if(!check_rights(R_ADMIN))
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index d9732818bdb..ae4241796b0 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -41,7 +41,7 @@
return FALSE
if(!considered_alive(applicant.mind) || considered_afk(applicant.mind)) //makes sure the player isn't a zombie, brain, or just afk all together
return FALSE
- return (!jobban_isbanned(applicant, targetrole) && !jobban_isbanned(applicant, ROLE_SYNDICATE))
+ return !is_banned_from(applicant.ckey, list(targetrole, ROLE_SYNDICATE))
/datum/admins/proc/makeTraitors()
diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm
index ad4851e0c3f..d1c15b15dc0 100644
--- a/code/modules/antagonists/_common/antag_datum.dm
+++ b/code/modules/antagonists/_common/antag_datum.dm
@@ -76,7 +76,7 @@ GLOBAL_LIST_EMPTY(antagonists)
/datum/antagonist/proc/is_banned(mob/M)
if(!M)
return FALSE
- . = (jobban_isbanned(M, ROLE_SYNDICATE) || QDELETED(M) || (job_rank && (jobban_isbanned(M,job_rank) || QDELETED(M))))
+ . = (is_banned_from(M.ckey, list(ROLE_SYNDICATE, job_rank)) || QDELETED(M))
/datum/antagonist/proc/replace_banned_player()
set waitfor = FALSE
diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm
index f874566be11..f44be97d2d3 100644
--- a/code/modules/antagonists/cult/runes.dm
+++ b/code/modules/antagonists/cult/runes.dm
@@ -848,7 +848,7 @@ structure_check() searches for nearby cultist structures required for the invoca
notify_ghosts("Manifest rune invoked in [get_area(src)].", 'sound/effects/ghost2.ogg', source = src)
var/list/ghosts_on_rune = list()
for(var/mob/dead/observer/O in T)
- if(O.client && !jobban_isbanned(O, ROLE_CULTIST) && !QDELETED(src) && !QDELETED(O))
+ if(O.client && !is_banned_from(O.ckey, ROLE_CULTIST) && !QDELETED(src) && !QDELETED(O))
ghosts_on_rune += O
if(!ghosts_on_rune.len)
to_chat(user, "There are no spirits near [src]! ")
diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm
index 230521e3735..f60deae4618 100644
--- a/code/modules/awaymissions/corpse.dm
+++ b/code/modules/awaymissions/corpse.dm
@@ -36,7 +36,7 @@
if(!uses)
to_chat(user, "This spawner is out of charges! ")
return
- if(jobban_isbanned(user, banType))
+ if(is_banned_from(user.key, banType))
to_chat(user, "You are jobanned! ")
return
if(QDELETED(src) || QDELETED(user))
diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm
index c85eb95b058..988c8546f1e 100644
--- a/code/modules/client/client_defines.dm
+++ b/code/modules/client/client_defines.dm
@@ -11,7 +11,7 @@
var/datum/click_intercept = null // Needs to implement InterceptClickOn(user,params,atom) proc
var/AI_Interact = 0
- var/jobbancache = null //Used to cache this client's jobbans to save on DB queries
+ var/ban_cache = null //Used to cache this client's bans to save on DB queries
var/last_message = "" //Contains the last message sent by this client - used to protect against copy-paste spamming.
var/last_message_count = 0 //contins a number of how many times a message identical to last_message was sent.
var/ircreplyamount = 0
@@ -72,4 +72,4 @@
var/list/credits //lazy list of all credit object bound to this client
- var/datum/player_details/player_details //these persist between logins/logouts during the same round.
\ No newline at end of file
+ var/datum/player_details/player_details //these persist between logins/logouts during the same round.
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index e03eaf15097..e4b716fd2be 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -197,7 +197,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Current Quirks: [all_quirks.len ? all_quirks.Join(", ") : "None"] "
dat += "Identity "
dat += ""
- if(jobban_isbanned(user, "appearance"))
+ if(is_banned_from(user.ckey, "Appearance"))
dat += "You are banned from using custom names and appearances. You can continue to adjust your characters, but you will be randomised once you join the game. "
dat += "Random Name "
dat += "Always Random Name: [be_random_name ? "Yes" : "No"] "
@@ -547,14 +547,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Special Role Settings "
- if(jobban_isbanned(user, ROLE_SYNDICATE))
- dat += "You are banned from antagonist roles. "
+ if(is_banned_from(user.ckey, ROLE_SYNDICATE))
+ dat += "You are banned from antagonist roles. "
src.be_special = list()
for (var/i in GLOB.special_roles)
- if(jobban_isbanned(user, i))
- dat += "Be [capitalize(i)]: BANNED "
+ if(is_banned_from(user.ckey, i))
+ dat += "Be [capitalize(i)]: BANNED "
else
var/days_remaining = null
if(ispath(GLOB.special_roles[i]) && CONFIG_GET(flag/use_age_restriction_for_jobs)) //If it's a game mode antag, check if the player meets the minimum age
@@ -673,8 +673,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
HTML += " "
var/rank = job.title
lastJob = job
- if(jobban_isbanned(user, rank))
- HTML += "[rank] BANNED "
+ if(is_banned_from(user.ckey, rank))
+ HTML += "[rank] BANNED "
continue
var/required_playtime_remaining = job.required_playtime_remaining(user.client)
if(required_playtime_remaining)
@@ -684,7 +684,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/available_in_days = job.available_in_days(user.client)
HTML += "[rank] \[IN [(available_in_days)] DAYS\] "
continue
- if((job_civilian_low & overflow.flag) && (rank != SSjob.overflow_role) && !jobban_isbanned(user, SSjob.overflow_role))
+ if((job_civilian_low & overflow.flag) && (rank != SSjob.overflow_role) && !is_banned_from(user.ckey, SSjob.overflow_role))
HTML += "[rank] "
continue
if((rank in GLOB.command_positions) || (rank == "AI"))//Bold head jobs
@@ -957,28 +957,22 @@ GLOBAL_LIST_EMPTY(preferences_datums)
return bal
/datum/preferences/proc/process_link(mob/user, list/href_list)
- if(href_list["jobbancheck"])
- var/job = sanitizeSQL(href_list["jobbancheck"])
- var/sql_ckey = sanitizeSQL(user.ckey)
- var/datum/DBQuery/query_get_jobban = SSdbcore.NewQuery("SELECT reason, bantime, duration, expiration_time, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), a_ckey) FROM [format_table_name("ban")] WHERE ckey = '[sql_ckey]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned) AND job = '[job]'")
- if(!query_get_jobban.warn_execute())
- qdel(query_get_jobban)
+ if(href_list["bancheck"])
+ var/list/ban_details = is_banned_from_with_details(user.ckey, user.client.address, user.client.computer_id, href_list["bancheck"])
+ var/admin = FALSE
+ if(GLOB.admin_datums[user.ckey] || GLOB.deadmins[user.ckey])
+ admin = TRUE
+ for(var/i in ban_details)
+ if(admin && !text2num(i["applies_to_admins"]))
+ continue
+ ban_details = i
+ break //we only want to get the most recent ban's details
+ if(ban_details && ban_details.len)
+ var/expires = "This is a permanent ban."
+ if(ban_details["expiration_time"])
+ expires = " The ban is for [DisplayTimeText(text2num(ban_details["duration"]) MINUTES)] and expires on [ban_details["expiration_time"]] (server time)."
+ to_chat(user, "You, or another user of this computer or connection ([ban_details["key"]]) is banned from playing [href_list["bancheck"]]. The ban reason is: [ban_details["reason"]] This ban (BanID #[ban_details["id"]]) was applied by [ban_details["admin_key"]] on [ban_details["bantime"]] during round ID [ban_details["round_id"]]. [expires] ")
return
- if(query_get_jobban.NextRow())
- var/reason = query_get_jobban.item[1]
- var/bantime = query_get_jobban.item[2]
- var/duration = text2num(query_get_jobban.item[3])
- var/expiration_time = query_get_jobban.item[4]
- var/admin_key = query_get_jobban.item[5]
- var/text
- text = "You, or another user of this computer, ([user.key]) is banned from playing [job]. The ban reason is: [reason] This ban was applied by [admin_key] on [bantime]"
- if(duration > 0)
- text += ". The ban is for [DisplayTimeText(duration MINUTES)] and expires on [expiration_time] (server time)"
- text += ". "
- to_chat(user, text)
- qdel(query_get_jobban)
- return
-
if(href_list["preference"] == "job")
switch(href_list["task"])
if("close")
@@ -990,7 +984,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if("random")
switch(joblessrole)
if(RETURNTOLOBBY)
- if(jobban_isbanned(user, SSjob.overflow_role))
+ if(is_banned_from(user.ckey, SSjob.overflow_role))
joblessrole = BERANDOMJOB
else
joblessrole = BEOVERFLOW
diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm
index 6727db7139a..ab92edc495d 100644
--- a/code/modules/client/verbs/ooc.dm
+++ b/code/modules/client/verbs/ooc.dm
@@ -19,7 +19,7 @@
if(prefs.muted & MUTE_OOC)
to_chat(src, "You cannot use OOC (muted). ")
return
- if(jobban_isbanned(src.mob, "OOC"))
+ if(is_banned_from(ckey, "OOC"))
to_chat(src, "You have been banned from OOC. ")
return
if(QDELETED(src))
diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm
index 6510932ff6b..f744ab1e737 100644
--- a/code/modules/mob/dead/new_player/new_player.dm
+++ b/code/modules/mob/dead/new_player/new_player.dm
@@ -308,7 +308,7 @@
return JOB_UNAVAILABLE_SLOTFULL
else
return JOB_UNAVAILABLE_SLOTFULL
- if(jobban_isbanned(src,rank))
+ if(is_banned_from(ckey, rank))
return JOB_UNAVAILABLE_BANNED
if(QDELETED(src))
return JOB_UNAVAILABLE_GENERIC
@@ -478,7 +478,7 @@
var/frn = CONFIG_GET(flag/force_random_names)
if(!frn)
- frn = jobban_isbanned(src, "appearance")
+ frn = is_banned_from(ckey, "Appearance")
if(QDELETED(src))
return
if(frn)
diff --git a/code/modules/mob/living/brain/posibrain.dm b/code/modules/mob/living/brain/posibrain.dm
index d61642f9d86..4711b6657b5 100644
--- a/code/modules/mob/living/brain/posibrain.dm
+++ b/code/modules/mob/living/brain/posibrain.dm
@@ -85,7 +85,7 @@ GLOBAL_VAR(posibrain_notify_cooldown)
/obj/item/mmi/posibrain/proc/activate(mob/user)
if(QDELETED(brainmob))
return
- if(is_occupied() || jobban_isbanned(user,"posibrain") || QDELETED(brainmob) || QDELETED(src) || QDELETED(user))
+ if(is_occupied() || is_banned_from(user.ckey, ROLE_POSIBRAIN) || QDELETED(brainmob) || QDELETED(src) || QDELETED(user))
return
if(user.suiciding) //if they suicided, they're out forever.
to_chat(user, "[src] fizzles slightly. Sadly it doesn't take those who suicided! ")
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index 32e4e7c19af..e032d55b04e 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -413,7 +413,7 @@
. = FALSE
/datum/emote/living/custom/run_emote(mob/user, params, type_override = null)
- if(jobban_isbanned(user, "emote"))
+ if(is_banned_from(user.ckey, "Emote"))
to_chat(user, "You cannot send custom emotes (banned).")
return FALSE
else if(QDELETED(user))
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm
index a655bdf2317..dd780af30c1 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm
@@ -41,7 +41,7 @@
//ATTACK GHOST IGNORING PARENT RETURN VALUE
/obj/item/drone_shell/attack_ghost(mob/user)
- if(jobban_isbanned(user,"drone") || QDELETED(src) || QDELETED(user))
+ if(is_banned_from(user.ckey, ROLE_DRONE) || QDELETED(src) || QDELETED(user))
return
if(CONFIG_GET(flag/use_age_restriction_for_jobs))
if(!isnum(user.client.player_age)) //apparently what happens when there's no DB connected. just don't let anybody be a drone without admin intervention
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index 35abde0a7ac..ed974d8c389 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -40,7 +40,7 @@
to_chat(usr, "Speech is currently admin-disabled. ")
return
- var/jb = jobban_isbanned(src, "OOC")
+ var/jb = is_banned_from(ckey, "OOC")
if(QDELETED(src))
return
diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm
index 074731d9f86..9fc3b506859 100644
--- a/code/modules/research/xenobiology/xenobiology.dm
+++ b/code/modules/research/xenobiology/xenobiology.dm
@@ -726,7 +726,7 @@
if(SM.sentience_type != animal_type)
to_chat(user, "You cannot transfer your consciousness to [SM]. " )
return ..()
- var/jb = jobban_isbanned(user, ROLE_MIND_TRANSFER)
+ var/jb = is_banned_from(user.ckey, ROLE_MIND_TRANSFER)
if(QDELETED(src) || QDELETED(M) || QDELETED(user))
return
diff --git a/config/config.txt b/config/config.txt
index f39a2bff34c..ee1f7e68813 100644
--- a/config/config.txt
+++ b/config/config.txt
@@ -46,9 +46,6 @@ ADMIN_LEGACY_SYSTEM
##If enabled, each time admins are loaded ranks the database will be updated with the current ranks and their flags
#LOAD_LEGACY_RANKS_ONLY
-## Comment this out if you want to use the SQL based banning system. The legacy systems use the files in the data folder. You need to set up your database to use the SQL based system.
-BAN_LEGACY_SYSTEM
-
## Comment this out to stop locally connected clients from being given the almost full access !localhost! admin rank
ENABLE_LOCALHOST_RANK
diff --git a/html/admin/banpanel.css b/html/admin/banpanel.css
new file mode 100644
index 00000000000..db8f76736f5
--- /dev/null
+++ b/html/admin/banpanel.css
@@ -0,0 +1,182 @@
+.column {
+ float: left;
+ flex-wrap: wrap;
+}
+
+.left {
+ width: 280px;
+}
+
+.middle {
+ width: 80px;
+}
+
+.right {
+ width: 150px;
+}
+
+.row:after {
+ content: '';
+ display: table;
+ clear: both;
+}
+
+.reason {
+ resize: none;
+ min-height: 40px;
+ width: 340px;
+}
+
+.rolegroup {
+ padding: 3px;
+ width: 430px;
+ border: none;
+ text-align: center;
+ outline: none;
+ display: inline-block;
+}
+
+.long {
+ width: 860px;
+}
+
+.content {
+ text-align: center;
+}
+
+.command {
+ background-color: #948f02;
+}
+
+.security {
+ background-color: #a30000;
+}
+
+.engineering {
+ background-color: #fb5613;
+}
+
+.medical {
+ background-color: #337296;
+}
+
+.science {
+ background-color: #993399;
+}
+
+.supply {
+ background-color: #a8732b;
+}
+
+.silicon {
+ background-color: #ff00ff;
+}
+
+.civilian {
+ background-color: #6eaa2c;
+}
+
+.ghostandotherroles {
+ background-color: #5c00e6;
+}
+
+.antagonistpositions {
+ background-color: #6d3f40;
+}
+
+.inputlabel {
+ position: relative;
+ display: inline;
+ cursor: pointer;
+ padding-left: 20px;
+}
+
+.inputlabel input {
+ position: absolute;
+ z-index: -1;
+ opacity: 0;
+}
+
+.inputbox {
+ position: absolute;
+ top: 0px;
+ left: 4px;
+ width: 14px;
+ height: 14px;
+ background: #e6e6e6;
+}
+
+.radio .inputbox {
+ border-radius: 50%;
+}
+
+.inputlabel:hover input ~ .inputbox {
+ background: #b4b4b4;
+}
+
+.inputlabel input:checked ~ .inputbox {
+ background: #2196F3;
+}
+
+.inputlabel:hover input:not([disabled]):checked ~ .inputbox{
+ background: #0a6ebd;
+}
+
+.inputlabel input:disabled ~ .inputbox {
+ pointer-events: none;
+ background: #838383;
+}
+
+.banned {
+ background: #ff4e4e;
+}
+
+.inputlabel:hover input ~ .banned {
+ background: #ff0000;
+}
+
+.inputlabel input:checked ~ .banned {
+ background: #a80000;
+}
+
+.inputlabel:hover input:not([disabled]):checked ~ .banned{
+ background: #810000;
+}
+
+.inputbox:after {
+ position: absolute;
+ display: none;
+ content: '';
+}
+
+.inputlabel input:checked ~ .inputbox:after {
+ display: block;
+}
+
+.checkbox .inputbox:after {
+ top: 1px;
+ left: 5px;
+ width: 3px;
+ height: 9px;
+ transform: rotate(45deg);
+ border: solid #fff;
+ border-width: 0 2px 2px 0;
+}
+
+.radio .inputbox:after {
+ top: 4px;
+ left: 4px;
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ background: #fff;
+}
+
+.select {
+ position: relative;
+ display: inline-block;
+}
+
+.hidden {
+ display: none;
+}
diff --git a/html/admin/banpanel.js b/html/admin/banpanel.js
new file mode 100644
index 00000000000..cc9af098549
--- /dev/null
+++ b/html/admin/banpanel.js
@@ -0,0 +1,16 @@
+function toggle_head(source, ext) {
+ document.getElementById(source.id.slice(0, -4) + ext).checked = source.checked;
+}
+
+function toggle_checkboxes(source, ext) {
+ var checkboxes = document.getElementsByClassName(source.name);
+ for (var i = 0, n = checkboxes.length; i < n; i++) {
+ checkboxes[i].checked = source.checked;
+ if (checkboxes[i].id) {
+ var idfound = document.getElementById(checkboxes[i].id.slice(0, -4) + ext);
+ if (idfound) {
+ idfound.checked = source.checked;
+ }
+ }
+ }
+}
diff --git a/html/admin/unbanpanel.css b/html/admin/unbanpanel.css
new file mode 100644
index 00000000000..cf4aae20c99
--- /dev/null
+++ b/html/admin/unbanpanel.css
@@ -0,0 +1,61 @@
+body {
+ margin: 0;
+}
+
+.searchbar {
+ overflow: hidden;
+ background-color: #272727;
+ position: fixed;
+ top: 0;
+ width: 100%;
+ font-weight: bold;
+ text-align: center;
+ line-height: 30px;
+ z-index: 1;
+}
+
+.main {
+ padding: 16px;
+ margin-top: 20px;
+ text-align: center;
+}
+
+.banbox {
+ position: relative;
+ width: 90%;
+ display: table;
+ flex-direction: column;
+ border: 1px solid #161616;
+ margin-right: auto;
+ margin-left: auto;
+ margin-bottom: 10px;
+ border-radius: 3px;
+}
+
+.header {
+ width: 100%;
+ background-color:rgba(0,0,0,0.3);
+}
+
+.container {
+ display: table;
+ width: 100%;
+}
+
+.reason {
+ display: table-cell;
+ width: 90%;
+}
+
+.edit {
+ display: table-cell;
+ width: 10%;
+}
+
+.banned {
+ background-color:#ff5555;
+}
+
+.unbanned {
+ background-color:#00b75c;
+}
diff --git a/tgstation.dme b/tgstation.dme
index 22e5baa45b7..23efe4fa672 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1077,7 +1077,6 @@
#include "code\modules\admin\admin_verbs.dm"
#include "code\modules\admin\adminmenu.dm"
#include "code\modules\admin\antag_panel.dm"
-#include "code\modules\admin\banjob.dm"
#include "code\modules\admin\chat_commands.dm"
#include "code\modules\admin\check_antagonists.dm"
#include "code\modules\admin\create_mob.dm"
@@ -1088,17 +1087,16 @@
#include "code\modules\admin\holder2.dm"
#include "code\modules\admin\ipintel.dm"
#include "code\modules\admin\IsBanned.dm"
-#include "code\modules\admin\NewBan.dm"
#include "code\modules\admin\permissionedit.dm"
#include "code\modules\admin\player_panel.dm"
#include "code\modules\admin\secrets.dm"
#include "code\modules\admin\sound_emitter.dm"
+#include "code\modules\admin\sql_ban_system.dm"
#include "code\modules\admin\sql_message_system.dm"
#include "code\modules\admin\stickyban.dm"
#include "code\modules\admin\team_panel.dm"
#include "code\modules\admin\topic.dm"
#include "code\modules\admin\whitelist.dm"
-#include "code\modules\admin\DB_ban\functions.dm"
#include "code\modules\admin\verbs\adminhelp.dm"
#include "code\modules\admin\verbs\adminjump.dm"
#include "code\modules\admin\verbs\adminpm.dm"