mirror of
https://github.com/KabKebab/GS13.git
synced 2026-08-21 12:06:15 +01:00
Uploading all files.
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
#Python 3+ Script for importing admins.txt and admin_ranks.txt 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
|
||||
#And that you have run the most recent commands listed in database_changelog.txt
|
||||
#
|
||||
#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 admin_import_2018-02-03.py "localhost" "root" "password" "feedback" "SS13_admin" "SS13_admin_ranks"
|
||||
#
|
||||
#This script performs no error-correction, improper configurations of admins.txt or admin_ranks.txt will cause either breaking exceptions or invalid table rows
|
||||
#It's safe to run this script with your game server(s) active.
|
||||
|
||||
|
||||
import MySQLdb
|
||||
import argparse
|
||||
import re
|
||||
import sys
|
||||
import string
|
||||
|
||||
def parse_text_flags(text, previous):
|
||||
flag_values = {"BUILDMODE":1, "BUILD":1, "ADMIN":2, "REJUVINATE":2, "REJUV":2, "BAN":4, "FUN":8, "SERVER":16, "DEBUG":32, "POSSESS":64, "PERMISSIONS":128, "RIGHTS":128, "STEALTH":256, "POLL":512, "VAREDIT":1024, "SOUNDS":2048, "SOUND":2048, "SPAWN":4096, "CREATE":4096, "AUTOLOGIN":8192, "AUTOADMIN":8192, "DBRANKS":16384}
|
||||
flags_int = 8192
|
||||
exclude_flags_int = 0
|
||||
can_edit_flags_int = 0
|
||||
flags = text.split(" ")
|
||||
if flags:
|
||||
for flag in flags:
|
||||
sign = flag[:1]
|
||||
if flag[1:] in ("@", "prev"):
|
||||
if sign is "+":
|
||||
flags_int = previous[0]
|
||||
elif sign is "-":
|
||||
exclude_flags_int = previous[1]
|
||||
elif sign is "*":
|
||||
can_edit_flags_int = previous[2]
|
||||
continue
|
||||
if flag[1:] in ("EVERYTHING", "HOST", "ALL"):
|
||||
if sign is "+":
|
||||
flags_int = 65535
|
||||
elif sign is "-":
|
||||
exclude_flags_int = 65535
|
||||
elif sign is "*":
|
||||
can_edit_flags_int = 65535
|
||||
continue
|
||||
if flag[1:] in flag_values:
|
||||
if sign is "+":
|
||||
flags_int += flag_values[flag[1:]]
|
||||
elif sign is "-":
|
||||
exclude_flags_int += flag_values[flag[1:]]
|
||||
elif sign is "*":
|
||||
can_edit_flags_int += flag_values[flag[1:]]
|
||||
flags_int = max(min(65535, flags_int), 0)
|
||||
exclude_flags_int = max(min(65535, exclude_flags_int), 0)
|
||||
can_edit_flags_int = max(min(65535, can_edit_flags_int), 0)
|
||||
return flags_int, exclude_flags_int, can_edit_flags_int
|
||||
|
||||
if sys.version_info[0] < 3:
|
||||
raise Exception("Python must be at least version 3 for this script.")
|
||||
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("admintable", help="Name of the current admin table (remember prefixes if you use them)")
|
||||
parser.add_argument("rankstable", help="Name of the current admin ranks (remember prefixes)")
|
||||
args = parser.parse_args()
|
||||
db=MySQLdb.connect(host=args.address, user=args.username, passwd=args.password, db=args.database)
|
||||
cursor=db.cursor()
|
||||
ranks_table = args.rankstable
|
||||
admin_table = args.admintable
|
||||
ckeyExformat = re.sub("@|-|_", " ", string.punctuation)
|
||||
with open("..\\config\\admin_ranks.txt") as rank_file:
|
||||
previous = 0
|
||||
for line in rank_file:
|
||||
if line.strip():
|
||||
if line.startswith("#"):
|
||||
continue
|
||||
matches = re.match("(.+)\\b\\s+=\\s*(.*)", line)
|
||||
rank = "".join((c for c in matches.group(1) if c not in ckeyExformat))
|
||||
flags = parse_text_flags(matches.group(2), previous)
|
||||
previous = flags
|
||||
cursor.execute("INSERT INTO {0} (rank, flags, exclude_flags, can_edit_flags) VALUES ('{1}', {2}, {3}, {4})".format(ranks_table, rank, flags[0], flags[1], flags[2]))
|
||||
with open("..\\config\\admins.txt") as admins_file:
|
||||
previous = 0
|
||||
ckeyformat = string.punctuation.replace("@", " ")
|
||||
for line in admins_file:
|
||||
if line.strip():
|
||||
if line.startswith("#"):
|
||||
continue
|
||||
matches = re.match("(.+)\\b\\s+=\\s+(.+)", line)
|
||||
ckey = "".join((c for c in matches.group(1) if c not in ckeyformat)).lower()
|
||||
rank = "".join((c for c in matches.group(2) if c not in ckeyExformat))
|
||||
cursor.execute("INSERT INTO {0} (ckey, rank) VALUES ('{1}', '{2}')".format(admin_table, ckey, rank))
|
||||
db.commit()
|
||||
cursor.close()
|
||||
print("Import complete.")
|
||||
@@ -0,0 +1,481 @@
|
||||
Any time you make a change to the schema files, remember to increment the database schema version. Generally increment the minor number, major should be reserved for significant changes to the schema. Both values go up to 255.
|
||||
|
||||
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);
|
||||
or
|
||||
INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (4, 7);
|
||||
|
||||
In any query remember to add a prefix to the table names if you use one.
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Version 4.7, 18 August 2018, by CitrusGender
|
||||
Modified table `messages`, adding column `severity` to classify notes based on their severity.
|
||||
|
||||
ALTER TABLE `messages` ADD `severity` enum('high','medium','minor','none') DEFAULT NULL AFTER `expire_timestamp`
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Version 4.6, 11 August 2018, by Jordie0608
|
||||
Modified table `messages`, adding column `expire_timestamp` to allow for auto-"deleting" messages.
|
||||
|
||||
ALTER TABLE `messages` ADD `expire_timestamp` DATETIME NULL DEFAULT NULL AFTER `secret`;
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Version 4.5, 9 July 2018, by Jordie0608
|
||||
Modified table `player`, adding column `byond_key` to store a user's key along with their ckey.
|
||||
To populate this new column run the included script 'populate_key_2018-07', see the file for use instructions.
|
||||
|
||||
ALTER TABLE `player` ADD `byond_key` VARCHAR(32) DEFAULT NULL AFTER `ckey`;
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Version 4.4, 9 May 2018, by Jordie0608
|
||||
Modified table `round`, renaming column `start_datetime` to `initialize_datetime` and `end_datetime` to `shutdown_datetime` and adding columns to replace both under the same name in preparation for changes to TGS server initialization.
|
||||
|
||||
ALTER TABLE `round`
|
||||
ALTER `start_datetime` DROP DEFAULT;
|
||||
ALTER TABLE `round`
|
||||
CHANGE COLUMN `start_datetime` `initialize_datetime` DATETIME NOT NULL AFTER `id`,
|
||||
ADD COLUMN `start_datetime` DATETIME NULL DEFAULT NULL AFTER `initialize_datetime`,
|
||||
CHANGE COLUMN `end_datetime` `shutdown_datetime` DATETIME NULL DEFAULT NULL AFTER `start_datetime`,
|
||||
ADD COLUMN `end_datetime` DATETIME NULL DEFAULT NULL AFTER `shutdown_datetime`;
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Version 4.3, 9 May 2018, by MrStonedOne
|
||||
Added table `role_time_log` and triggers `role_timeTlogupdate`, `role_timeTloginsert` and `role_timeTlogdelete` to update it from changes to `role_time`
|
||||
|
||||
CREATE TABLE `role_time_log` ( `id` BIGINT NOT NULL AUTO_INCREMENT , `ckey` VARCHAR(32) NOT NULL , `job` VARCHAR(128) NOT NULL , `delta` INT NOT NULL , `datetime` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , PRIMARY KEY (`id`), INDEX (`ckey`), INDEX (`job`), INDEX (`datetime`)) ENGINE = InnoDB;
|
||||
|
||||
DELIMITER
|
||||
$$
|
||||
CREATE TRIGGER `role_timeTlogupdate` AFTER UPDATE ON `role_time` FOR EACH ROW BEGIN INSERT into role_time_log (ckey, job, delta) VALUES (NEW.CKEY, NEW.job, NEW.minutes-OLD.minutes);
|
||||
END
|
||||
$$
|
||||
CREATE TRIGGER `role_timeTloginsert` AFTER INSERT ON `role_time` FOR EACH ROW BEGIN INSERT into role_time_log (ckey, job, delta) VALUES (NEW.ckey, NEW.job, NEW.minutes);
|
||||
END
|
||||
$$
|
||||
CREATE TRIGGER `role_timeTlogdelete` AFTER DELETE ON `role_time` FOR EACH ROW BEGIN INSERT into role_time_log (ckey, job, delta) VALUES (OLD.ckey, OLD.job, 0-OLD.minutes);
|
||||
END
|
||||
$$
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Version 4.2, 17 April 2018, by Jordie0608
|
||||
Modified table 'admin', adding the columns 'round_id' and 'target'
|
||||
ALTER TABLE `admin_log`
|
||||
ADD COLUMN `round_id` INT UNSIGNED NOT NULL AFTER `datetime`,
|
||||
ADD COLUMN `target` VARCHAR(32) NOT NULL AFTER `operation`;
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Version 4.1, 3 February 2018, by Jordie0608
|
||||
Modified tables 'admin', 'admin_log' and 'admin_rank', removing unnecessary columns and adding support for excluding rights flags from admin ranks.
|
||||
This change was made to enable use of sql-based admin loading.
|
||||
To import your existing admins and ranks run the included script 'admin_import_2018-02-03.py', see the file for use instructions.
|
||||
Legacy file-based admin loading is still supported, if you want to continue using it the script doesn't need to be run.
|
||||
|
||||
ALTER TABLE `admin`
|
||||
CHANGE COLUMN `rank` `rank` VARCHAR(32) NOT NULL AFTER `ckey`,
|
||||
DROP COLUMN `id`,
|
||||
DROP COLUMN `level`,
|
||||
DROP COLUMN `flags`,
|
||||
DROP COLUMN `email`,
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`ckey`);
|
||||
|
||||
ALTER TABLE `admin_log`
|
||||
CHANGE COLUMN `datetime` `datetime` DATETIME NOT NULL AFTER `id`,
|
||||
CHANGE COLUMN `adminckey` `adminckey` VARCHAR(32) NOT NULL AFTER `datetime`,
|
||||
CHANGE COLUMN `adminip` `adminip` INT(10) UNSIGNED NOT NULL AFTER `adminckey`,
|
||||
ADD COLUMN `operation` ENUM('add admin','remove admin','change admin rank','add rank','remove rank','change rank flags') NOT NULL AFTER `adminip`,
|
||||
CHANGE COLUMN `log` `log` VARCHAR(1000) NOT NULL AFTER `operation`;
|
||||
|
||||
ALTER TABLE `admin_ranks`
|
||||
CHANGE COLUMN `rank` `rank` VARCHAR(32) NOT NULL FIRST,
|
||||
CHANGE COLUMN `flags` `flags` SMALLINT UNSIGNED NOT NULL AFTER `rank`,
|
||||
ADD COLUMN `exclude_flags` SMALLINT UNSIGNED NOT NULL AFTER `flags`,
|
||||
ADD COLUMN `can_edit_flags` SMALLINT(5) UNSIGNED NOT NULL AFTER `exclude_flags`,
|
||||
DROP COLUMN `id`,
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`rank`);
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Version 4.0, 12 November 2017, by Jordie0608
|
||||
Modified feedback table to use json, a python script is used to migrate data to this new format.
|
||||
|
||||
See the file 'feedback_conversion_2017-11-12.py' for instructions on how to use the script.
|
||||
|
||||
A new json feedback table can be created with:
|
||||
CREATE TABLE `feedback` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`datetime` datetime NOT NULL,
|
||||
`round_id` int(11) unsigned NOT NULL,
|
||||
`key_name` varchar(32) NOT NULL,
|
||||
`key_type` enum('text', 'amount', 'tally', 'nested tally', 'associative') NOT NULL,
|
||||
`version` tinyint(3) unsigned NOT NULL,
|
||||
`json` json NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Version 3.4, 28 August 2017, by MrStonedOne
|
||||
Modified table 'messages', adding a deleted column and editing all indexes to include it
|
||||
|
||||
ALTER TABLE `messages`
|
||||
ADD COLUMN `deleted` tinyint(1) unsigned NOT NULL DEFAULT '0' AFTER `edits`,
|
||||
DROP INDEX `idx_msg_ckey_time`,
|
||||
DROP INDEX `idx_msg_type_ckeys_time`,
|
||||
DROP INDEX `idx_msg_type_ckey_time_odr`,
|
||||
ADD INDEX `idx_msg_ckey_time` (`targetckey`,`timestamp`, `deleted`),
|
||||
ADD INDEX `idx_msg_type_ckeys_time` (`type`,`targetckey`,`adminckey`,`timestamp`, `deleted`),
|
||||
ADD INDEX `idx_msg_type_ckey_time_odr` (`type`,`targetckey`,`timestamp`, `deleted`);
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Version 3.3, 25 August 2017, by Jordie0608
|
||||
|
||||
Modified tables 'connection_log', 'legacy_population', 'library', 'messages' and 'player' to add additional 'round_id' tracking in various forms and 'server_ip' and 'server_port' to the table 'messages'.
|
||||
|
||||
ALTER TABLE `connection_log` ADD COLUMN `round_id` INT(11) UNSIGNED NOT NULL AFTER `server_port`;
|
||||
ALTER TABLE `legacy_population` ADD COLUMN `round_id` INT(11) UNSIGNED NOT NULL AFTER `server_port`;
|
||||
ALTER TABLE `library` ADD COLUMN `round_id_created` INT(11) UNSIGNED NOT NULL AFTER `deleted`;
|
||||
ALTER TABLE `messages` ADD COLUMN `server_ip` INT(10) UNSIGNED NOT NULL AFTER `server`, ADD COLUMN `server_port` SMALLINT(5) UNSIGNED NOT NULL AFTER `server_ip`, ADD COLUMN `round_id` INT(11) UNSIGNED NOT NULL AFTER `server_port`;
|
||||
ALTER TABLE `player` ADD COLUMN `firstseen_round_id` INT(11) UNSIGNED NOT NULL AFTER `firstseen`, ADD COLUMN `lastseen_round_id` INT(11) UNSIGNED NOT NULL AFTER `lastseen`;
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Version 3.2, 18 August 2017, by Cyberboss and nfreader
|
||||
|
||||
Modified table 'death', adding the columns `last_words` and 'suicide'.
|
||||
|
||||
ALTER TABLE `death`
|
||||
ADD COLUMN `last_words` varchar(255) DEFAULT NULL AFTER `staminaloss`,
|
||||
ADD COLUMN `suicide` tinyint(0) NOT NULL DEFAULT '0' AFTER `last_words`;
|
||||
|
||||
Remember to add a prefix to the table name if you use them.
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Version 3.1, 20th July 2017, by Shadowlight213
|
||||
Added role_time table to track time spent playing departments.
|
||||
Also, added flags column to the player table.
|
||||
|
||||
CREATE TABLE `role_time` ( `ckey` VARCHAR(32) NOT NULL , `job` VARCHAR(128) NOT NULL , `minutes` INT UNSIGNED NOT NULL, PRIMARY KEY (`ckey`, `job`) ) ENGINE = InnoDB;
|
||||
|
||||
ALTER TABLE `player` ADD `flags` INT NOT NULL default '0' AFTER `accountjoindate`;
|
||||
|
||||
Remember to add a prefix to the table name if you use them.
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Version 3.0, 28 June 2017, by oranges
|
||||
Added schema_revision to store the current db revision, why start at 3.0?
|
||||
|
||||
because:
|
||||
15:09 <+MrStonedOne> 1.0 was erro, 2.0 was when i removed erro_, 3.0 was when jordie made all the strings that hold numbers numbers
|
||||
|
||||
CREATE TABLE `schema_revision` (
|
||||
`major` TINYINT(3) UNSIGNED NOT NULL ,
|
||||
`minor` TINYINT(3) UNSIGNED NOT NULL ,
|
||||
`date` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL,
|
||||
PRIMARY KEY ( `major`,`minor` )
|
||||
) ENGINE = INNODB;
|
||||
|
||||
INSERT INTO `schema_revision` (`major`, `minor`) VALUES (3, 0);
|
||||
|
||||
Remember to add a prefix to the table name if you use them.
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
26 June 2017, by Jordie0608
|
||||
|
||||
Modified table 'poll_option', adding the column 'default_percentage_calc'.
|
||||
|
||||
ALTER TABLE `poll_option` ADD COLUMN `default_percentage_calc` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1' AFTER `descmax`
|
||||
|
||||
Remember to add a prefix to the table name if you use them.
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
22 June 2017, by Jordie0608
|
||||
|
||||
Modified table 'poll_option', removing the column 'percentagecalc'.
|
||||
|
||||
ALTER TABLE `poll_option` DROP COLUMN `percentagecalc`
|
||||
|
||||
Remember to add a prefix to the table name if you use them.
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
8 June 2017, by Jordie0608
|
||||
|
||||
Modified table 'death', adding column 'round_id', removing column 'gender' and replacing column 'coord' with the columns 'x_coord', 'y_coord' and 'z_coord'.
|
||||
|
||||
START TRANSACTION;
|
||||
ALTER TABLE `death` DROP COLUMN `gender`, ADD COLUMN `x_coord` SMALLINT(5) UNSIGNED NOT NULL AFTER `coord`, ADD COLUMN `y_coord` SMALLINT(5) UNSIGNED NOT NULL AFTER `x_coord`, ADD COLUMN `z_coord` SMALLINT(5) UNSIGNED NOT NULL AFTER `y_coord`, ADD COLUMN `round_id` INT(11) NOT NULL AFTER `server_port`;
|
||||
SET SQL_SAFE_UPDATES = 0;
|
||||
UPDATE `death` SET `x_coord` = SUBSTRING_INDEX(`coord`, ',', 1), `y_coord` = SUBSTRING_INDEX(SUBSTRING_INDEX(`coord`, ',', 2), ',', -1), `z_coord` = SUBSTRING_INDEX(`coord`, ',', -1);
|
||||
SET SQL_SAFE_UPDATES = 1;
|
||||
ALTER TABLE `death` DROP COLUMN `coord`;
|
||||
COMMIT;
|
||||
|
||||
Remember to add a prefix to the table name if you use them.
|
||||
|
||||
---------------------------------------------------
|
||||
|
||||
30 May 2017, by MrStonedOne
|
||||
|
||||
Z levels changed, this query allows you to convert old ss13 death records:
|
||||
|
||||
UPDATE death SET coord = CONCAT(SUBSTRING_INDEX(coord, ',', 2), ', ', CASE TRIM(SUBSTRING_INDEX(coord, ',', -1)) WHEN 1 THEN 2 WHEN 2 THEN 1 ELSE TRIMSUBSTRING_INDEX(coord, ',', -1) END)
|
||||
|
||||
---------------------------------------------------
|
||||
|
||||
26 May 2017, by Jordie0608
|
||||
|
||||
Modified table 'ban', adding the column 'round_id'.
|
||||
|
||||
ALTER TABLE `ban` ADD COLUMN `round_id` INT(11) NOT NULL AFTER `server_port`
|
||||
|
||||
Remember to add a prefix to the table name if you use them.
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
20 May 2017, by Jordie0608
|
||||
|
||||
Created table `round` to replace tracking of the datapoints 'round_start', 'round_end', 'server_ip', 'game_mode', 'round_end_results', 'end_error', 'end_proper', 'emergency_shuttle', 'map_name' and 'station_renames' in the `feedback` table.
|
||||
Once created this table is populated with rows from the `feedback` table.
|
||||
|
||||
START TRANSACTION;
|
||||
CREATE TABLE `round` (`id` INT(11) NOT NULL AUTO_INCREMENT, `start_datetime` DATETIME NOT NULL, `end_datetime` DATETIME NULL, `server_ip` INT(10) UNSIGNED NOT NULL, `server_port` SMALLINT(5) UNSIGNED NOT NULL, `commit_hash` CHAR(40) NULL, `game_mode` VARCHAR(32) NULL, `game_mode_result` VARCHAR(64) NULL, `end_state` VARCHAR(64) NULL, `shuttle_name` VARCHAR(64) NULL, `map_name` VARCHAR(32) NULL, `station_name` VARCHAR(80) NULL, PRIMARY KEY (`id`));
|
||||
ALTER TABLE `feedback` ADD INDEX `tmp` (`round_id` ASC, `var_name` ASC);
|
||||
INSERT INTO `round`
|
||||
(`id`, `start_datetime`, `end_datetime`, `server_ip`, `server_port`, `commit_hash`, `game_mode`, `game_mode_result`, `end_state`, `shuttle_name`, `map_name`, `station_name`)
|
||||
SELECT DISTINCT ri.round_id, IFNULL(STR_TO_DATE(st.details,'%a %b %e %H:%i:%s %Y'), TIMESTAMP(0)), STR_TO_DATE(et.details,'%a %b %e %H:%i:%s %Y'), IFNULL(INET_ATON(SUBSTRING_INDEX(IF(si.details = '', '0', IF(SUBSTRING_INDEX(si.details, ':', 1) LIKE '%_._%', si.details, '0')), ':', 1)), INET_ATON(0)), IFNULL(IF(si.details LIKE '%:_%', CAST(SUBSTRING_INDEX(si.details, ':', -1) AS UNSIGNED), '0'), '0'), ch.details, gm.details, mr.details, IFNULL(es.details, ep.details), ss.details, mn.details, sn.details
|
||||
FROM `feedback`AS ri
|
||||
LEFT JOIN `feedback` AS st ON ri.round_id = st.round_id AND st.var_name = "round_start" LEFT JOIN `feedback` AS et ON ri.round_id = et.round_id AND et.var_name = "round_end" LEFT JOIN `feedback` AS si ON ri.round_id = si.round_id AND si.var_name = "server_ip" LEFT JOIN `feedback` AS ch ON ri.round_id = ch.round_id AND ch.var_name = "revision" LEFT JOIN `feedback` AS gm ON ri.round_id = gm.round_id AND gm.var_name = "game_mode" LEFT JOIN `feedback` AS mr ON ri.round_id = mr.round_id AND mr.var_name = "round_end_result" LEFT JOIN `feedback` AS es ON ri.round_id = es.round_id AND es.var_name = "end_state" LEFT JOIN `feedback` AS ep ON ri.round_id = ep.round_id AND ep.var_name = "end_proper" LEFT JOIN `feedback` AS ss ON ri.round_id = ss.round_id AND ss.var_name = "emergency_shuttle" LEFT JOIN `feedback` AS mn ON ri.round_id = mn.round_id AND mn.var_name = "map_name" LEFT JOIN `feedback` AS sn ON ri.round_id = sn.round_id AND sn.var_name = "station_renames";
|
||||
ALTER TABLE `feedback` DROP INDEX `tmp`;
|
||||
COMMIT;
|
||||
|
||||
It's not necessary to delete the rows from the `feedback` table but henceforth these datapoints will be in the `round` table.
|
||||
|
||||
Remember to add a prefix to the table names if you use them
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
21 April 2017, by Jordie0608
|
||||
|
||||
Modified table 'player', adding the column 'accountjoindate', removing the column 'id' and making the column 'ckey' the primary key.
|
||||
|
||||
ALTER TABLE `player` DROP COLUMN `id`, ADD COLUMN `accountjoindate` DATE NULL AFTER `lastadminrank`, DROP PRIMARY KEY, ADD PRIMARY KEY (`ckey`), DROP INDEX `ckey`;
|
||||
|
||||
Remember to add a prefix to the table name if you use them.
|
||||
|
||||
----------------------------------------------------
|
||||
10 March 2017, by Jordie0608
|
||||
|
||||
Modified table 'death', adding the columns 'toxloss', 'cloneloss', and 'staminaloss' and table 'legacy_population', adding the columns 'server_ip' and 'server_port'.
|
||||
|
||||
ALTER TABLE `death` ADD COLUMN `toxloss` SMALLINT(5) UNSIGNED NOT NULL AFTER `oxyloss`, ADD COLUMN `cloneloss` SMALLINT(5) UNSIGNED NOT NULL AFTER `toxloss`, ADD COLUMN `staminaloss` SMALLINT(5) UNSIGNED NOT NULL AFTER `cloneloss`;
|
||||
|
||||
ALTER TABLE `legacy_population` ADD COLUMN `server_ip` INT(10) UNSIGNED NOT NULL AFTER `time`, ADD COLUMN `server_port` SMALLINT(5) UNSIGNED NOT NULL AFTER `server_ip`;
|
||||
|
||||
Remember to add a prefix to the table name if you use them.
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
19 February 2017, by Jordie0608
|
||||
|
||||
Optimised and indexed significant portions of the schema.
|
||||
|
||||
See the file 'optimisations_2017-02-19.sql' for instructions on how to apply these changes to your database.
|
||||
|
||||
Remember to add a prefix to the table name if you use them
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
30 January 2017, by Lzimann
|
||||
|
||||
Modified table 'death', adding the columns 'mapname' and 'server'.
|
||||
|
||||
ALTER TABLE `death` ADD COLUMN `mapname` TEXT NOT NULL AFTER `coord`, ADD COLUMN `server` TEXT NOT NULL AFTER `mapname`
|
||||
|
||||
Remember to add a prefix to the table name if you use them
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
25 January 2017, by Jordie0608
|
||||
|
||||
Created table 'messages' to supersede the 'notes', 'memos', and 'watchlist' tables; they must be collated into this new table
|
||||
|
||||
To create this new table run the following command:
|
||||
|
||||
CREATE TABLE `messages` (`id` INT(11) NOT NULL AUTO_INCREMENT , `type` VARCHAR(32) NOT NULL , `targetckey` VARCHAR(32) NOT NULL , `adminckey` VARCHAR(32) NOT NULL , `text` TEXT NOT NULL , `timestamp` DATETIME NOT NULL , `server` VARCHAR(32) NULL , `secret` TINYINT(1) NULL DEFAULT 1 , `lasteditor` VARCHAR(32) NULL , `edits` TEXT NULL , PRIMARY KEY (`id`) )
|
||||
|
||||
To copy the contents of the 'notes', 'memos', and 'watchlist' tables to this new table run the following commands:
|
||||
|
||||
INSERT INTO `messages`
|
||||
(`id`,`type`,`targetckey`,`adminckey`,`text`,`timestamp`,`server`,`secret`,`lasteditor`,`edits`) SELECT `id`, "note", `ckey`, `adminckey`, `notetext`, `timestamp`, `server`, `secret`, `last_editor`, `edits` FROM `notes`
|
||||
|
||||
INSERT INTO `messages`
|
||||
(`type`,`targetckey`,`adminckey`,`text`,`timestamp`,`lasteditor`,`edits`) SELECT "memo", `ckey`, `ckey`, `memotext`, `timestamp`, `last_editor`, `edits` FROM `memo`
|
||||
|
||||
INSERT INTO `messages`
|
||||
(`type`,`targetckey`,`adminckey`,`text`,`timestamp`,`lasteditor`,`edits`) SELECT "watchlist entry", `ckey`, `adminckey`, `reason`, `timestamp`, `last_editor`, `edits` FROM `watch`
|
||||
|
||||
It's not necessary to delete the 'notes', 'memos', and 'watchlist' tables but they will no longer be used.
|
||||
|
||||
Remember to add a prefix to the table names if you use them
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
1 September 2016, by Jordie0608
|
||||
|
||||
Modified table 'notes', adding column 'secret'.
|
||||
|
||||
ALTER TABLE `notes` ADD COLUMN `secret` TINYINT(1) NOT NULL DEFAULT '1' AFTER `server`
|
||||
|
||||
Remember to add a prefix to the table name if you use them
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
19 August 2016, by Shadowlight213
|
||||
|
||||
Changed appearance bans to be jobbans.
|
||||
|
||||
UPDATE `ban` SET `job` = "appearance", `bantype` = "JOB_PERMABAN" WHERE `bantype` = "APPEARANCE_PERMABAN"
|
||||
|
||||
Remember to add a prefix to the table name if you use them
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
3 July 2016, by Jordie0608
|
||||
|
||||
Modified table 'poll_question', adding column 'dontshow' which was recently added to the server schema.
|
||||
|
||||
ALTER TABLE `poll_question` ADD COLUMN `dontshow` TINYINT(1) NOT NULL DEFAULT '0' AFTER `for_trialmin`
|
||||
|
||||
Remember to add a prefix to the table name if you use them
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
16th April 2016
|
||||
|
||||
Added ipintel table, only required if ip intel is enabled in the config
|
||||
|
||||
CREATE TABLE `ipintel` (
|
||||
`ip` INT UNSIGNED NOT NULL ,
|
||||
`date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL ,
|
||||
`intel` REAL NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY ( `ip` )
|
||||
) ENGINE = INNODB;
|
||||
|
||||
---------------------------------------------------
|
||||
|
||||
21 September 2015, by Jordie0608
|
||||
|
||||
Modified table 'poll_question', adding columns 'createdby_ckey', 'createdby_ip' and 'for_trialmin' to bring it inline with the schema used by the tg servers.
|
||||
|
||||
ALTER TABLE `poll_question` ADD COLUMN `createdby_ckey` VARCHAR(45) NULL DEFAULT NULL AFTER `multiplechoiceoptions`, ADD COLUMN `createdby_ip` VARCHAR(45) NULL DEFAULT NULL AFTER `createdby_ckey`, ADD COLUMN `for_trialmin` VARCHAR(45) NULL DEFAULT NULL AFTER `createdby_ip`
|
||||
|
||||
Remember to add a prefix to the table name if you use them
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
27 August 2015, by Jordie0608
|
||||
|
||||
Modified table 'watch', removing 'id' column, making 'ckey' primary and adding the columns 'timestamp', 'adminckey', 'last_editor' and 'edits'.
|
||||
|
||||
ALTER TABLE `watch` DROP COLUMN `id`, ADD COLUMN `timestamp` datetime NOT NULL AFTER `reason`, ADD COLUMN `adminckey` varchar(32) NOT NULL AFTER `timestamp`, ADD COLUMN `last_editor` varchar(32) NULL AFTER `adminckey`, ADD COLUMN `edits` text NULL AFTER `last_editor`, DROP PRIMARY KEY, ADD PRIMARY KEY (`ckey`)
|
||||
|
||||
Remember to add a prefix to the table name if you use them.
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
14 August 2015, by Jordie0608
|
||||
|
||||
Added new table 'notes' to replace BYOND's .sav note system.
|
||||
|
||||
To create this new table run the following command:
|
||||
|
||||
CREATE TABLE `notes` ( `id` int(11) NOT NULL AUTO_INCREMENT, `ckey` varchar(32) NOT NULL, `notetext` text NOT NULL, `timestamp` datetime NOT NULL, `adminckey` varchar(32) NOT NULL, `last_editor` varchar(32), `edits` text, `server` varchar(50) NOT NULL, PRIMARY KEY (`id`))
|
||||
|
||||
Remember to add prefix to the table name if you use them.
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
28 July 2015, by Jordie0608
|
||||
|
||||
Modified table 'memo', removing 'id' column and making 'ckey' primary.
|
||||
|
||||
ALTER TABLE `memo` DROP COLUMN `id`, DROP PRIMARY KEY, ADD PRIMARY KEY (`ckey`)
|
||||
|
||||
Remember to add prefix to the table name if you use them.
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
19 July 2015, by Jordie0608
|
||||
|
||||
Added new table 'memo' for use with admin memos.
|
||||
|
||||
To create this new table run the following command:
|
||||
|
||||
CREATE TABLE `memo` (`id` int(11) NOT NULL AUTO_INCREMENT, `ckey` varchar(32) NOT NULL, `memotext` text NOT NULL, `timestamp` datetime NOT NULL, `last_editor` varchar(32), `edits` text, PRIMARY KEY (`id`))
|
||||
|
||||
Remember to add prefix to the table name if you use them.
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
7 July 2015, by MrStonedOne
|
||||
|
||||
Removed the privacy poll and related table. Existing codebases may safely delete the privacy table after updating:
|
||||
|
||||
DROP TABLE `privacy`;
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
19 May 2015, by Jordie0608
|
||||
|
||||
Added new table 'watch' for use in flagging ckeys. It shouldn't ever exist, but also added command to de-erroize this new table just in case someone does make it like that.
|
||||
|
||||
To create this new table run the following command:
|
||||
|
||||
CREATE TABLE `watch` (`id` int(11) NOT NULL AUTO_INCREMENT, `ckey` varchar(32) NOT NULL, `reason` text NOT NULL, PRIMARY KEY (`id`))
|
||||
|
||||
Remember to add prefix to the table name if you use them.
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
19 September 2014, by MrStonedOne
|
||||
|
||||
Removed erro_ from table names. dbconfig.txt has a option allowing you to change the prefix used in code, defaults to "erro_" if left out for legacy reasons.
|
||||
|
||||
If you are creating a new database and want to change the prefix, simply find and replace SS13_ to what ever you want (including nothing) and set the prefix value
|
||||
|
||||
Two schema files are now included, one with prefixes and one without.
|
||||
|
||||
If you have an existing database, and you want to rid your database of erros, you will have to rename all of the tables. A bit sql is included to do just that in errofreedatabase.sql Feel free to find and replace the prefix to what ever you want (or nothing)
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
4 November 2013, by Errorage
|
||||
|
||||
The column 'deleted' was added to the erro_library table. If set to anything other than null, the book is interpreted as deleted.
|
||||
|
||||
To update your database, execute the following code in phpmyadmin, mysql workbench or whatever program you use:
|
||||
|
||||
ALTER TABLE erro_library ADD COLUMN deleted TINYINT(1) NULL DEFAULT NULL AFTER datetime;
|
||||
|
||||
If you want to 'soft delete' a book (meaning it remains in the library, but isn't viewable by players), set the value in the 'deleted' column for the row to 1. To undelete, set it back to null. If you're making an admin tool to work with this, execute the following SQL statement to soft-delete the book with id someid:
|
||||
|
||||
UPDATE erro_library SET deleted = 1 WHERE id = someid
|
||||
|
||||
(Replace someid with the id of the book you want to soft delete.)
|
||||
|
||||
----------------------------------------------------
|
||||
@@ -0,0 +1,15 @@
|
||||
ALTER TABLE erro_admin RENAME TO SS13_admin;
|
||||
ALTER TABLE erro_admin_log RENAME TO SS13_admin_log;
|
||||
ALTER TABLE erro_admin_ranks RENAME TO SS13_admin_ranks;
|
||||
ALTER TABLE erro_ban RENAME TO SS13_ban;
|
||||
ALTER TABLE erro_connection_log RENAME TO SS13_connection_log;
|
||||
ALTER TABLE erro_death RENAME TO SS13_death;
|
||||
ALTER TABLE erro_feedback RENAME TO SS13_feedback;
|
||||
ALTER TABLE erro_legacy_population RENAME TO SS13_legacy_population;
|
||||
ALTER TABLE erro_library RENAME TO SS13_library;
|
||||
ALTER TABLE erro_player RENAME TO SS13_player;
|
||||
ALTER TABLE erro_poll_option RENAME TO SS13_poll_option;
|
||||
ALTER TABLE erro_poll_question RENAME TO SS13_poll_question;
|
||||
ALTER TABLE erro_poll_textreply RENAME TO SS13_poll_textreply;
|
||||
ALTER TABLE erro_poll_vote RENAME TO SS13_poll_vote;
|
||||
ALTER TABLE erro_watch RENAME TO SS13_watch;
|
||||
@@ -0,0 +1,553 @@
|
||||
#Python 3+ Script for jsonifying feedback table data as of 2017-11-12 made by Jordie0608
|
||||
#Apologies for the boilerplated and squirrely code in parts, this has been my first foray into python
|
||||
#
|
||||
#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
|
||||
#
|
||||
#tgstation no longer supports MySQL which has been superseded by MariaDB, a drop-in replacement.
|
||||
#Before running this script you will need to migrate to MariaDB.
|
||||
#Migrating is very easy to do, for details on how see: https://mariadb.com/kb/en/library/upgrading-from-mysql-to-mariadb/
|
||||
#
|
||||
#You will also have to create a new feedback table for inserting converted data to per the schema:
|
||||
#CREATE TABLE `feedback_new` (
|
||||
# `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
# `datetime` datetime NOT NULL,
|
||||
# `round_id` int(11) unsigned NOT NULL,
|
||||
# `key_name` varchar(32) NOT NULL,
|
||||
# `key_type` enum('text', 'amount', 'tally', 'nested tally', 'associative') NOT NULL,
|
||||
# `version` tinyint(3) unsigned NOT NULL,
|
||||
# `json` json NOT NULL,
|
||||
# PRIMARY KEY (`id`)
|
||||
#) ENGINE=MyISAM
|
||||
#This is to prevent the destruction of legacy 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 feedback 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 feedback_conversion_2017-11-12.py "localhost" "root" "password" "feedback" "SS13_feedback" "SS13_feedback_new"
|
||||
#I found that this script would complete conversion of 10000 rows approximately every 2-3 seconds
|
||||
#Depending on the size of your feedback table and the computer used it may take several minutes for the script to finish
|
||||
#
|
||||
#The script has been tested to complete with tgstation's feedback table as of 2017-10-23 01:34:06
|
||||
#Due to the complexity of data that has potentially changed formats multiple times and suffered errors when recording I cannot guarantee it'll always execute successfully
|
||||
#In the event of an error the new feedback table is automatically truncated
|
||||
#The source table is never modified so you don't have to worry about losing any data due to errors
|
||||
#Note that some feedback keys are renamed or coalesced into one, additionnaly some have been entirely removed
|
||||
#
|
||||
#While this script can be run with your game server(s) active, it may interfere with other database operations and any feedback created after the script has started won't be converted
|
||||
|
||||
import MySQLdb
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
def parse_text(details):
|
||||
if not details:
|
||||
return
|
||||
if details.startswith('"') and details.endswith('"'):
|
||||
details = details[1:-1] #the first and last " aren't removed by splitting the dictionary
|
||||
details = details.split('" | "')
|
||||
else:
|
||||
if "_" in details:
|
||||
details = details.split(' ')
|
||||
return details
|
||||
|
||||
def parse_tally(details):
|
||||
if not details:
|
||||
return
|
||||
overflowed = None
|
||||
if len(details) >= 65535: #a string this long means the data hit the 64KB character limit of TEXT columns
|
||||
overflowed = True
|
||||
if details.startswith('"') and details.endswith('"'):
|
||||
details = details[details.find('"')+1:details.rfind('"')] #unlike others some of the tally data has extra characters to remove
|
||||
split_details = details.split('" | "')
|
||||
else:
|
||||
split_details = details.split(' ')
|
||||
if overflowed:
|
||||
split_details = split_details[:-1] #since the string overflowed the last element will be incomplete and needs to be ignored
|
||||
details = {}
|
||||
for i in split_details:
|
||||
increment = 1
|
||||
if '|' in i and i[i.find('|')+1:]:
|
||||
increment = float(i[i.find('|')+1:])
|
||||
i = i[:i.find('|')]
|
||||
if i in details:
|
||||
details[i] += increment
|
||||
else:
|
||||
details[i] = increment
|
||||
for i in details:
|
||||
details[i] = '{0:g}'.format(details[i]) #remove .0 from floats that have it to conform with DM
|
||||
return details
|
||||
|
||||
def parse_nested(var_name, details):
|
||||
if not details:
|
||||
return
|
||||
#group by data before pipe
|
||||
if var_name in ("admin_toggle", "preferences_verb", "changeling_objective", "cult_objective", "traitor_objective", "wizard_objective", "mining_equipment_bought", "vending_machine_usage", "changeling_powers", "wizard_spell_improved", "testmerged_prs"):
|
||||
if details.startswith('"') and details.endswith('"'):
|
||||
details = details[1:-1]
|
||||
split_details = details.split('" | "')
|
||||
else:
|
||||
split_details = details.split(' ')
|
||||
details = {}
|
||||
for i in split_details:
|
||||
if "|" in i and i[:i.find('|')] not in details:
|
||||
details[i[:i.find('|')]] = {}
|
||||
elif "|" not in i and i[i.find('|')+1:] not in details:
|
||||
details[i[i.find('|')+1:]] = 0
|
||||
for i in split_details:
|
||||
if "|" in i:
|
||||
if details[i[:i.find('|')]] is not dict:
|
||||
continue
|
||||
if i[i.find('|')+1:] in details[i[:i.find('|')]]:
|
||||
details[i[:i.find('|')]][i[i.find('|')+1:]] += 1
|
||||
else:
|
||||
details[i[:i.find('|')]][i[i.find('|')+1:]] = 1
|
||||
else:
|
||||
if i in details and type(details[i]) is not dict: #sometimes keys that should have a value after a pipe just don't and would otherwise error here
|
||||
details[i] += 1
|
||||
return details
|
||||
#group by data after pipe
|
||||
elif var_name in ("cargo_imports", "traitor_uplink_items_bought", "export_sold_cost", "item_used_for_combat", "played_url"):
|
||||
if details.startswith('"') and details.endswith('"'):
|
||||
details = details[1:-1]
|
||||
split_details = details.split('" | "')
|
||||
else:
|
||||
split_details = details.split(' ')
|
||||
details = {}
|
||||
for i in split_details:
|
||||
if i == i[i.rfind('|')+1:]: #there's no pipe and data to group by, so we fill it in
|
||||
i = "{0}|missing data".format(i)
|
||||
details[i[i.rfind('|')+1:]] = {}
|
||||
for i in split_details:
|
||||
if i == i[i.rfind('|')+1:]:
|
||||
i = "{0}|missing data".format(i)
|
||||
if i[:i.find('|')] in details[i[i.rfind('|')+1:]]:
|
||||
details[i[i.rfind('|')+1:]][i[:i.find('|')]] += 1
|
||||
else:
|
||||
details[i[i.rfind('|')+1:]][i[:i.find('|')]] = 1
|
||||
return details
|
||||
elif var_name == "hivelord_core":
|
||||
if details.startswith('"') and details.endswith('"'):
|
||||
details = details[1:-1]
|
||||
split_details = details.split('" | "')
|
||||
else:
|
||||
split_details = details.split(' ')
|
||||
details = {}
|
||||
for i in split_details:
|
||||
if i[:i.find('|')] not in details:
|
||||
details[i[:i.find('|')]] = {}
|
||||
if "used" in i:
|
||||
if "used" not in details:
|
||||
details[i[:i.find('|')]]["used"] = {}
|
||||
for i in split_details:
|
||||
if "used" in i:
|
||||
if "used" not in details[i[:i.find('|')]]:
|
||||
details[i[:i.find('|')]]["used"] = {}
|
||||
details[i[:i.find('|')]]["used"][i[i.rfind('|')+1:]] = 1
|
||||
else:
|
||||
if i[i.rfind('|')+1:] in details[i[:i.find('|')]]["used"]:
|
||||
details[i[:i.find('|')]]["used"][i[i.rfind('|')+1:]] += 1
|
||||
else:
|
||||
details[i[:i.find('|')]]["used"][i[i.rfind('|')+1:]] = 1
|
||||
elif "|" in i:
|
||||
if i[i.find('|')+1:] in details[i[:i.find('|')]]:
|
||||
details[i[:i.find('|')]][i[i.find('|')+1:]] += 1
|
||||
else:
|
||||
details[i[:i.find('|')]][i[i.find('|')+1:]] = 1
|
||||
return details
|
||||
elif var_name == "job_preferences":
|
||||
if details.startswith('"') and details.endswith('"'):
|
||||
details = details[1:-1]
|
||||
split_details = details.split('|-" | "|')
|
||||
else:
|
||||
split_details = details.split('|- |')
|
||||
details = {}
|
||||
for i in split_details:
|
||||
if i.startswith('|'):
|
||||
i = i[1:]
|
||||
if i[:i.find('|')] not in details:
|
||||
details[i[:i.find('|')]] = {}
|
||||
for i in split_details:
|
||||
if i.startswith('|'):
|
||||
i = i[1:]
|
||||
if i.endswith('-'):
|
||||
i = i[:-2]
|
||||
sub_split = i.split('|')
|
||||
job = sub_split[0]
|
||||
sub_split = sub_split[1:]
|
||||
for o in sub_split:
|
||||
details[job][o[:o.find('=')].lower()] = o[o.find('=')+1:]
|
||||
return details
|
||||
|
||||
def parse_associative(var_name, details):
|
||||
if not details:
|
||||
return
|
||||
if var_name == "colonies_dropped":
|
||||
if details.startswith('"') and details.endswith('"'):
|
||||
details = details[1:-1]
|
||||
split_details = details.split('|')
|
||||
details = {}
|
||||
details["1"] = {"x" : split_details[0], "y" : split_details[1], "z" : split_details[2]}
|
||||
return details
|
||||
elif var_name == "commendation":
|
||||
if details.startswith('"') and details.endswith('"'):
|
||||
details = details[1:-1]
|
||||
if '}" | "{' in details:
|
||||
split_details = details.split('}" | "{')
|
||||
else:
|
||||
split_details = details.split('} {')
|
||||
details = {}
|
||||
for i in split_details:
|
||||
params = []
|
||||
sub_split = i.split(',')
|
||||
for o in sub_split:
|
||||
o = re.sub('[^A-Za-z0-9 ]', '', o[o.find(':')+1:]) #remove all the formatting and escaped characters from being pre-encoded as json
|
||||
params.append(o)
|
||||
details[len(details)+1] = {"commender" : params[0], "commendee" : params[1], "medal" : params[2], "reason" : params[3]}
|
||||
return details
|
||||
elif var_name == "high_research_level":
|
||||
if details.startswith('"') and details.endswith('"'):
|
||||
details = details[1:-1]
|
||||
split_details = details.split('" | "')
|
||||
else:
|
||||
split_details = details.split(' ')
|
||||
details = {}
|
||||
levels = {}
|
||||
for i in split_details:
|
||||
x = {i[:-1] : i[-1:]}
|
||||
levels.update(x)
|
||||
details["1"] = levels
|
||||
return details
|
||||
|
||||
def parse_special(var_name, var_value, details):
|
||||
#old data is essentially a tally in text form
|
||||
if var_name == "immortality_talisman":
|
||||
if details.startswith('"') and details.endswith('"'):
|
||||
split_details = details.split('" | "')
|
||||
else:
|
||||
split_details = details.split(' ')
|
||||
return len(split_details)
|
||||
#now records channel names, so we have to fill in whats missing
|
||||
elif var_name == "newscaster_channels":
|
||||
details = ["missing data"]
|
||||
details *= var_value
|
||||
return details
|
||||
#all the channels got renamed, plus we ignore any with an amount of zero
|
||||
elif var_name == "radio_usage":
|
||||
if details.startswith('"') and details.endswith('"'):
|
||||
details = details[details.find('C'):-1]
|
||||
split_details = details.split('" | "')
|
||||
else:
|
||||
split_details = details.split(' ')
|
||||
details = {}
|
||||
new_keys = {"COM":"common", "SCI":"science", "HEA":"command", "MED":"medical", "ENG":"engineering", "SEC":"security", "DTH":"centcom", "SYN":"syndicate", "SRV":"service", "CAR":"supply", "OTH":"other", "PDA":"PDA", "RC":"request console"}
|
||||
for i in split_details:
|
||||
if i.endswith('0'):
|
||||
continue
|
||||
if i[:i.find('-')] not in new_keys:
|
||||
continue
|
||||
details[new_keys[i[:i.find('-')]]] = i[i.find('-')+1:]
|
||||
return details
|
||||
#all of the data tracked by this is invalid due to recording the incorrect type
|
||||
elif var_name == "shuttle_gib":
|
||||
return {"missing data":1}
|
||||
#all records have a prefix of 'slimebirth_' that needs to be removed
|
||||
elif var_name == "slime_babies_born":
|
||||
if details.startswith('"') and details.endswith('"'):
|
||||
details = details[1:-1]
|
||||
split_details = details.split('" | "')
|
||||
else:
|
||||
split_details = details.split(' ')
|
||||
details = {}
|
||||
for i in split_details:
|
||||
if i[i.find('_')+1:].replace('_', ' ') in details:
|
||||
details[i[i.find('_')+1:].replace('_', ' ')] += 1
|
||||
else:
|
||||
details[i[i.find('_')+1:].replace('_', ' ')] = 1
|
||||
return details
|
||||
#spaces were replaced by underscores, we need to undo this
|
||||
elif var_name == "slime_core_harvested":
|
||||
if details.startswith('"') and details.endswith('"'):
|
||||
details = details[1:-1]
|
||||
split_details = details.split('" | "')
|
||||
else:
|
||||
split_details = details.split(' ')
|
||||
details = {}
|
||||
for i in split_details:
|
||||
if i.replace('_', ' ') in details:
|
||||
details[i.replace('_', ' ')] += 1
|
||||
else:
|
||||
details[i.replace('_', ' ')] = 1
|
||||
return details
|
||||
|
||||
def parse_multirow(var_name, var_value, details, multirows_completed):
|
||||
if var_name in ("ahelp_close", "ahelp_icissue", "ahelp_reject", "ahelp_reopen", "ahelp_resolve", "ahelp_unresolved"):
|
||||
ahelp_vars = {"ahelp_close":"closed", "ahelp_icissue":"IC", "ahelp_reject":"rejected", "ahelp_reopen":"reopened", "ahelp_resolve":"resolved", "ahelp_unresolved":"unresolved"}
|
||||
details = {ahelp_vars[var_name]:var_value}
|
||||
del ahelp_vars[var_name]
|
||||
query_where = "round_id = {0} AND (".format(query_row[2])
|
||||
for c, i in enumerate(ahelp_vars):
|
||||
if c:
|
||||
query_where += " OR "
|
||||
query_where += "var_name = \"{0}\"".format(i)
|
||||
query_where += ")"
|
||||
cursor.execute("SELECT var_name, var_value FROM {0} WHERE {1}".format(current_table, query_where))
|
||||
rows = cursor.fetchall()
|
||||
if rows:
|
||||
for r in rows:
|
||||
details[ahelp_vars[r[0]]] = r[1]
|
||||
keys = list(ahelp_vars.keys())
|
||||
keys.append(var_name)
|
||||
multirows_completed += keys
|
||||
return details
|
||||
elif var_name in ("alert_comms_blue", "alert_comms_green"):
|
||||
level_vars = {"alert_comms_blue":"1", "alert_comms_green":"0"}
|
||||
details = {level_vars[var_name]:var_value}
|
||||
del level_vars[var_name]
|
||||
i = list(level_vars)[0]
|
||||
cursor.execute("SELECT var_value FROM {0} WHERE round_id = {1} AND var_name = \"{2}\"".format(current_table, query_row[2], i))
|
||||
row = cursor.fetchone()
|
||||
if row:
|
||||
details[level_vars[i]] = row[0]
|
||||
keys = list(level_vars.keys())
|
||||
keys.append(var_name)
|
||||
multirows_completed += keys
|
||||
return details
|
||||
elif var_name in ("alert_keycard_auth_bsa", "alert_keycard_auth_maint"):
|
||||
auth_vars = {"alert_keycard_auth_maint":("emergency maintenance access", "enabled"), "alert_keycard_auth_bsa":("bluespace artillery", "unlocked")}
|
||||
i = list(auth_vars[var_name])
|
||||
details = {i[0]:{i[1]:var_value}}
|
||||
del auth_vars[var_name]
|
||||
i = list(auth_vars)[0]
|
||||
cursor.execute("SELECT var_value FROM {0} WHERE round_id = {1} AND var_name = \"{2}\"".format(current_table, query_row[2], i))
|
||||
row = cursor.fetchone()
|
||||
if row:
|
||||
o = list(auth_vars[i])
|
||||
details[o[0]] = {o[1]:row[0]}
|
||||
keys = list(auth_vars.keys())
|
||||
keys.append(var_name)
|
||||
multirows_completed += keys
|
||||
return details
|
||||
elif var_name in ("arcade_loss_hp_emagged", "arcade_loss_hp_normal", "arcade_loss_mana_emagged", "arcade_loss_mana_normal", "arcade_win_emagged", "arcade_win_normal"):
|
||||
result_vars = {"arcade_loss_hp_emagged":("loss", "hp", "emagged"), "arcade_loss_hp_normal":("loss", "hp", "normal"), "arcade_loss_mana_emagged":("loss", "mana", "emagged"), "arcade_loss_mana_normal":("loss", "mana", "normal"), "arcade_win_emagged":("win", "emagged"), "arcade_win_normal":("win", "normal")}
|
||||
i = list(result_vars[var_name])
|
||||
del result_vars[var_name]
|
||||
if i[0] == "loss":
|
||||
details = {i[0]:{i[1]:{i[2]:var_value}}}
|
||||
else:
|
||||
details = {i[0]:{i[1]:var_value}}
|
||||
query_where = "round_id = {0} AND (".format(query_row[2])
|
||||
for c, i in enumerate(result_vars):
|
||||
if c:
|
||||
query_where += " OR "
|
||||
query_where += "var_name = \"{0}\"".format(i)
|
||||
query_where += ")"
|
||||
cursor.execute("SELECT var_name, var_value FROM {0} WHERE {1}".format(current_table, query_where))
|
||||
rows = cursor.fetchall()
|
||||
if rows:
|
||||
for r in rows:
|
||||
i = list(result_vars[r[0]])
|
||||
if i[0] not in details:
|
||||
details[i[0]] = {}
|
||||
if i[0] == "loss":
|
||||
if i[1] not in details[i[0]]:
|
||||
details[i[0]][i[1]] = {}
|
||||
details[i[0]][i[1]][i[2]] = r[1]
|
||||
else:
|
||||
details[i[0]][i[1]] = r[1]
|
||||
keys = list(result_vars.keys())
|
||||
keys.append(var_name)
|
||||
multirows_completed += keys
|
||||
return details
|
||||
elif var_name in ("cyborg_engineering", "cyborg_janitor", "cyborg_medical", "cyborg_miner", "cyborg_peacekeeper", "cyborg_security", "cyborg_service", "cyborg_standard"):
|
||||
module_vars = {"cyborg_engineering":"Engineering", "cyborg_janitor":"Janitor", "cyborg_medical":"Medical", "cyborg_miner":"Miner", "cyborg_peacekeeper":"Peacekeeper", "cyborg_security":"Security", "cyborg_service":"Service", "cyborg_standard":"Standard"}
|
||||
details = {module_vars[var_name]:var_value}
|
||||
del module_vars[var_name]
|
||||
query_where = "round_id = {0} AND (".format(query_row[2])
|
||||
for c, i in enumerate(module_vars):
|
||||
if c:
|
||||
query_where += " OR "
|
||||
query_where += "var_name = \"{0}\"".format(i)
|
||||
query_where += ")"
|
||||
cursor.execute("SELECT var_name, var_value FROM {0} WHERE {1}".format(current_table, query_where))
|
||||
rows = cursor.fetchall()
|
||||
if rows:
|
||||
for r in rows:
|
||||
details[module_vars[r[0]]] = r[1]
|
||||
keys = list(module_vars.keys())
|
||||
keys.append(var_name)
|
||||
multirows_completed += keys
|
||||
return details
|
||||
elif var_name in ("escaped_human", "escaped_total", "round_end_clients", "round_end_ghosts", "survived_human", "survived_total"):
|
||||
round_vars = {"escaped_human":("escapees", "human"), "escaped_total":("escapees", "total"), "round_end_clients":("clients"), "round_end_ghosts":("ghosts"), "survived_human":("survivors", "human"), "survived_total":("survivors", "total")}
|
||||
if var_name in ("round_end_clients", "round_end_ghosts"):
|
||||
i = round_vars[var_name]
|
||||
details = {i:var_value}
|
||||
else:
|
||||
i = list(round_vars[var_name])
|
||||
details = {i[0]:{i[1]:var_value}}
|
||||
del round_vars[var_name]
|
||||
query_where = "round_id = {0} AND (".format(query_row[2])
|
||||
for c, i in enumerate(round_vars):
|
||||
if c:
|
||||
query_where += " OR "
|
||||
query_where += "var_name = \"{0}\"".format(i)
|
||||
query_where += ")"
|
||||
cursor.execute("SELECT var_name, var_value FROM {0} WHERE {1}".format(current_table, query_where))
|
||||
rows = cursor.fetchall()
|
||||
if rows:
|
||||
for r in rows:
|
||||
if r[0] in ("round_end_clients", "round_end_ghosts"):
|
||||
i = round_vars[r[0]]
|
||||
details[i] = r[1]
|
||||
else:
|
||||
i = list(round_vars[r[0]])
|
||||
if i[0] not in details:
|
||||
details[i[0]] = {}
|
||||
details[i[0]][i[1]] = r[1]
|
||||
keys = list(round_vars.keys())
|
||||
keys.append(var_name)
|
||||
multirows_completed += keys
|
||||
return details
|
||||
elif var_name in ("mecha_durand_created", "mecha_firefighter_created", "mecha_gygax_created", "mecha_honker_created", "mecha_odysseus_created", "mecha_phazon_created", "mecha_ripley_created"):
|
||||
mecha_vars ={"mecha_durand_created":"Durand", "mecha_firefighter_created":"APLU \"Firefighter\"", "mecha_gygax_created":"Gygax", "mecha_honker_created":"H.O.N.K", "mecha_odysseus_created":"Odysseus", "mecha_phazon_created":"Phazon", "mecha_ripley_created":"APLU \"Ripley\""}
|
||||
details = {mecha_vars[var_name]:var_value}
|
||||
del mecha_vars[var_name]
|
||||
query_where = "round_id = {0} AND (".format(query_row[2])
|
||||
for c, i in enumerate(mecha_vars):
|
||||
if c:
|
||||
query_where += " OR "
|
||||
query_where += "var_name = \"{0}\"".format(i)
|
||||
query_where += ")"
|
||||
cursor.execute("SELECT var_name, var_value FROM {0} WHERE {1}".format(current_table, query_where))
|
||||
rows = cursor.fetchall()
|
||||
if rows:
|
||||
for r in rows:
|
||||
details[mecha_vars[r[0]]] = r[1]
|
||||
keys = list(mecha_vars.keys())
|
||||
keys.append(var_name)
|
||||
multirows_completed += keys
|
||||
return details
|
||||
|
||||
def pick_parsing(var_name, var_value, details, multirows_completed):
|
||||
if var_name in text_keys:
|
||||
return parse_text(details)
|
||||
elif var_name in amount_keys:
|
||||
return var_value
|
||||
elif var_name in simple_tallies:
|
||||
return parse_tally(details)
|
||||
elif var_name in nested_tallies:
|
||||
return parse_nested(var_name, details)
|
||||
elif var_name in associatives:
|
||||
return parse_associative(var_name, details)
|
||||
elif var_name in special_cases:
|
||||
return parse_special(var_name, var_value, details)
|
||||
elif var_name in multirow:
|
||||
return parse_multirow(var_name, var_value, details, multirows_completed)
|
||||
else:
|
||||
return False
|
||||
|
||||
if sys.version_info[0] < 3:
|
||||
raise Exception("Python must be at least version 3 for this script.")
|
||||
text_keys = ["religion_book", "religion_deity", "religion_name", "shuttle_fasttravel", "shuttle_manipulator", "shuttle_purchase", "shuttle_reason", "station_renames"]
|
||||
amount_keys = ["admin_cookies_spawned", "cyborg_ais_created", "cyborg_frames_built", "cyborg_mmis_filled", "newscaster_newspapers_printed", "newscaster_stories", "nuclear_challenge_mode"]
|
||||
simple_tallies = ["admin_secrets_fun_used", "admin_verb", "assembly_made", "brother_success", "cell_used", "changeling_power_purchase", "changeling_success", "chaplain_weapon", "chemical_reaction", "circuit_printed", "clockcult_scripture_recited", "contamination", "cult_runes_scribed", "engine_started", "event_admin_cancelled", "event_ran", "food_harvested", "food_made", "gun_fired", "handcuffs", "item_deconstructed", "item_printed", "jaunter", "lazarus_injector", "megafauna_kills", "mining_voucher_redeemed", "mobs_killed_mining", "object_crafted", "ore_mined", "pick_used_mining", "slime_cores_used", "surgeries_completed", "time_dilation_current", "traitor_random_uplink_items_gotten", "traitor_success", "voice_of_god", "warp_cube", "wisp_lantern", "wizard_spell_learned", "wizard_success", "zone_targeted"]
|
||||
nested_tallies = ["admin_toggle", "cargo_imports", "changeling_objective", "changeling_powers", "cult_objective", "export_sold_cost", "hivelord_core", "item_used_for_combat", "job_preferences", "mining_equipment_bought", "played_url", "preferences_verb", "testmerged_prs", "traitor_objective", "traitor_uplink_items_bought", "vending_machine_usage", "wizard_objective", "wizard_spell_improved"]
|
||||
associatives = ["colonies_dropped", "commendation", "high_research_level"]
|
||||
special_cases = ["immortality_talisman", "newscaster_channels", "radio_usage", "shuttle_gib", "slime_babies_born", "slime_core_harvested"]
|
||||
multirow = ["ahelp_close", "ahelp_icissue", "ahelp_reject", "ahelp_reopen", "ahelp_resolve", "ahelp_unresolved", "alert_comms_blue", "alert_comms_green", "alert_keycard_auth_bsa", "alert_keycard_auth_maint", "arcade_loss_hp_emagged", "arcade_loss_hp_normal", "arcade_loss_mana_emagged", "arcade_loss_mana_normal", "arcade_win_emagged", "arcade_win_normal", "cyborg_engineering", "cyborg_janitor", "cyborg_medical", "cyborg_miner", "cyborg_peacekeeper", "cyborg_security", "cyborg_service", "cyborg_standard", "escaped_human", "escaped_total", "mecha_durand_created", "mecha_firefighter_created", "mecha_gygax_created", "mecha_honker_created", "mecha_odysseus_created", "mecha_phazon_created", "mecha_ripley_created", "round_end_clients", "round_end_ghosts", "survived_human", "survived_total"]
|
||||
renames = {"ahelp_stats":["ahelp_close", "ahelp_icissue", "ahelp_reject", "ahelp_reopen", "ahelp_resolve", "ahelp_unresolved"], "ais_created":["cyborg_ais_created"], "arcade_results":["arcade_loss_hp_emagged", "arcade_loss_hp_normal", "arcade_loss_mana_emagged", "arcade_loss_mana_normal", "arcade_win_emagged", "arcade_win_normal"], "cyborg_modules":["cyborg_engineering", "cyborg_janitor", "cyborg_medical", "cyborg_miner", "cyborg_peacekeeper", "cyborg_security", "cyborg_service", "cyborg_standard"], "immortality_talisman_uses":["immortality_talisman"], "keycard_auths":["alert_keycard_auth_bsa", "alert_keycard_auth_maint"], "mechas_created":["mecha_durand_created", "mecha_firefighter_created", "mecha_gygax_created", "mecha_honker_created", "mecha_odysseus_created", "mecha_phazon_created", "mecha_ripley_created"], "mmis_filled":["cyborg_mmis_filled"], "newspapers_printed":["newscaster_newspapers_printed"], "round_end_stats":["escaped_human", "escaped_total", "round_end_clients", "round_end_ghosts", "survived_human", "survived_total"], "security_level_changes":["alert_comms_blue", "alert_comms_green"]}
|
||||
key_types = {"amount":["ais_created", "immortality_talisman_uses", "mmis_filled", "newspapers_printed", "admin_cookies_spawned", "cyborg_frames_built", "newscaster_stories", "nuclear_challenge_mode"],
|
||||
"associative":["colonies_dropped", "commendation", "high_research_level"],
|
||||
"nested tally":["admin_toggle", "arcade_results", "cargo_imports", "changeling_objective", "changeling_powers", "cult_objective", "export_sold_cost", "hivelord_core", "item_used_for_combat", "job_preferences", "keycard_auths", "mining_equipment_bought", "played_url", "preferences_verb", "round_end_stats", "testmerged_prs", "traitor_objective", "traitor_uplink_items_bought", "vending_machine_usage", "wizard_objective", "wizard_spell_improved"],
|
||||
"tally":[ "admin_secrets_fun_used", "admin_verb", "ahelp_stats", "assembly_made", "brother_success", "cell_used", "changeling_power_purchase", "changeling_success", "chaplain_weapon", "chemical_reaction", "circuit_printed", "clockcult_scripture_recited", "contamination", "cult_runes_scribed", "cyborg_modules", "engine_started", "event_admin_cancelled", "event_ran", "food_harvested", "food_made", "gun_fired", "handcuffs", "item_deconstructed", "item_printed", "jaunter", "lazarus_injector", "mechas_created", "megafauna_kills", "mining_voucher_redeemed", "mobs_killed_mining", "object_crafted", "ore_mined", "pick_used_mining", "radio_usage", "security_level_changes", "shuttle_gib", "slime_babies_born", "slime_cores_used", "slime_core_harvested", "surgeries_completed", "time_dilation_current", "traitor_random_uplink_items_gotten", "traitor_success", "voice_of_god", "warp_cube", "wisp_lantern", "wizard_spell_learned", "wizard_success", "zone_targeted"],
|
||||
"text":["shuttle_fasttravel", "shuttle_manipulator", "shuttle_purchase", "shuttle_reason", "newscaster_channels", "religion_book", "religion_deity", "religion_name", "station_renames"]}
|
||||
multirows_completed = []
|
||||
query_values = ""
|
||||
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 feedback 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()
|
||||
cursor.execute("SELECT @@GLOBAL.version_comment")
|
||||
db_version = "".join([x for x in cursor.fetchone()])
|
||||
database_mysql = False
|
||||
if 'MySQL' in db_version:
|
||||
database_mysql = True
|
||||
elif 'mariadb' not in db_version:
|
||||
choice = input("Unable to determine database version installed, are you using MySQL? Type Yes or No and press enter...").lower()
|
||||
if choice == "yes":
|
||||
database_mysql = True
|
||||
if database_mysql == True:
|
||||
print("WARNING Database detected to be MySQL: tgstation no longer supports MySQL which has been superseded by MariaDB, a drop-in replacement.\nBefore running this script you will need to migrate to MariaDB.\nMigrating is very easy to do, for details on how see: https://mariadb.com/kb/en/library/upgrading-from-mysql-to-mariadb/")
|
||||
input("Press enter to quit...")
|
||||
quit()
|
||||
current_table = args.curtable
|
||||
new_table = args.newtable
|
||||
cursor.execute("SELECT max(id), max(round_id) FROM {0}".format(current_table))
|
||||
query_id = cursor.fetchone()
|
||||
max_id = query_id[0]
|
||||
max_round_id = query_id[1]
|
||||
start_time = datetime.now()
|
||||
print("Beginning conversion at {0}".format(start_time.strftime("%Y-%m-%d %H:%M:%S")))
|
||||
try:
|
||||
for current_id in range(max_id):
|
||||
if current_id % 10000 == 0:
|
||||
cur_time = datetime.now()
|
||||
print("Reached row ID {0} Duration: {1}".format(current_id, cur_time - start_time))
|
||||
cursor.execute("SELECT * FROM {0} WHERE id = {1}".format(current_table, current_id))
|
||||
query_row = cursor.fetchone()
|
||||
if not query_row:
|
||||
continue
|
||||
else:
|
||||
if current_round != query_row[2] or current_round == max_round_id:
|
||||
multirows_completed.clear()
|
||||
if query_values:
|
||||
query_values = query_values[:-1]
|
||||
query_values += ';'
|
||||
cursor.execute("INSERT INTO {0} (datetime, round_id, key_name, key_type, version, json) VALUES {1}".format(new_table, query_values))
|
||||
query_values = ""
|
||||
current_round = query_row[2]
|
||||
if query_row[3] in multirows_completed:
|
||||
continue
|
||||
parsed_data = pick_parsing(query_row[3], query_row[4], query_row[5], multirows_completed)
|
||||
if not parsed_data:
|
||||
continue
|
||||
json_data = {}
|
||||
json_data["data"] = parsed_data
|
||||
new_key = query_row[3]
|
||||
for r in renames:
|
||||
if new_key in renames[r]:
|
||||
new_key = r
|
||||
break
|
||||
new_key_type = None
|
||||
for t in key_types:
|
||||
if new_key in key_types[t]:
|
||||
new_key_type = t
|
||||
break
|
||||
dequoted_json = re.sub("\'", "\\'", json.dumps(json_data))
|
||||
query_values += "('{0}',{1},'{2}','{3}',{4},'{5}'),".format(query_row[1], query_row[2], new_key, new_key_type, 1, dequoted_json)
|
||||
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:
|
||||
cursor.execute("SELECT round_id FROM {0} WHERE id = {1}".format(current_table, current_id-1))
|
||||
query_round_id = cursor.fetchone()
|
||||
end_time = datetime.now()
|
||||
print("Error encountered on row ID {0} at {1}".format(current_id, datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
|
||||
print("Note SQL insertion errors will be due to data from round ID {0}".format(query_round_id[0])) #since data is inserted when the round id changes on a new row
|
||||
print("Script duration: {0}".format(end_time - start_time))
|
||||
cursor.execute("TRUNCATE {0} ".format(new_table))
|
||||
raise e
|
||||
cursor.close()
|
||||
Binary file not shown.
@@ -0,0 +1,96 @@
|
||||
-- --------------------------------------------------------
|
||||
-- Host: 127.0.0.1
|
||||
-- Server version: 10.4.7-MariaDB - mariadb.org binary distribution
|
||||
-- Server OS: Win64
|
||||
-- HeidiSQL Version: 10.2.0.5599
|
||||
-- --------------------------------------------------------
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
/*!50503 SET NAMES utf8mb4 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
@@ -0,0 +1,14 @@
|
||||
CREATE TABLE `mentor_memo` (
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`memotext` text NOT NULL,
|
||||
`timestamp` datetime NOT NULL,
|
||||
`last_editor` varchar(32) DEFAULT NULL,
|
||||
`edits` text,
|
||||
PRIMARY KEY (`ckey`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE `mentor` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
It is recommended you do not perfom any of these queries while your server is live as they will lock the tables during execution.
|
||||
|
||||
Backup your database before starting; Breaking errors may occur when old data is not be compatible with new column formats.
|
||||
i.e. A field that is null or empty due to rows existing before the column was added, data corruption or incorrect inputs will prevent altering the column to be NOT NULL.
|
||||
To account where this is likely to occur, these queries check if fields have valid data and if not will replace invalid data with 0.
|
||||
Some fields may be out of range for new column lengths, this will also cause a breaking error.
|
||||
For instance `death`.`bruteloss` is now SMALLINT and won't accept any values over 65535.
|
||||
Data in this table can thus be truncated using a query such as:
|
||||
UPDATE `[database]`.`[table]` SET `[column]` = LEAST(`[column]`, [max column size])
|
||||
To truncate a text field you would have to use SUBSTRING(), however I don't suggest you truncate any text fields.
|
||||
If you wish to instead preserve this data you will need to modify the schema and queries to accomodate.
|
||||
|
||||
Additionally, you may encounter the error "Error Code: 1411. Incorrect string value: '[query]' for function inet_aton".
|
||||
This is due to a bug with the default sql_mode in MySQL version 5.7, wherein a value of '' cannot be passed to INET_ATON() without error, see here for reference: https://bugs.mysql.com/bug.php?id=82280
|
||||
The INET_ATON() function inteprets any abnormal data as being '', examples are:
|
||||
' 127.0.0.1' - contains a whitespace character such as space, tab or newline.
|
||||
'127.a.$,1' - contains non-numeric characters
|
||||
'300.0.0.1' - ipv4 octets must be within a range of 0 to 255
|
||||
Note that '127.0.1' and '127.0..1' are both valid data formats but will not equate to the correct ip address.
|
||||
|
||||
If you get this error there are steps you can take to deal with the invalid data:
|
||||
To get a list of all unique fields that aren't valid ipv4 addresses, run the query:
|
||||
SELECT DISTINCT [column] FROM [table] WHERE [column] NOT REGEXP '^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
|
||||
Note this will only retrieve the first 1000 results, if you want more append to the query:
|
||||
LIMIT 0, [max result]
|
||||
Now inspect your results for any data that is invalid and correct them.
|
||||
If you prefer, you can also automatically replace invalid data with 0 using a similar query:
|
||||
UPDATE [table] SET [column] = '0' WHERE [column] NOT REGEXP '^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
|
||||
This will replace all invalid data, even data that could potentially be corrected.
|
||||
Finally, per the bug report, you can have MySQL ignore the errors and instead produce warnings while continuing with the query.
|
||||
To do so, run the query:
|
||||
SET @@sql_mode=''
|
||||
Do not use this method unless you are sure about it; This setting will persist until your MySQL server is restarted, potentially affecting the data integrity of this and future queries.
|
||||
|
||||
Take note some columns have been renamed, removed or changed type. Any services relying on these columns will have to be updated per changes.
|
||||
|
||||
----------------------------------------------------*/
|
||||
|
||||
START TRANSACTION;
|
||||
ALTER TABLE `ban`
|
||||
DROP COLUMN `rounds`
|
||||
, CHANGE COLUMN `bantype` `bantype` ENUM('PERMABAN', 'TEMPBAN', 'JOB_PERMABAN', 'JOB_TEMPBAN', 'ADMIN_PERMABAN', 'ADMIN_TEMPBAN') NOT NULL
|
||||
, CHANGE COLUMN `reason` `reason` VARCHAR(2048) NOT NULL
|
||||
, CHANGE COLUMN `who` `who` VARCHAR(2048) NOT NULL
|
||||
, CHANGE COLUMN `adminwho` `adminwho` VARCHAR(2048) NOT NULL
|
||||
, CHANGE COLUMN `unbanned` `unbanned` TINYINT UNSIGNED NULL DEFAULT NULL
|
||||
, ADD COLUMN `server_ip` INT UNSIGNED NOT NULL AFTER `serverip`
|
||||
, ADD COLUMN `server_port` SMALLINT UNSIGNED NOT NULL AFTER `server_ip`
|
||||
, ADD COLUMN `ipTEMP` INT UNSIGNED NOT NULL AFTER `ip`
|
||||
, ADD COLUMN `a_ipTEMP` INT UNSIGNED NOT NULL AFTER `a_ip`
|
||||
, ADD COLUMN `unbanned_ipTEMP` INT UNSIGNED NULL DEFAULT NULL AFTER `unbanned_ip`;
|
||||
SET SQL_SAFE_UPDATES = 0;
|
||||
UPDATE `ban`
|
||||
SET `server_ip` = INET_ATON(SUBSTRING_INDEX(IF(`serverip` = '', '0', IF(SUBSTRING_INDEX(`serverip`, ':', 1) LIKE '%_._%', `serverip`, '0')), ':', 1))
|
||||
, `server_port` = IF(`serverip` LIKE '%:_%', CAST(SUBSTRING_INDEX(`serverip`, ':', -1) AS UNSIGNED), '0')
|
||||
, `ipTEMP` = INET_ATON(IF(`ip` LIKE '%_._%', `ip`, '0'))
|
||||
, `a_ipTEMP` = INET_ATON(IF(`a_ip` LIKE '%_._%', `a_ip`, '0'))
|
||||
, `unbanned_ipTEMP` = INET_ATON(IF(`unbanned_ip` LIKE '%_._%', `unbanned_ip`, '0'));
|
||||
SET SQL_SAFE_UPDATES = 1;
|
||||
ALTER TABLE `ban`
|
||||
DROP COLUMN `unbanned_ip`
|
||||
, DROP COLUMN `a_ip`
|
||||
, DROP COLUMN `ip`
|
||||
, DROP COLUMN `serverip`
|
||||
, CHANGE COLUMN `ipTEMP` `ip` INT(10) UNSIGNED NOT NULL
|
||||
, CHANGE COLUMN `a_ipTEMP` `a_ip` INT(10) UNSIGNED NOT NULL
|
||||
, CHANGE COLUMN `unbanned_ipTEMP` `unbanned_ip` INT(10) UNSIGNED NULL DEFAULT NULL;
|
||||
COMMIT;
|
||||
|
||||
START TRANSACTION;
|
||||
ALTER TABLE `connection_log`
|
||||
ADD COLUMN `server_ip` INT UNSIGNED NOT NULL AFTER `serverip`
|
||||
, ADD COLUMN `server_port` SMALLINT UNSIGNED NOT NULL AFTER `server_ip`
|
||||
, ADD COLUMN `ipTEMP` INT UNSIGNED NOT NULL AFTER `ip`;
|
||||
SET SQL_SAFE_UPDATES = 0;
|
||||
UPDATE `connection_log`
|
||||
SET `server_ip` = INET_ATON(SUBSTRING_INDEX(IF(`serverip` = '', '0', IF(SUBSTRING_INDEX(`serverip`, ':', 1) LIKE '%_._%', `serverip`, '0')), ':', 1))
|
||||
, `server_port` = IF(`serverip` LIKE '%:_%', CAST(SUBSTRING_INDEX(`serverip`, ':', -1) AS UNSIGNED), '0')
|
||||
, `ipTEMP` = INET_ATON(IF(`ip` LIKE '%_._%', `ip`, '0'));
|
||||
SET SQL_SAFE_UPDATES = 1;
|
||||
ALTER TABLE `connection_log`
|
||||
DROP COLUMN `ip`
|
||||
, DROP COLUMN `serverip`
|
||||
, CHANGE COLUMN `ipTEMP` `ip` INT(10) UNSIGNED NOT NULL;
|
||||
COMMIT;
|
||||
|
||||
START TRANSACTION;
|
||||
SET SQL_SAFE_UPDATES = 0;
|
||||
UPDATE `death`
|
||||
SET `bruteloss` = LEAST(`bruteloss`, 65535)
|
||||
, `brainloss` = LEAST(`brainloss`, 65535)
|
||||
, `fireloss` = LEAST(`fireloss`, 65535)
|
||||
, `oxyloss` = LEAST(`oxyloss`, 65535);
|
||||
ALTER TABLE `death`
|
||||
CHANGE COLUMN `pod` `pod` VARCHAR(50) NOT NULL
|
||||
, CHANGE COLUMN `coord` `coord` VARCHAR(32) NOT NULL
|
||||
, CHANGE COLUMN `mapname` `mapname` VARCHAR(32) NOT NULL
|
||||
, CHANGE COLUMN `job` `job` VARCHAR(32) NOT NULL
|
||||
, CHANGE COLUMN `special` `special` VARCHAR(32) NULL DEFAULT NULL
|
||||
, CHANGE COLUMN `name` `name` VARCHAR(96) NOT NULL
|
||||
, CHANGE COLUMN `byondkey` `byondkey` VARCHAR(32) NOT NULL
|
||||
, CHANGE COLUMN `laname` `laname` VARCHAR(96) NULL DEFAULT NULL
|
||||
, CHANGE COLUMN `lakey` `lakey` VARCHAR(32) NULL DEFAULT NULL
|
||||
, CHANGE COLUMN `gender` `gender` ENUM('neuter', 'male', 'female', 'plural') NOT NULL
|
||||
, CHANGE COLUMN `bruteloss` `bruteloss` SMALLINT UNSIGNED NOT NULL
|
||||
, CHANGE COLUMN `brainloss` `brainloss` SMALLINT UNSIGNED NOT NULL
|
||||
, CHANGE COLUMN `fireloss` `fireloss` SMALLINT UNSIGNED NOT NULL
|
||||
, CHANGE COLUMN `oxyloss` `oxyloss` SMALLINT UNSIGNED NOT NULL
|
||||
, ADD COLUMN `server_ip` INT UNSIGNED NOT NULL AFTER `server`
|
||||
, ADD COLUMN `server_port` SMALLINT UNSIGNED NOT NULL AFTER `server_ip`;
|
||||
UPDATE `death`
|
||||
SET `server_ip` = INET_ATON(SUBSTRING_INDEX(IF(`server` = '', '0', IF(SUBSTRING_INDEX(`server`, ':', 1) LIKE '%_._%', `server`, '0')), ':', 1))
|
||||
, `server_port` = IF(`server` LIKE '%:_%', CAST(SUBSTRING_INDEX(`server`, ':', -1) AS UNSIGNED), '0');
|
||||
SET SQL_SAFE_UPDATES = 1;
|
||||
ALTER TABLE `death`
|
||||
DROP COLUMN `server`;
|
||||
COMMIT;
|
||||
|
||||
ALTER TABLE `library`
|
||||
CHANGE COLUMN `category` `category` ENUM('Any', 'Fiction', 'Non-Fiction', 'Adult', 'Reference', 'Religion') NOT NULL
|
||||
, CHANGE COLUMN `ckey` `ckey` VARCHAR(32) NOT NULL DEFAULT 'LEGACY'
|
||||
, CHANGE COLUMN `datetime` `datetime` DATETIME NOT NULL
|
||||
, CHANGE COLUMN `deleted` `deleted` TINYINT(1) UNSIGNED NULL DEFAULT NULL;
|
||||
|
||||
ALTER TABLE `messages`
|
||||
CHANGE COLUMN `type` `type` ENUM('memo', 'message', 'message sent', 'note', 'watchlist entry') NOT NULL
|
||||
, CHANGE COLUMN `text` `text` VARCHAR(2048) NOT NULL
|
||||
, CHANGE COLUMN `secret` `secret` TINYINT(1) UNSIGNED NOT NULL;
|
||||
|
||||
START TRANSACTION;
|
||||
ALTER TABLE `player`
|
||||
ADD COLUMN `ipTEMP` INT UNSIGNED NOT NULL AFTER `ip`;
|
||||
SET SQL_SAFE_UPDATES = 0;
|
||||
UPDATE `player`
|
||||
SET `ipTEMP` = INET_ATON(IF(`ip` LIKE '%_._%', `ip`, '0'));
|
||||
SET SQL_SAFE_UPDATES = 1;
|
||||
ALTER TABLE `player`
|
||||
DROP COLUMN `ip`
|
||||
, CHANGE COLUMN `ipTEMP` `ip` INT(10) UNSIGNED NOT NULL;
|
||||
COMMIT;
|
||||
|
||||
START TRANSACTION;
|
||||
ALTER TABLE `poll_question`
|
||||
CHANGE COLUMN `polltype` `polltype` ENUM('OPTION', 'TEXT', 'NUMVAL', 'MULTICHOICE', 'IRV') NOT NULL
|
||||
, CHANGE COLUMN `adminonly` `adminonly` TINYINT(1) UNSIGNED NOT NULL
|
||||
, CHANGE COLUMN `createdby_ckey` `createdby_ckey` VARCHAR(32) NULL DEFAULT NULL
|
||||
, CHANGE COLUMN `dontshow` `dontshow` TINYINT(1) UNSIGNED NOT NULL
|
||||
, ADD COLUMN `createdby_ipTEMP` INT UNSIGNED NOT NULL AFTER `createdby_ip`
|
||||
, DROP COLUMN `for_trialmin`;
|
||||
SET SQL_SAFE_UPDATES = 0;
|
||||
UPDATE `poll_question`
|
||||
SET `createdby_ipTEMP` = INET_ATON(IF(`createdby_ip` LIKE '%_._%', `createdby_ip`, '0'));
|
||||
SET SQL_SAFE_UPDATES = 1;
|
||||
ALTER TABLE `poll_question`
|
||||
DROP COLUMN `createdby_ip`
|
||||
, CHANGE COLUMN `createdby_ipTEMP` `createdby_ip` INT(10) UNSIGNED NOT NULL;
|
||||
COMMIT;
|
||||
|
||||
START TRANSACTION;
|
||||
ALTER TABLE `poll_textreply`
|
||||
CHANGE COLUMN `replytext` `replytext` VARCHAR(2048) NOT NULL
|
||||
, ADD COLUMN `ipTEMP` INT UNSIGNED NOT NULL AFTER `ip`;
|
||||
SET SQL_SAFE_UPDATES = 0;
|
||||
UPDATE `poll_textreply`
|
||||
SET `ipTEMP` = INET_ATON(IF(`ip` LIKE '%_._%', `ip`, '0'));
|
||||
SET SQL_SAFE_UPDATES = 1;
|
||||
ALTER TABLE `poll_textreply`
|
||||
DROP COLUMN `ip`
|
||||
, CHANGE COLUMN `ipTEMP` `ip` INT(10) UNSIGNED NOT NULL;
|
||||
COMMIT;
|
||||
|
||||
START TRANSACTION;
|
||||
ALTER TABLE `poll_vote`
|
||||
CHANGE COLUMN `ckey` `ckey` VARCHAR(32) NOT NULL
|
||||
, ADD COLUMN `ipTEMP` INT UNSIGNED NOT NULL AFTER `ip`;
|
||||
SET SQL_SAFE_UPDATES = 0;
|
||||
UPDATE `poll_vote`
|
||||
SET `ipTEMP` = INET_ATON(IF(`ip` LIKE '%_._%', `ip`, '0'));
|
||||
SET SQL_SAFE_UPDATES = 1;
|
||||
ALTER TABLE `poll_vote`
|
||||
DROP COLUMN `ip`
|
||||
, CHANGE COLUMN `ipTEMP` `ip` INT(10) UNSIGNED NOT NULL;
|
||||
COMMIT;
|
||||
|
||||
/*----------------------------------------------------
|
||||
|
||||
These queries are to be run after the above.
|
||||
These indexes are designed with only the codebase queries in mind.
|
||||
You may find it helpful to modify or create your own indexes if you utilise additional queries for other services.
|
||||
|
||||
----------------------------------------------------*/
|
||||
|
||||
ALTER TABLE `ban`
|
||||
ADD INDEX `idx_ban_checkban` (`ckey` ASC, `bantype` ASC, `expiration_time` ASC, `unbanned` ASC, `job` ASC)
|
||||
, ADD INDEX `idx_ban_isbanned` (`ckey` ASC, `ip` ASC, `computerid` ASC, `bantype` ASC, `expiration_time` ASC, `unbanned` ASC)
|
||||
, ADD INDEX `idx_ban_count` (`id` ASC, `a_ckey` ASC, `bantype` ASC, `expiration_time` ASC, `unbanned` ASC);
|
||||
|
||||
ALTER TABLE `ipintel`
|
||||
ADD INDEX `idx_ipintel` (`ip` ASC, `intel` ASC, `date` ASC);
|
||||
|
||||
ALTER TABLE `library`
|
||||
ADD INDEX `idx_lib_id_del` (`id` ASC, `deleted` ASC)
|
||||
, ADD INDEX `idx_lib_del_title` (`deleted` ASC, `title` ASC)
|
||||
, ADD INDEX `idx_lib_search` (`deleted` ASC, `author` ASC, `title` ASC, `category` ASC);
|
||||
|
||||
ALTER TABLE `messages`
|
||||
ADD INDEX `idx_msg_ckey_time` (`targetckey` ASC, `timestamp` ASC)
|
||||
, ADD INDEX `idx_msg_type_ckeys_time` (`type` ASC, `targetckey` ASC, `adminckey` ASC, `timestamp` ASC)
|
||||
, ADD INDEX `idx_msg_type_ckey_time_odr` (`type` ASC, `targetckey` ASC, `timestamp` ASC);
|
||||
|
||||
ALTER TABLE `player`
|
||||
ADD INDEX `idx_player_cid_ckey` (`computerid` ASC, `ckey` ASC)
|
||||
, ADD INDEX `idx_player_ip_ckey` (`ip` ASC, `ckey` ASC);
|
||||
|
||||
ALTER TABLE `poll_option`
|
||||
ADD INDEX `idx_pop_pollid` (`pollid` ASC);
|
||||
|
||||
ALTER TABLE `poll_question`
|
||||
ADD INDEX `idx_pquest_question_time_ckey` (`question` ASC, `starttime` ASC, `endtime` ASC, `createdby_ckey` ASC, `createdby_ip` ASC)
|
||||
, ADD INDEX `idx_pquest_time_admin` (`starttime` ASC, `endtime` ASC, `adminonly` ASC)
|
||||
, ADD INDEX `idx_pquest_id_time_type_admin` (`id` ASC, `starttime` ASC, `endtime` ASC, `polltype` ASC, `adminonly` ASC);
|
||||
|
||||
ALTER TABLE `poll_vote`
|
||||
ADD INDEX `idx_pvote_pollid_ckey` (`pollid` ASC, `ckey` ASC)
|
||||
, ADD INDEX `idx_pvote_optionid_ckey` (`optionid` ASC, `ckey` ASC);
|
||||
|
||||
ALTER TABLE `poll_textreply`
|
||||
ADD INDEX `idx_ptext_pollid_ckey` (`pollid` ASC, `ckey` ASC);
|
||||
@@ -0,0 +1,92 @@
|
||||
#Python 3+ Script for populating the key of all ckeys in player table 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
|
||||
#And that you have run the most recent commands listed in database_changelog.txt
|
||||
#
|
||||
#To view the parameters for this script, execute it with the argument --help
|
||||
#All the positional arguments are required, remember to include a prefixe in your table name if you use one
|
||||
#--useckey and --onlynull are optional arguments, see --help for their function
|
||||
#An example of the command used to execute this script from powershell:
|
||||
#python populate_key_2018-07-09.py "localhost" "root" "password" "feedback" "SS13_player" --onlynull --useckey
|
||||
#
|
||||
#This script requires an internet connection to function
|
||||
#Sometimes byond.com fails to return the page for a valid ckey, this can be a temporary problem and may be resolved by rerunning the script
|
||||
#You can have the script use the existing ckey instead if the key is unable to be parsed with the --useckey optional argument
|
||||
#To make the script only iterate on rows that failed to parse a ckey and have a null byond_key column, use the --onlynull optional argument
|
||||
#To make the script only iterate on rows that have a matching ckey and byond_key column, use the --onlyckeymatch optional argument
|
||||
#The --onlynull and --onlyckeymatch arguments are mutually exclusive, the script can't be run with both of them enabled
|
||||
#
|
||||
#It's safe to run this script with your game server(s) active.
|
||||
|
||||
import MySQLdb
|
||||
import argparse
|
||||
import re
|
||||
import sys
|
||||
from urllib.request import urlopen
|
||||
from datetime import datetime
|
||||
|
||||
if sys.version_info[0] < 3:
|
||||
raise Exception("Python must be at least version 3 for this script.")
|
||||
query_values = ""
|
||||
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 password")
|
||||
parser.add_argument("database", help="Database name")
|
||||
parser.add_argument("playertable", help="Name of the player table (remember a prefix if you use one)")
|
||||
parser.add_argument("--useckey", help="Use the player's ckey for their key if unable to contact or parse their member page", action="store_true")
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument("--onlynull", help="Only try to update rows if their byond_key column is null, mutually exclusive with --onlyckeymatch", action="store_true")
|
||||
group.add_argument("--onlyckeymatch", help="Only try to update rows that have matching ckey and byond_key columns from the --useckey argument, mutually exclusive with --onlynull", action="store_true")
|
||||
args = parser.parse_args()
|
||||
where = ""
|
||||
if args.onlynull:
|
||||
where = " WHERE byond_key IS NULL"
|
||||
if args.onlyckeymatch:
|
||||
where = " WHERE byond_key = ckey"
|
||||
db=MySQLdb.connect(host=args.address, user=args.username, passwd=args.password, db=args.database)
|
||||
cursor=db.cursor()
|
||||
player_table = args.playertable
|
||||
cursor.execute("SELECT ckey FROM {0}{1}".format(player_table, where))
|
||||
ckey_list = cursor.fetchall()
|
||||
failed_ckeys = []
|
||||
start_time = datetime.now()
|
||||
success = 0
|
||||
fail = 0
|
||||
print("Beginning script at {0}".format(start_time.strftime("%Y-%m-%d %H:%M:%S")))
|
||||
if not ckey_list:
|
||||
print("Query returned no rows")
|
||||
for current_ckey in ckey_list:
|
||||
link = urlopen("https://secure.byond.com/members/{0}/?format=text".format(current_ckey[0]))
|
||||
data = link.read()
|
||||
data = data.decode("ISO-8859-1")
|
||||
match = re.search("\tkey = \"(.+)\"", data)
|
||||
if match:
|
||||
key = match.group(1)
|
||||
success += 1
|
||||
else:
|
||||
fail += 1
|
||||
failed_ckeys.append(current_ckey[0])
|
||||
msg = "Failed to parse a key for {0}".format(current_ckey[0])
|
||||
if args.useckey:
|
||||
msg += ", using their ckey instead"
|
||||
print(msg)
|
||||
key = current_ckey[0]
|
||||
else:
|
||||
print(msg)
|
||||
continue
|
||||
cursor.execute("UPDATE {0} SET byond_key = %s WHERE ckey = %s".format(player_table), (key, current_ckey[0]))
|
||||
db.commit()
|
||||
end_time = datetime.now()
|
||||
print("Script completed at {0} with duration {1}".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), end_time - start_time))
|
||||
if failed_ckeys:
|
||||
if args.useckey:
|
||||
print("The following ckeys failed to parse a key so their ckey was used instead:")
|
||||
else:
|
||||
print("The following ckeys failed to parse a key and were skipped:")
|
||||
print("\n".join(failed_ckeys))
|
||||
print("Keys successfully parsed: {0} Keys failed parsing: {1}".format(success, fail))
|
||||
cursor.close()
|
||||
@@ -0,0 +1,473 @@
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
|
||||
--
|
||||
-- Table structure for table `admin`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `admin`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `admin` (
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`rank` varchar(32) NOT NULL,
|
||||
PRIMARY KEY (`ckey`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `admin_log`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `admin_log`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `admin_log` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`datetime` datetime NOT NULL,
|
||||
`round_id` int(11) unsigned NOT NULL,
|
||||
`adminckey` varchar(32) NOT NULL,
|
||||
`adminip` int(10) unsigned NOT NULL,
|
||||
`operation` enum('add admin','remove admin','change admin rank','add rank','remove rank','change rank flags') NOT NULL,
|
||||
`target` varchar(32) NOT NULL,
|
||||
`log` varchar(1000) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `admin_ranks`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `admin_ranks`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `admin_ranks` (
|
||||
`rank` varchar(32) NOT NULL,
|
||||
`flags` smallint(5) unsigned NOT NULL,
|
||||
`exclude_flags` smallint(5) unsigned NOT NULL,
|
||||
`can_edit_flags` smallint(5) unsigned NOT NULL,
|
||||
PRIMARY KEY (`rank`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `ban`
|
||||
--
|
||||
|
||||
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,
|
||||
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`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `connection_log`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `connection_log`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `connection_log` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`datetime` datetime DEFAULT NULL,
|
||||
`server_ip` int(10) unsigned NOT NULL,
|
||||
`server_port` smallint(5) unsigned NOT NULL,
|
||||
`round_id` int(11) unsigned NOT NULL,
|
||||
`ckey` varchar(45) DEFAULT NULL,
|
||||
`ip` int(10) unsigned NOT NULL,
|
||||
`computerid` varchar(45) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `death`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `death`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `death` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`pod` varchar(50) NOT NULL,
|
||||
`x_coord` smallint(5) unsigned NOT NULL,
|
||||
`y_coord` smallint(5) unsigned NOT NULL,
|
||||
`z_coord` smallint(5) unsigned NOT NULL,
|
||||
`mapname` varchar(32) NOT NULL,
|
||||
`server_ip` int(10) unsigned NOT NULL,
|
||||
`server_port` smallint(5) unsigned NOT NULL,
|
||||
`round_id` int(11) NOT NULL,
|
||||
`tod` datetime NOT NULL COMMENT 'Time of death',
|
||||
`job` varchar(32) NOT NULL,
|
||||
`special` varchar(32) DEFAULT NULL,
|
||||
`name` varchar(96) NOT NULL,
|
||||
`byondkey` varchar(32) NOT NULL,
|
||||
`laname` varchar(96) DEFAULT NULL,
|
||||
`lakey` varchar(32) DEFAULT NULL,
|
||||
`bruteloss` smallint(5) unsigned NOT NULL,
|
||||
`brainloss` smallint(5) unsigned NOT NULL,
|
||||
`fireloss` smallint(5) unsigned NOT NULL,
|
||||
`oxyloss` smallint(5) unsigned NOT NULL,
|
||||
`toxloss` smallint(5) unsigned NOT NULL,
|
||||
`cloneloss` smallint(5) unsigned NOT NULL,
|
||||
`staminaloss` smallint(5) unsigned NOT NULL,
|
||||
`last_words` varchar(255) DEFAULT NULL,
|
||||
`suicide` tinyint(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `feedback`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `feedback`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `feedback` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`datetime` datetime NOT NULL,
|
||||
`round_id` int(11) unsigned NOT NULL,
|
||||
`key_name` varchar(32) NOT NULL,
|
||||
`key_type` enum('text', 'amount', 'tally', 'nested tally', 'associative') NOT NULL,
|
||||
`version` tinyint(3) unsigned NOT NULL,
|
||||
`json` json NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `ipintel`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `ipintel`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `ipintel` (
|
||||
`ip` int(10) unsigned NOT NULL,
|
||||
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`intel` double NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`ip`),
|
||||
KEY `idx_ipintel` (`ip`,`intel`,`date`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `legacy_population`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `legacy_population`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `legacy_population` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`playercount` int(11) DEFAULT NULL,
|
||||
`admincount` int(11) DEFAULT NULL,
|
||||
`time` datetime NOT NULL,
|
||||
`server_ip` int(10) unsigned NOT NULL,
|
||||
`server_port` smallint(5) unsigned NOT NULL,
|
||||
`round_id` int(11) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `library`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `library`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `library` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`author` varchar(45) NOT NULL,
|
||||
`title` varchar(45) NOT NULL,
|
||||
`content` text NOT NULL,
|
||||
`category` enum('Any','Fiction','Non-Fiction','Adult','Reference','Religion') NOT NULL,
|
||||
`ckey` varchar(32) NOT NULL DEFAULT 'LEGACY',
|
||||
`datetime` datetime NOT NULL,
|
||||
`deleted` tinyint(1) unsigned DEFAULT NULL,
|
||||
`round_id_created` int(11) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `deleted_idx` (`deleted`),
|
||||
KEY `idx_lib_id_del` (`id`,`deleted`),
|
||||
KEY `idx_lib_del_title` (`deleted`,`title`),
|
||||
KEY `idx_lib_search` (`deleted`,`author`,`title`,`category`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `messages`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `messages`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `messages` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`type` enum('memo','message','message sent','note','watchlist entry') NOT NULL,
|
||||
`targetckey` varchar(32) NOT NULL,
|
||||
`adminckey` varchar(32) NOT NULL,
|
||||
`text` varchar(2048) NOT NULL,
|
||||
`timestamp` datetime NOT NULL,
|
||||
`server` varchar(32) DEFAULT NULL,
|
||||
`server_ip` int(10) unsigned NOT NULL,
|
||||
`server_port` smallint(5) unsigned NOT NULL,
|
||||
`round_id` int(11) unsigned NOT NULL,
|
||||
`secret` tinyint(1) unsigned NOT NULL,
|
||||
`expire_timestamp` datetime DEFAULT NULL,
|
||||
`severity` enum('high','medium','minor','none') DEFAULT NULL,
|
||||
`lasteditor` varchar(32) DEFAULT NULL,
|
||||
`edits` text,
|
||||
`deleted` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_msg_ckey_time` (`targetckey`,`timestamp`, `deleted`),
|
||||
KEY `idx_msg_type_ckeys_time` (`type`,`targetckey`,`adminckey`,`timestamp`, `deleted`),
|
||||
KEY `idx_msg_type_ckey_time_odr` (`type`,`targetckey`,`timestamp`, `deleted`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `role_time`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `role_time`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
|
||||
CREATE TABLE `role_time`
|
||||
( `ckey` VARCHAR(32) NOT NULL ,
|
||||
`job` VARCHAR(32) NOT NULL ,
|
||||
`minutes` INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`ckey`, `job`)
|
||||
) ENGINE = InnoDB;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `role_time`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `role_time_log`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `role_time_log` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`job` varchar(128) NOT NULL,
|
||||
`delta` int(11) NOT NULL,
|
||||
`datetime` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ckey` (`ckey`),
|
||||
KEY `job` (`job`),
|
||||
KEY `datetime` (`datetime`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `player`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `player`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `player` (
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`byond_key` varchar(32) DEFAULT NULL,
|
||||
`firstseen` datetime NOT NULL,
|
||||
`firstseen_round_id` int(11) unsigned NOT NULL,
|
||||
`lastseen` datetime NOT NULL,
|
||||
`lastseen_round_id` int(11) unsigned NOT NULL,
|
||||
`ip` int(10) unsigned NOT NULL,
|
||||
`computerid` varchar(32) NOT NULL,
|
||||
`lastadminrank` varchar(32) NOT NULL DEFAULT 'Player',
|
||||
`accountjoindate` DATE DEFAULT NULL,
|
||||
`flags` smallint(5) unsigned DEFAULT '0' NOT NULL,
|
||||
PRIMARY KEY (`ckey`),
|
||||
KEY `idx_player_cid_ckey` (`computerid`,`ckey`),
|
||||
KEY `idx_player_ip_ckey` (`ip`,`ckey`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `poll_option`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `poll_option`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `poll_option` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`pollid` int(11) NOT NULL,
|
||||
`text` varchar(255) NOT NULL,
|
||||
`minval` int(3) DEFAULT NULL,
|
||||
`maxval` int(3) DEFAULT NULL,
|
||||
`descmin` varchar(32) DEFAULT NULL,
|
||||
`descmid` varchar(32) DEFAULT NULL,
|
||||
`descmax` varchar(32) DEFAULT NULL,
|
||||
`default_percentage_calc` tinyint(1) unsigned NOT NULL DEFAULT '1',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_pop_pollid` (`pollid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `poll_question`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `poll_question`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `poll_question` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`polltype` enum('OPTION','TEXT','NUMVAL','MULTICHOICE','IRV') NOT NULL,
|
||||
`starttime` datetime NOT NULL,
|
||||
`endtime` datetime NOT NULL,
|
||||
`question` varchar(255) NOT NULL,
|
||||
`adminonly` tinyint(1) unsigned NOT NULL,
|
||||
`multiplechoiceoptions` int(2) DEFAULT NULL,
|
||||
`createdby_ckey` varchar(32) DEFAULT NULL,
|
||||
`createdby_ip` int(10) unsigned NOT NULL,
|
||||
`dontshow` tinyint(1) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_pquest_question_time_ckey` (`question`,`starttime`,`endtime`,`createdby_ckey`,`createdby_ip`),
|
||||
KEY `idx_pquest_time_admin` (`starttime`,`endtime`,`adminonly`),
|
||||
KEY `idx_pquest_id_time_type_admin` (`id`,`starttime`,`endtime`,`polltype`,`adminonly`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `poll_textreply`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `poll_textreply`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `poll_textreply` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`datetime` datetime NOT NULL,
|
||||
`pollid` int(11) NOT NULL,
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`ip` int(10) unsigned NOT NULL,
|
||||
`replytext` varchar(2048) NOT NULL,
|
||||
`adminrank` varchar(32) NOT NULL DEFAULT 'Player',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_ptext_pollid_ckey` (`pollid`,`ckey`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `poll_vote`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `poll_vote`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `poll_vote` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`datetime` datetime NOT NULL,
|
||||
`pollid` int(11) NOT NULL,
|
||||
`optionid` int(11) NOT NULL,
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`ip` int(10) unsigned NOT NULL,
|
||||
`adminrank` varchar(32) NOT NULL,
|
||||
`rating` int(2) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_pvote_pollid_ckey` (`pollid`,`ckey`),
|
||||
KEY `idx_pvote_optionid_ckey` (`optionid`,`ckey`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `round`
|
||||
--
|
||||
DROP TABLE IF EXISTS `round`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `round` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`initialize_datetime` DATETIME NOT NULL,
|
||||
`start_datetime` DATETIME NULL,
|
||||
`shutdown_datetime` DATETIME NULL,
|
||||
`end_datetime` DATETIME NULL,
|
||||
`server_ip` INT(10) UNSIGNED NOT NULL,
|
||||
`server_port` SMALLINT(5) UNSIGNED NOT NULL,
|
||||
`commit_hash` CHAR(40) NULL,
|
||||
`game_mode` VARCHAR(32) NULL,
|
||||
`game_mode_result` VARCHAR(64) NULL,
|
||||
`end_state` VARCHAR(64) NULL,
|
||||
`shuttle_name` VARCHAR(64) NULL,
|
||||
`map_name` VARCHAR(32) NULL,
|
||||
`station_name` VARCHAR(80) NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
--
|
||||
-- Table structure for table `schema_revision`
|
||||
--
|
||||
DROP TABLE IF EXISTS `schema_revision`;
|
||||
CREATE TABLE `schema_revision` (
|
||||
`major` TINYINT(3) unsigned NOT NULL,
|
||||
`minor` TINYINT(3) unsigned NOT NULL,
|
||||
`date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`major`, `minor`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `role_timeTlogupdate` AFTER UPDATE ON `role_time` FOR EACH ROW BEGIN INSERT into role_time_log (ckey, job, delta) VALUES (NEW.CKEY, NEW.job, NEW.minutes-OLD.minutes);
|
||||
END
|
||||
$$
|
||||
CREATE TRIGGER `role_timeTloginsert` AFTER INSERT ON `role_time` FOR EACH ROW BEGIN INSERT into role_time_log (ckey, job, delta) VALUES (NEW.ckey, NEW.job, NEW.minutes);
|
||||
END
|
||||
$$
|
||||
CREATE TRIGGER `role_timeTlogdelete` AFTER DELETE ON `role_time` FOR EACH ROW BEGIN INSERT into role_time_log (ckey, job, delta) VALUES (OLD.ckey, OLD.job, 0-OLD.minutes);
|
||||
END
|
||||
$$
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
@@ -0,0 +1,473 @@
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_admin`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_admin`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `SS13_admin` (
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`rank` varchar(32) NOT NULL,
|
||||
PRIMARY KEY (`ckey`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_admin_log`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_admin_log`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `SS13_admin_log` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`datetime` datetime NOT NULL,
|
||||
`round_id` int(11) unsigned NOT NULL,
|
||||
`adminckey` varchar(32) NOT NULL,
|
||||
`adminip` int(10) unsigned NOT NULL,
|
||||
`operation` enum('add admin','remove admin','change admin rank','add rank','remove rank','change rank flags') NOT NULL,
|
||||
`target` varchar(32) NOT NULL,
|
||||
`log` varchar(1000) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_admin_ranks`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_admin_ranks`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `SS13_admin_ranks` (
|
||||
`rank` varchar(32) NOT NULL,
|
||||
`flags` smallint(5) unsigned NOT NULL,
|
||||
`exclude_flags` smallint(5) unsigned NOT NULL,
|
||||
`can_edit_flags` smallint(5) unsigned NOT NULL,
|
||||
PRIMARY KEY (`rank`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_ban`
|
||||
--
|
||||
|
||||
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,
|
||||
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`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_connection_log`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_connection_log`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `SS13_connection_log` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`datetime` datetime DEFAULT NULL,
|
||||
`server_ip` int(10) unsigned NOT NULL,
|
||||
`server_port` smallint(5) unsigned NOT NULL,
|
||||
`round_id` int(11) unsigned NOT NULL,
|
||||
`ckey` varchar(45) DEFAULT NULL,
|
||||
`ip` int(10) unsigned NOT NULL,
|
||||
`computerid` varchar(45) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_death`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_death`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `SS13_death` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`pod` varchar(50) NOT NULL,
|
||||
`x_coord` smallint(5) unsigned NOT NULL,
|
||||
`y_coord` smallint(5) unsigned NOT NULL,
|
||||
`z_coord` smallint(5) unsigned NOT NULL,
|
||||
`mapname` varchar(32) NOT NULL,
|
||||
`server_ip` int(10) unsigned NOT NULL,
|
||||
`server_port` smallint(5) unsigned NOT NULL,
|
||||
`round_id` int(11) NOT NULL,
|
||||
`tod` datetime NOT NULL COMMENT 'Time of death',
|
||||
`job` varchar(32) NOT NULL,
|
||||
`special` varchar(32) DEFAULT NULL,
|
||||
`name` varchar(96) NOT NULL,
|
||||
`byondkey` varchar(32) NOT NULL,
|
||||
`laname` varchar(96) DEFAULT NULL,
|
||||
`lakey` varchar(32) DEFAULT NULL,
|
||||
`bruteloss` smallint(5) unsigned NOT NULL,
|
||||
`brainloss` smallint(5) unsigned NOT NULL,
|
||||
`fireloss` smallint(5) unsigned NOT NULL,
|
||||
`oxyloss` smallint(5) unsigned NOT NULL,
|
||||
`toxloss` smallint(5) unsigned NOT NULL,
|
||||
`cloneloss` smallint(5) unsigned NOT NULL,
|
||||
`staminaloss` smallint(5) unsigned NOT NULL,
|
||||
`last_words` varchar(255) DEFAULT NULL,
|
||||
`suicide` tinyint(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_feedback`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_feedback`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `SS13_feedback` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`datetime` datetime NOT NULL,
|
||||
`round_id` int(11) unsigned NOT NULL,
|
||||
`key_name` varchar(32) NOT NULL,
|
||||
`version` tinyint(3) unsigned NOT NULL,
|
||||
`key_type` enum('text', 'amount', 'tally', 'nested tally', 'associative') NOT NULL,
|
||||
`json` json NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_ipintel`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_ipintel`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `SS13_ipintel` (
|
||||
`ip` int(10) unsigned NOT NULL,
|
||||
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`intel` double NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`ip`),
|
||||
KEY `idx_ipintel` (`ip`,`intel`,`date`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_legacy_population`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_legacy_population`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `SS13_legacy_population` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`playercount` int(11) DEFAULT NULL,
|
||||
`admincount` int(11) DEFAULT NULL,
|
||||
`time` datetime NOT NULL,
|
||||
`server_ip` int(10) unsigned NOT NULL,
|
||||
`server_port` smallint(5) unsigned NOT NULL,
|
||||
`round_id` int(11) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_library`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_library`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `SS13_library` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`author` varchar(45) NOT NULL,
|
||||
`title` varchar(45) NOT NULL,
|
||||
`content` text NOT NULL,
|
||||
`category` enum('Any','Fiction','Non-Fiction','Adult','Reference','Religion') NOT NULL,
|
||||
`ckey` varchar(32) NOT NULL DEFAULT 'LEGACY',
|
||||
`datetime` datetime NOT NULL,
|
||||
`deleted` tinyint(1) unsigned DEFAULT NULL,
|
||||
`round_id_created` int(11) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `deleted_idx` (`deleted`),
|
||||
KEY `idx_lib_id_del` (`id`,`deleted`),
|
||||
KEY `idx_lib_del_title` (`deleted`,`title`),
|
||||
KEY `idx_lib_search` (`deleted`,`author`,`title`,`category`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_messages`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_messages`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `SS13_messages` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`type` enum('memo','message','message sent','note','watchlist entry') NOT NULL,
|
||||
`targetckey` varchar(32) NOT NULL,
|
||||
`adminckey` varchar(32) NOT NULL,
|
||||
`text` varchar(2048) NOT NULL,
|
||||
`timestamp` datetime NOT NULL,
|
||||
`server` varchar(32) DEFAULT NULL,
|
||||
`server_ip` int(10) unsigned NOT NULL,
|
||||
`server_port` smallint(5) unsigned NOT NULL,
|
||||
`round_id` int(11) unsigned NOT NULL,
|
||||
`secret` tinyint(1) unsigned NOT NULL,
|
||||
`expire_timestamp` datetime DEFAULT NULL,
|
||||
`severity` enum('high','medium','minor','none') DEFAULT NULL,
|
||||
`lasteditor` varchar(32) DEFAULT NULL,
|
||||
`edits` text,
|
||||
`deleted` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_msg_ckey_time` (`targetckey`,`timestamp`, `deleted`),
|
||||
KEY `idx_msg_type_ckeys_time` (`type`,`targetckey`,`adminckey`,`timestamp`, `deleted`),
|
||||
KEY `idx_msg_type_ckey_time_odr` (`type`,`targetckey`,`timestamp`, `deleted`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_role_time`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_role_time`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
|
||||
CREATE TABLE `SS13_role_time`
|
||||
( `ckey` VARCHAR(32) NOT NULL ,
|
||||
`job` VARCHAR(32) NOT NULL ,
|
||||
`minutes` INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`ckey`, `job`)
|
||||
) ENGINE = InnoDB;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_role_time`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_role_time_log`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `SS13_role_time_log` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`job` varchar(128) NOT NULL,
|
||||
`delta` int(11) NOT NULL,
|
||||
`datetime` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ckey` (`ckey`),
|
||||
KEY `job` (`job`),
|
||||
KEY `datetime` (`datetime`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_player`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_player`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `SS13_player` (
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`byond_key` varchar(32) DEFAULT NULL,
|
||||
`firstseen` datetime NOT NULL,
|
||||
`firstseen_round_id` int(11) unsigned NOT NULL,
|
||||
`lastseen` datetime NOT NULL,
|
||||
`lastseen_round_id` int(11) unsigned NOT NULL,
|
||||
`ip` int(10) unsigned NOT NULL,
|
||||
`computerid` varchar(32) NOT NULL,
|
||||
`lastadminrank` varchar(32) NOT NULL DEFAULT 'Player',
|
||||
`accountjoindate` DATE DEFAULT NULL,
|
||||
`flags` smallint(5) unsigned DEFAULT '0' NOT NULL,
|
||||
PRIMARY KEY (`ckey`),
|
||||
KEY `idx_player_cid_ckey` (`computerid`,`ckey`),
|
||||
KEY `idx_player_ip_ckey` (`ip`,`ckey`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_poll_option`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_poll_option`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `SS13_poll_option` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`pollid` int(11) NOT NULL,
|
||||
`text` varchar(255) NOT NULL,
|
||||
`minval` int(3) DEFAULT NULL,
|
||||
`maxval` int(3) DEFAULT NULL,
|
||||
`descmin` varchar(32) DEFAULT NULL,
|
||||
`descmid` varchar(32) DEFAULT NULL,
|
||||
`descmax` varchar(32) DEFAULT NULL,
|
||||
`default_percentage_calc` tinyint(1) unsigned NOT NULL DEFAULT '1',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_pop_pollid` (`pollid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_poll_question`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_poll_question`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `SS13_poll_question` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`polltype` enum('OPTION','TEXT','NUMVAL','MULTICHOICE','IRV') NOT NULL,
|
||||
`starttime` datetime NOT NULL,
|
||||
`endtime` datetime NOT NULL,
|
||||
`question` varchar(255) NOT NULL,
|
||||
`adminonly` tinyint(1) unsigned NOT NULL,
|
||||
`multiplechoiceoptions` int(2) DEFAULT NULL,
|
||||
`createdby_ckey` varchar(32) DEFAULT NULL,
|
||||
`createdby_ip` int(10) unsigned NOT NULL,
|
||||
`dontshow` tinyint(1) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_pquest_question_time_ckey` (`question`,`starttime`,`endtime`,`createdby_ckey`,`createdby_ip`),
|
||||
KEY `idx_pquest_time_admin` (`starttime`,`endtime`,`adminonly`),
|
||||
KEY `idx_pquest_id_time_type_admin` (`id`,`starttime`,`endtime`,`polltype`,`adminonly`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_poll_textreply`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_poll_textreply`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `SS13_poll_textreply` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`datetime` datetime NOT NULL,
|
||||
`pollid` int(11) NOT NULL,
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`ip` int(10) unsigned NOT NULL,
|
||||
`replytext` varchar(2048) NOT NULL,
|
||||
`adminrank` varchar(32) NOT NULL DEFAULT 'Player',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_ptext_pollid_ckey` (`pollid`,`ckey`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_poll_vote`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_poll_vote`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `SS13_poll_vote` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`datetime` datetime NOT NULL,
|
||||
`pollid` int(11) NOT NULL,
|
||||
`optionid` int(11) NOT NULL,
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`ip` int(10) unsigned NOT NULL,
|
||||
`adminrank` varchar(32) NOT NULL,
|
||||
`rating` int(2) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_pvote_pollid_ckey` (`pollid`,`ckey`),
|
||||
KEY `idx_pvote_optionid_ckey` (`optionid`,`ckey`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_round`
|
||||
--
|
||||
DROP TABLE IF EXISTS `SS13_round`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `SS13_round` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`initialize_datetime` DATETIME NOT NULL,
|
||||
`start_datetime` DATETIME NULL,
|
||||
`shutdown_datetime` DATETIME NULL,
|
||||
`end_datetime` DATETIME NULL,
|
||||
`server_ip` INT(10) UNSIGNED NOT NULL,
|
||||
`server_port` SMALLINT(5) UNSIGNED NOT NULL,
|
||||
`commit_hash` CHAR(40) NULL,
|
||||
`game_mode` VARCHAR(32) NULL,
|
||||
`game_mode_result` VARCHAR(64) NULL,
|
||||
`end_state` VARCHAR(64) NULL,
|
||||
`shuttle_name` VARCHAR(64) NULL,
|
||||
`map_name` VARCHAR(32) NULL,
|
||||
`station_name` VARCHAR(80) NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
--
|
||||
-- Table structure for table `SS13_schema_revision`
|
||||
--
|
||||
DROP TABLE IF EXISTS `SS13_schema_revision`;
|
||||
CREATE TABLE `SS13_schema_revision` (
|
||||
`major` TINYINT(3) unsigned NOT NULL,
|
||||
`minor` TINYINT(3) unsigned NOT NULL,
|
||||
`date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`major`,`minor`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `SS13_role_timeTlogupdate` AFTER UPDATE ON `SS13_role_time` FOR EACH ROW BEGIN INSERT into SS13_role_time_log (ckey, job, delta) VALUES (NEW.CKEY, NEW.job, NEW.minutes-OLD.minutes);
|
||||
END
|
||||
$$
|
||||
CREATE TRIGGER `SS13_role_timeTloginsert` AFTER INSERT ON `SS13_role_time` FOR EACH ROW BEGIN INSERT into SS13_role_time_log (ckey, job, delta) VALUES (NEW.ckey, NEW.job, NEW.minutes);
|
||||
END
|
||||
$$
|
||||
CREATE TRIGGER `SS13_role_timeTlogdelete` AFTER DELETE ON `SS13_role_time` FOR EACH ROW BEGIN INSERT into SS13_role_time_log (ckey, job, delta) VALUES (OLD.ckey, OLD.job, 0-OLD.minutes);
|
||||
END
|
||||
$$
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
Reference in New Issue
Block a user