SQL Saving - Rewrite + Implenetation (#350)

Rewrite's Mahzel's SQL character and preference saving.
Introduces easy config switching between the new and old system, with no troubles at all.

Also introduces better logging for DBQuery/proc/parseArguments(), should something go wrong. And classes SQL query errors as full on error snow, as opposed to debug data.
This commit is contained in:
skull132
2016-05-30 23:39:07 +03:00
parent 6881213b75
commit 7dacaa28dd
21 changed files with 1333 additions and 1339 deletions

427
SQL/Aurora_SQL_Schema.sql Normal file
View File

@@ -0,0 +1,427 @@
CREATE DATABASE `spacestation13` /*!40100 DEFAULT CHARACTER SET utf8 */;
CREATE TABLE `ss13_admin` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ckey` varchar(32) CHARACTER SET latin1 NOT NULL,
`rank` varchar(32) CHARACTER SET latin1 NOT NULL DEFAULT 'Administrator',
`level` int(2) NOT NULL DEFAULT '0',
`flags` int(16) NOT NULL DEFAULT '0',
`discord_id` varchar(45) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_admin_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`datetime` datetime NOT NULL,
`adminckey` varchar(32) CHARACTER SET latin1 NOT NULL,
`adminip` varchar(18) CHARACTER SET latin1 NOT NULL,
`log` text CHARACTER SET latin1 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_ban` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`bantime` datetime NOT NULL,
`serverip` varchar(32) CHARACTER SET latin1 NOT NULL,
`bantype` varchar(32) CHARACTER SET latin1 NOT NULL,
`reason` text CHARACTER SET latin1 NOT NULL,
`job` varchar(32) CHARACTER SET latin1 DEFAULT NULL,
`duration` int(11) NOT NULL,
`rounds` int(11) DEFAULT NULL,
`expiration_time` datetime NOT NULL,
`ckey` varchar(32) CHARACTER SET latin1 NOT NULL,
`computerid` varchar(32) CHARACTER SET latin1 NOT NULL,
`ip` varchar(32) CHARACTER SET latin1 NOT NULL,
`a_ckey` varchar(32) CHARACTER SET latin1 NOT NULL,
`a_computerid` varchar(32) CHARACTER SET latin1 NOT NULL,
`a_ip` varchar(32) CHARACTER SET latin1 NOT NULL,
`who` text CHARACTER SET latin1 NOT NULL,
`adminwho` text CHARACTER SET latin1 NOT NULL,
`edits` text CHARACTER SET latin1,
`unbanned` tinyint(1) DEFAULT NULL,
`unbanned_datetime` datetime DEFAULT NULL,
`unbanned_ckey` varchar(32) CHARACTER SET latin1 DEFAULT NULL,
`unbanned_computerid` varchar(32) CHARACTER SET latin1 DEFAULT NULL,
`unbanned_ip` varchar(32) CHARACTER SET latin1 DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_ban_mirrors` (
`ban_mirror_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`ban_id` int(10) unsigned NOT NULL,
`player_ckey` varchar(32) NOT NULL,
`ban_mirror_ip` varchar(32) NOT NULL,
`ban_mirror_computerid` varchar(32) NOT NULL,
`ban_mirror_datetime` datetime NOT NULL,
PRIMARY KEY (`ban_mirror_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_characters` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ckey` varchar(32) NOT NULL,
`name` varchar(128) NOT NULL,
`metadata` varchar(512) DEFAULT NULL,
`random_name` tinyint(1) DEFAULT '0',
`gender` varchar(32) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`species` varchar(32) DEFAULT NULL,
`language` varchar(128) DEFAULT NULL,
`hair_colour` varchar(7) DEFAULT NULL,
`facial_colour` varchar(7) DEFAULT NULL,
`skin_tone` int(11) DEFAULT NULL,
`skin_colour` varchar(7) DEFAULT NULL,
`hair_style` varchar(32) DEFAULT NULL,
`facial_style` varchar(32) DEFAULT NULL,
`eyes_colour` varchar(7) DEFAULT NULL,
`underwear` varchar(32) DEFAULT NULL,
`undershirt` varchar(32) DEFAULT NULL,
`backbag` int(11) DEFAULT NULL,
`b_type` varchar(32) DEFAULT NULL,
`spawnpoint` varchar(32) DEFAULT NULL,
`jobs` text,
`alternate_option` tinyint(1) DEFAULT NULL,
`alternate_titles` text,
`disabilities` int(11) DEFAULT '0',
`skills` text,
`skills_specialization` text,
`home_system` text,
`citizenship` text,
`faction` text,
`religion` text,
`nt_relation` text,
`uplink_location` text,
`organs_data` text,
`organs_robotic` text,
`gear` text,
PRIMARY KEY (`id`),
KEY `ss13_characters_ckey` (`ckey`),
KEY `ss13_characteres_name` (`name`),
CONSTRAINT `ss13_characters_fk_ckey` FOREIGN KEY (`ckey`) REFERENCES `ss13_player` (`ckey`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `ss13_characters_flavour` (
`char_id` int(11) NOT NULL,
`records_employment` text,
`records_medical` text,
`records_security` text,
`records_exploit` text,
`flavour_general` text,
`flavour_head` text,
`flavour_face` text,
`flavour_eyes` text,
`flavour_torso` text,
`flavour_arms` text,
`flavour_hands` text,
`flavour_legs` text,
`flavour_feet` text,
`robot_default` text,
`robot_standard` text,
`robot_engineering` text,
`robot_construction` text,
`robot_surgeon` text,
`robot_crisis` text,
`robot_miner` text,
`robot_janitor` text,
`robot_service` text,
`robot_clerical` text,
`robot_security` text,
`robot_research` text,
PRIMARY KEY (`char_id`),
CONSTRAINT `ss13_flavour_fk_char_id` FOREIGN KEY (`char_id`) REFERENCES `ss13_characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
CREATE TABLE `ss13_connection_log` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`ckey` varchar(32) NOT NULL,
`datetime` datetime NOT NULL,
`serverip` varchar(32) NOT NULL,
`ip` varchar(18) NOT NULL,
`computerid` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_customitems` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ckey` varchar(32) CHARACTER SET latin1 NOT NULL,
`real_name` varchar(32) CHARACTER SET latin1 NOT NULL,
`item` varchar(124) CHARACTER SET latin1 NOT NULL,
`job` text CHARACTER SET latin1,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_death` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pod` text CHARACTER SET latin1 NOT NULL COMMENT 'Place of death',
`coord` text CHARACTER SET latin1 NOT NULL COMMENT 'X, Y, Z POD',
`tod` datetime NOT NULL COMMENT 'Time of death',
`job` text CHARACTER SET latin1 NOT NULL,
`special` text CHARACTER SET latin1 NOT NULL,
`name` text CHARACTER SET latin1 NOT NULL,
`byondkey` text CHARACTER SET latin1 NOT NULL,
`laname` text CHARACTER SET latin1 NOT NULL COMMENT 'Last attacker name',
`lakey` text CHARACTER SET latin1 NOT NULL COMMENT 'Last attacker key',
`gender` text CHARACTER SET latin1 NOT NULL,
`bruteloss` int(11) NOT NULL,
`brainloss` int(11) NOT NULL,
`fireloss` int(11) NOT NULL,
`oxyloss` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_directives` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(64) CHARACTER SET latin1 NOT NULL,
`data` text CHARACTER SET latin1 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_feedback` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`time` datetime NOT NULL,
`round_id` int(8) NOT NULL,
`var_name` varchar(32) CHARACTER SET latin1 NOT NULL,
`var_value` int(16) DEFAULT NULL,
`details` text CHARACTER SET latin1,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_forms` (
`form_id` int(11) NOT NULL AUTO_INCREMENT,
`id` varchar(4) CHARACTER SET latin1 NOT NULL,
`name` varchar(50) CHARACTER SET latin1 NOT NULL,
`department` varchar(32) CHARACTER SET latin1 NOT NULL,
`data` text CHARACTER SET latin1 NOT NULL,
`info` text CHARACTER SET latin1,
PRIMARY KEY (`form_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_library` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`author` text CHARACTER SET latin1 NOT NULL,
`title` text CHARACTER SET latin1 NOT NULL,
`content` text CHARACTER SET latin1 NOT NULL,
`category` text CHARACTER SET latin1 NOT NULL,
`uploadtime` datetime NOT NULL,
`uploader` varchar(32) CHARACTER SET latin1 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_news` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`publishtime` int(11) NOT NULL,
`channel` varchar(64) CHARACTER SET latin1 NOT NULL,
`author` varchar(64) CHARACTER SET latin1 NOT NULL,
`title` varchar(64) CHARACTER SET latin1 DEFAULT NULL,
`body` text CHARACTER SET latin1 NOT NULL,
`notpublishing` tinyint(1) DEFAULT '0',
`approved` tinyint(1) DEFAULT '0',
`status` tinyint(1) NOT NULL DEFAULT '1',
`uploadip` varchar(18) CHARACTER SET latin1 NOT NULL,
`uploadtime` datetime NOT NULL,
`approvetime` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_notes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`adddate` datetime NOT NULL,
`ckey` varchar(32) CHARACTER SET latin1 NOT NULL,
`ip` varchar(18) CHARACTER SET latin1 DEFAULT NULL,
`computerid` varchar(32) CHARACTER SET latin1 DEFAULT NULL,
`a_ckey` varchar(32) CHARACTER SET latin1 NOT NULL,
`content` text CHARACTER SET latin1 NOT NULL,
`visible` tinyint(1) NOT NULL DEFAULT '1',
`edited` tinyint(1) NOT NULL DEFAULT '0',
`lasteditor` varchar(32) CHARACTER SET latin1 DEFAULT NULL,
`lasteditdate` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_player` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ckey` varchar(32) CHARACTER SET latin1 NOT NULL,
`firstseen` datetime NOT NULL,
`lastseen` datetime NOT NULL,
`ip` varchar(18) CHARACTER SET latin1 NOT NULL,
`computerid` varchar(32) CHARACTER SET latin1 NOT NULL,
`lastadminrank` varchar(32) CHARACTER SET latin1 NOT NULL DEFAULT 'Player',
`whitelist_status` int(11) unsigned NOT NULL DEFAULT '0',
`migration_status` tinyint(1) DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `ckey` (`ckey`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_player_linking` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`forum_id` int(11) NOT NULL,
`forum_username_short` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`forum_username` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`player_ckey` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`status` enum('new','confirmed','rejected','linked') COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `ss13_player_preferences` (
`ckey` varchar(32) NOT NULL,
`ooccolor` text NOT NULL,
`lastchangelog` text NOT NULL,
`UI_style` text NOT NULL,
`current_character` int(11) NOT NULL,
`toggles` int(11) NOT NULL,
`UI_style_color` text NOT NULL,
`UI_style_alpha` int(11) NOT NULL,
`be_special` int(11) NOT NULL,
`asfx_togs` int(11) NOT NULL,
PRIMARY KEY (`ckey`),
CONSTRAINT `player_preferences_fk_ckey` FOREIGN KEY (`ckey`) REFERENCES `ss13_player` (`ckey`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `ss13_poll_option` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pollid` int(11) NOT NULL,
`text` varchar(255) CHARACTER SET latin1 NOT NULL,
`percentagecalc` tinyint(1) NOT NULL DEFAULT '1',
`minval` int(3) DEFAULT NULL,
`maxval` int(3) DEFAULT NULL,
`descmin` varchar(32) CHARACTER SET latin1 DEFAULT NULL,
`descmid` varchar(32) CHARACTER SET latin1 DEFAULT NULL,
`descmax` varchar(32) CHARACTER SET latin1 DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_poll_question` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`polltype` varchar(16) CHARACTER SET latin1 NOT NULL DEFAULT 'OPTION',
`starttime` datetime NOT NULL,
`endtime` datetime NOT NULL,
`question` varchar(255) CHARACTER SET latin1 NOT NULL,
`multiplechoiceoptions` int(11) DEFAULT NULL,
`adminonly` tinyint(1) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=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) CHARACTER SET latin1 NOT NULL,
`ip` varchar(18) CHARACTER SET latin1 NOT NULL,
`replytext` text CHARACTER SET latin1 NOT NULL,
`adminrank` varchar(32) CHARACTER SET latin1 NOT NULL DEFAULT 'Player',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=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(255) CHARACTER SET latin1 NOT NULL,
`ip` varchar(16) CHARACTER SET latin1 NOT NULL,
`adminrank` varchar(32) CHARACTER SET latin1 NOT NULL,
`rating` int(2) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_population` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`playercount` int(11) DEFAULT NULL,
`admincount` int(11) DEFAULT NULL,
`time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=69279 DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_privacy` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`datetime` datetime NOT NULL,
`ckey` varchar(32) CHARACTER SET latin1 NOT NULL,
`option` varchar(128) CHARACTER SET latin1 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_syndie_contracts` (
`contract_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`contractee_id` int(11) NOT NULL,
`contractee_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`status` enum('new','open','mod-nok','completed','closed','reopened','canceled') COLLATE utf8_unicode_ci NOT NULL,
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`description` text COLLATE utf8_unicode_ci NOT NULL,
`reward_credits` int(11) DEFAULT NULL,
`reward_other` text COLLATE utf8_unicode_ci,
`completer_id` int(11) DEFAULT NULL,
`completer_name` text COLLATE utf8_unicode_ci,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`contract_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `ss13_syndie_contracts_comments` (
`comment_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`contract_id` int(11) NOT NULL,
`commentor_id` int(11) NOT NULL,
`commentor_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`comment` text COLLATE utf8_unicode_ci NOT NULL,
`image_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`type` enum('mod-author','mod-ooc','ic','ic-comprep','ic-failrep','ic-cancel','ooc') COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`comment_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `ss13_syndie_contracts_subscribers` (
`contract_id` int(10) unsigned NOT NULL,
`user_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`contract_id`,`user_id`),
CONSTRAINT `syndie_contracts_subscribers_contract_id_foreign` FOREIGN KEY (`contract_id`) REFERENCES `ss13_syndie_contracts` (`contract_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `ss13_warnings` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`time` datetime NOT NULL,
`severity` tinyint(1) DEFAULT '0',
`reason` text CHARACTER SET latin1 NOT NULL,
`notes` text CHARACTER SET latin1,
`ckey` varchar(32) CHARACTER SET latin1 NOT NULL,
`computerid` varchar(32) CHARACTER SET latin1 NOT NULL,
`ip` varchar(32) CHARACTER SET latin1 NOT NULL,
`a_ckey` varchar(32) CHARACTER SET latin1 NOT NULL,
`a_computerid` varchar(32) DEFAULT NULL,
`a_ip` varchar(32) DEFAULT NULL,
`acknowledged` tinyint(1) DEFAULT '0',
`expired` tinyint(1) DEFAULT '0',
`visible` tinyint(1) DEFAULT '1',
`edited` tinyint(1) DEFAULT '0',
`lasteditor` varchar(32) CHARACTER SET latin1 DEFAULT NULL,
`lasteditdate` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ss13_web_sso` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`ckey` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`token` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`ip` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `ss13_whitelist_log` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`datetime` datetime NOT NULL,
`user` varchar(32) NOT NULL,
`action_method` varchar(32) NOT NULL DEFAULT 'Game Server',
`action` mediumtext NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `ss13_whitelist_statuses` (
`flag` int(10) unsigned NOT NULL,
`status_name` varchar(32) NOT NULL,
PRIMARY KEY (`status_name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

View File

@@ -1,246 +0,0 @@
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!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 utf8mb4 */;
CREATE TABLE `characters_data` (
`Id` int(11) NOT NULL,
`char_id` int(11) NOT NULL,
`OOC` varchar(512) DEFAULT NULL,
`name` varchar(128) NOT NULL,
`isRandom` tinyint(1) DEFAULT NULL,
`gender` varchar(32) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`species` varchar(32) DEFAULT NULL,
`language` varchar(128) DEFAULT NULL,
`hair_R` int(11) DEFAULT NULL,
`hair_G` int(11) DEFAULT NULL,
`hair_B` int(11) DEFAULT NULL,
`facial_R` int(11) DEFAULT NULL,
`facial_G` int(11) DEFAULT NULL,
`facial_B` int(11) DEFAULT NULL,
`skin_tone` int(11) DEFAULT NULL,
`skin_R` int(11) DEFAULT NULL,
`skin_G` int(11) DEFAULT NULL,
`skin_B` int(11) DEFAULT NULL,
`hair_style` varchar(32) DEFAULT NULL,
`facial_style` varchar(32) DEFAULT NULL,
`eyes_R` int(11) DEFAULT NULL,
`eyes_G` int(11) DEFAULT NULL,
`eyes_B` int(11) DEFAULT NULL,
`underwear` varchar(32) DEFAULT NULL,
`undershirt` varchar(32) DEFAULT NULL,
`backbag` int(11) DEFAULT NULL,
`b_type` varchar(32) DEFAULT NULL,
`spawnpoint` varchar(32) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `characters_flavour` (
`id` int(11) NOT NULL,
`char_id` int(11) NOT NULL,
`generals` text NOT NULL,
`head` text NOT NULL,
`face` text NOT NULL,
`eyes` text NOT NULL,
`torso` text NOT NULL,
`arms` text NOT NULL,
`hands` text NOT NULL,
`legs` text NOT NULL,
`feet` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
CREATE TABLE `characters_gear` (
`id` int(11) NOT NULL,
`char_id` int(11) NOT NULL,
`gear` mediumtext
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `characters_jobs` (
`id` int(11) NOT NULL,
`char_id` int(11) NOT NULL,
`Alternate` int(11) NOT NULL,
`civ_high` int(11) NOT NULL,
`civ_med` int(11) NOT NULL,
`civ_low` int(11) NOT NULL,
`medsci_high` int(11) NOT NULL,
`medsci_med` int(11) NOT NULL,
`medsci_low` int(11) NOT NULL,
`engsec_high` int(11) NOT NULL,
`engsec_med` int(11) NOT NULL,
`engsec_low` int(11) NOT NULL,
`alt_titles` mediumtext NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
CREATE TABLE `characters_misc` (
`id` int(11) NOT NULL,
`char_id` int(11) NOT NULL,
`med_rec` text NOT NULL,
`sec_rec` text NOT NULL,
`gen_rec` text NOT NULL,
`disab` text NOT NULL,
`used_skill` int(11) NOT NULL,
`skills_spec` text NOT NULL,
`home_sys` text NOT NULL,
`citizen` text NOT NULL,
`faction` text NOT NULL,
`religion` text NOT NULL,
`NT_relation` text NOT NULL,
`uplink_loc` text NOT NULL,
`exploit_rec` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `characters_organs` (
`id` int(11) NOT NULL,
`char_id` int(11) NOT NULL,
`l_leg` text,
`r_leg` text,
`l_arm` text,
`r_arm` text,
`l_foot` text,
`r_foot` text,
`l_hand` text,
`r_hand` text,
`heart` text,
`eyes` text
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `characters_rlimb` (
`id` int(11) NOT NULL,
`char_id` int(11) NOT NULL,
`l_leg` text,
`r_leg` text,
`l_arm` text,
`r_arm` text,
`l_foot` text,
`r_foot` text,
`l_hand` text,
`r_hand` text
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `characters_robot_flavour` (
`id` int(11) NOT NULL,
`char_id` int(11) DEFAULT NULL,
`Default_Robot` text,
`Standard` text,
`Engineering` text,
`Construction` text,
`Surgeon` text,
`Crisis` text,
`Miner` text,
`Janitor` text,
`Service` text,
`Clerical` text,
`Security` text,
`Research` text
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `characters_skills` (
`id` int(11) NOT NULL,
`char_id` int(11) NOT NULL,
`Command` int(11) DEFAULT NULL,
`Botany` int(11) DEFAULT NULL,
`Cooking` int(11) DEFAULT NULL,
`Close_Combat` int(11) DEFAULT NULL,
`Weapons_Expertise` int(11) DEFAULT NULL,
`Forensics` int(11) DEFAULT NULL,
`NanoTrasen_Law` int(11) DEFAULT NULL,
`EVA` int(11) DEFAULT NULL,
`Construction` int(11) DEFAULT NULL,
`Electrical` int(11) DEFAULT NULL,
`Atmos` int(11) DEFAULT NULL,
`Engines` int(11) DEFAULT NULL,
`Heavy_Mach` int(11) DEFAULT NULL,
`Complex_Devices` int(11) DEFAULT NULL,
`Information_Tech` int(11) DEFAULT NULL,
`Genetics` int(11) DEFAULT NULL,
`Chemistry` int(11) DEFAULT NULL,
`Science` int(11) DEFAULT NULL,
`Medicine` int(11) DEFAULT NULL,
`Anatomy` int(11) DEFAULT NULL,
`Virology` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `player_preferences` (
`id` int(11) NOT NULL,
`ckey` text NOT NULL,
`ooccolor` text NOT NULL,
`lastchangelog` text NOT NULL,
`UI_style` text NOT NULL,
`default_slot` int(11) NOT NULL,
`toggles` int(11) NOT NULL,
`UI_style_color` text NOT NULL,
`UI_style_alpha` int(11) NOT NULL,
`be_special` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `ss13_characters` (
`id` int(11) NOT NULL,
`ckey` varchar(32) DEFAULT NULL,
`slot` int(11) DEFAULT '0',
`Character_Name` text
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
ALTER TABLE `characters_data`
ADD PRIMARY KEY (`Id`);
ALTER TABLE `characters_flavour`
ADD PRIMARY KEY (`id`);
ALTER TABLE `characters_gear`
ADD PRIMARY KEY (`id`);
ALTER TABLE `characters_jobs`
ADD PRIMARY KEY (`id`);
ALTER TABLE `characters_misc`
ADD PRIMARY KEY (`id`);
ALTER TABLE `characters_organs`
ADD PRIMARY KEY (`id`);
ALTER TABLE `characters_rlimb`
ADD PRIMARY KEY (`id`);
ALTER TABLE `characters_robot_flavour`
ADD PRIMARY KEY (`id`);
ALTER TABLE `characters_skills`
ADD PRIMARY KEY (`id`);
ALTER TABLE `player_preferences`
ADD PRIMARY KEY (`id`);
ALTER TABLE `ss13_characters`
ADD PRIMARY KEY (`id`);
ALTER TABLE `characters_data`
MODIFY `Id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `characters_flavour`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `characters_gear`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `characters_jobs`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `characters_misc`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `characters_organs`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `characters_rlimb`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `characters_robot_flavour`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `characters_skills`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `player_preferences`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `ss13_characters`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
/*!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 */;

View File

@@ -1,120 +0,0 @@
CREATE TABLE `ss13_admin` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ckey` varchar(32) NOT NULL,
`rank` varchar(32) NOT NULL DEFAULT 'Administrator',
`level` int(2) NOT NULL DEFAULT '0',
`flags` int(16) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
CREATE TABLE `ss13_admin_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`datetime` datetime NOT NULL,
`adminckey` varchar(32) NOT NULL,
`adminip` varchar(18) NOT NULL,
`log` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
CREATE TABLE `ss13_ban` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`bantime` datetime NOT NULL,
`serverip` varchar(32) NOT NULL,
`bantype` varchar(32) NOT NULL,
`reason` text NOT NULL,
`job` varchar(32) DEFAULT NULL,
`duration` int(11) NOT NULL,
`rounds` int(11) DEFAULT NULL,
`expiration_time` datetime NOT NULL,
`ckey` varchar(32) NOT NULL,
`computerid` varchar(32) NOT NULL,
`ip` varchar(32) NOT NULL,
`a_ckey` varchar(32) NOT NULL,
`a_computerid` varchar(32) NOT NULL,
`a_ip` varchar(32) NOT NULL,
`who` text NOT NULL,
`adminwho` text NOT NULL,
`edits` text,
`unbanned` tinyint(1) DEFAULT NULL,
`unbanned_datetime` datetime DEFAULT NULL,
`unbanned_ckey` varchar(32) DEFAULT NULL,
`unbanned_computerid` varchar(32) DEFAULT NULL,
`unbanned_ip` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
CREATE TABLE `ss13_feedback` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`time` datetime NOT NULL,
`round_id` int(8) NOT NULL,
`var_name` varchar(32) NOT NULL,
`var_value` int(16) DEFAULT NULL,
`details` text,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
CREATE TABLE `ss13_player` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ckey` varchar(32) NOT NULL,
`firstseen` datetime NOT NULL,
`lastseen` datetime NOT NULL,
`ip` varchar(18) NOT NULL,
`computerid` varchar(32) NOT NULL,
`lastadminrank` varchar(32) NOT NULL DEFAULT 'Player',
PRIMARY KEY (`id`),
UNIQUE KEY `ckey` (`ckey`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
CREATE TABLE `ss13_poll_option` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pollid` int(11) NOT NULL,
`text` varchar(255) NOT NULL,
`percentagecalc` tinyint(1) NOT NULL DEFAULT '1',
`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,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
CREATE TABLE `ss13_poll_question` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`polltype` varchar(16) NOT NULL DEFAULT 'OPTION',
`starttime` datetime NOT NULL,
`endtime` datetime NOT NULL,
`question` varchar(255) NOT NULL,
`adminonly` tinyint(1) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
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` varchar(18) NOT NULL,
`replytext` text NOT NULL,
`adminrank` varchar(32) NOT NULL DEFAULT 'Player',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
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(255) NOT NULL,
`ip` varchar(16) NOT NULL,
`adminrank` varchar(32) NOT NULL,
`rating` int(2) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
CREATE TABLE `ss13_privacy` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`datetime` datetime NOT NULL,
`ckey` varchar(32) NOT NULL,
`option` varchar(128) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;

View File

@@ -1,100 +0,0 @@
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';
CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ;
CREATE SCHEMA IF NOT EXISTS `tgstation` DEFAULT CHARACTER SET latin1 ;
USE `mydb` ;
USE `tgstation` ;
-- -----------------------------------------------------
-- Table `tgstation`.`death`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `ss13_death` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`pod` TEXT NOT NULL COMMENT 'Place of death' ,
`coord` TEXT NOT NULL COMMENT 'X, Y, Z POD' ,
`tod` DATETIME NOT NULL COMMENT 'Time of death' ,
`job` TEXT NOT NULL ,
`special` TEXT NOT NULL ,
`name` TEXT NOT NULL ,
`byondkey` TEXT NOT NULL ,
`laname` TEXT NOT NULL COMMENT 'Last attacker name' ,
`lakey` TEXT NOT NULL COMMENT 'Last attacker key' ,
`gender` TEXT NOT NULL ,
`bruteloss` INT(11) NOT NULL ,
`brainloss` INT(11) NOT NULL ,
`fireloss` INT(11) NOT NULL ,
`oxyloss` INT(11) NOT NULL ,
PRIMARY KEY (`id`) )
ENGINE = MyISAM
AUTO_INCREMENT = 3409
DEFAULT CHARACTER SET = latin1;
-- -----------------------------------------------------
-- Table `tgstation`.`karma`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `ss13_karma` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`spendername` TEXT NOT NULL ,
`spenderkey` TEXT NOT NULL ,
`receivername` TEXT NOT NULL ,
`receiverkey` TEXT NOT NULL ,
`receiverrole` TEXT NOT NULL ,
`receiverspecial` TEXT NOT NULL ,
`isnegative` TINYINT(1) NOT NULL ,
`spenderip` TEXT NOT NULL ,
`time` DATETIME NOT NULL ,
PRIMARY KEY (`id`) )
ENGINE = MyISAM
AUTO_INCREMENT = 943
DEFAULT CHARACTER SET = latin1;
-- -----------------------------------------------------
-- Table `tgstation`.`karmatotals`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `ss13_karmatotals` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`byondkey` TEXT NOT NULL ,
`karma` INT(11) NOT NULL ,
PRIMARY KEY (`id`) )
ENGINE = MyISAM
AUTO_INCREMENT = 244
DEFAULT CHARACTER SET = latin1;
-- -----------------------------------------------------
-- Table `tgstation`.`library`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `ss13_library` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`author` TEXT NOT NULL ,
`title` TEXT NOT NULL ,
`content` TEXT NOT NULL ,
`category` TEXT NOT NULL ,
PRIMARY KEY (`id`) )
ENGINE = MyISAM
AUTO_INCREMENT = 184
DEFAULT CHARACTER SET = latin1;
-- -----------------------------------------------------
-- Table `tgstation`.`population`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `ss13_population` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`playercount` INT(11) NULL DEFAULT NULL ,
`admincount` INT(11) NULL DEFAULT NULL ,
`time` DATETIME NOT NULL ,
PRIMARY KEY (`id`) )
ENGINE = MyISAM
AUTO_INCREMENT = 2544
DEFAULT CHARACTER SET = latin1;
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

View File

@@ -893,13 +893,15 @@
#include "code\modules\cciaa\cciaa_items.dm"
#include "code\modules\client\client defines.dm"
#include "code\modules\client\client procs.dm"
#include "code\modules\client\client_saveSQL.dm"
#include "code\modules\client\preferences.dm"
#include "code\modules\client\preferences_ambience.dm"
#include "code\modules\client\preferences_factions.dm"
#include "code\modules\client\preferences_gear.dm"
#include "code\modules\client\preferences_save_migration.dm"
#include "code\modules\client\preferences_savefile.dm"
#include "code\modules\client\preferences_spawnpoints.dm"
#include "code\modules\client\preferences_sql.dm"
#include "code\modules\client\preferences_system_control.dm"
#include "code\modules\client\preferences_toggles.dm"
#include "code\modules\clothing\clothing.dm"
#include "code\modules\clothing\ears\skrell.dm"

View File

@@ -155,7 +155,8 @@ var/list/gamemode_cache = list()
var/admin_legacy_system = 0 //Defines whether the server uses the legacy admin system with admins.txt or the SQL system. Config option in config.txt
var/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt
var/use_age_restriction_for_jobs = 0 //Do jobs use account age restrictions? --requires database
var/sql_whitelists = 0 //Defined whether the server uses an SQL based whitelist system, or the legacy one with two .txts. Config option in config.txt
var/sql_whitelists = 0 //Defined whether the server uses an SQL based whitelist system, or the legacy one with two .txts. Config option in config.txt
var/sql_saves = 0 //Defines whether the server uses an SQL based character and preference saving system. Config option in config.txt
var/simultaneous_pm_warning_timeout = 100
@@ -684,6 +685,9 @@ var/list/gamemode_cache = list()
if("webint_url")
config.webint_url = value
if("sql_saves")
config.sql_saves = 1
else
log_misc("Unknown setting in configuration: '[name]'")

View File

@@ -123,7 +123,7 @@ DBQuery/proc/Execute(var/list/argument_list = null, var/pass_not_found = 0, sql_
var/result = _dm_db_execute(_db_query, sql_query, db_connection._db_con, cursor_handler, null)
if (ErrorMsg())
log_debug("SQL Error: '[ErrorMsg()]'")
error("SQL Error: '[ErrorMsg()]'")
return result
@@ -207,6 +207,7 @@ DBQuery/proc/SetConversion(column,conversion)
argument = "NULL"
else
log_debug("parseArguments() failed! Cannot identify argument!")
log_debug("Placeholder: '[placeholder]'. Argument: '[argument]'")
return 0
query_to_parse = replacetextEx(query_to_parse, placeholder, argument)

View File

@@ -538,7 +538,7 @@ var/list/admin_verbs_cciaa = list(
prefs.ooccolor = input(src, "Please select your OOC colour.", "OOC colour") as color
else if(response == "Reset to default")
prefs.ooccolor = initial(prefs.ooccolor)
prefs.save_preferences()
prefs.handle_preferences_save(src)
feedback_add_details("admin_verb","OC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
@@ -907,6 +907,7 @@ var/list/admin_verbs_cciaa = list(
usr << "You now will get attack log messages"
else
usr << "You now won't get attack log messages"
prefs.handle_preferences_save(src)
/client/proc/toggleghostwriters()

View File

@@ -46,5 +46,6 @@
var/related_accounts_ip = "Requires database" //So admins know why it isn't working - Used to determine what other accounts previously logged in from this ip
var/related_accounts_cid = "Requires database" //So admins know why it isn't working - Used to determine what other accounts previously logged in from this computer id
var/whitelist_status = 0 //Used to determine what whitelists the player has access to. Uses bitflag values!
var/need_saves_migrated = "Requires database" //Used to determine whether or not the ckey needs their saves migrated over to the database. Default is 0 upon successful connection.
preload_rsc = 0 // This is 0 so we can set it to an URL once the player logs in and have them download the resources from a different server.

View File

@@ -200,6 +200,8 @@
admins += src
holder.owner = src
log_client_to_db()
//preferences datum - also holds some persistant data for the client (because we may as well keep these datums to a minimum)
prefs = preferences_datums[ckey]
if(!prefs)
@@ -234,8 +236,6 @@
warnings_alert()
log_client_to_db()
check_linking_requests()
send_resources()
@@ -280,6 +280,22 @@
else
return -1
/client/verb/test_shit()
set category = "OOC"
set name = "Test Muh Shit"
var/savefile/S = new /savefile(src.prefs.path)
if (!S)
testing("Error opening save file!")
return
S.cd = "/"
testing("Starting to cycle through the dirs!")
for (var/a in S.dir)
testing("Found a dir! [a]")
testing("Cycled through all the dirs!")
/client/proc/log_client_to_db()
@@ -292,7 +308,7 @@
var/sql_ckey = sql_sanitize_text(src.ckey)
var/DBQuery/query = dbcon.NewQuery("SELECT id, datediff(Now(),firstseen) as age, whitelist_status FROM ss13_player WHERE ckey = '[sql_ckey]'")
var/DBQuery/query = dbcon.NewQuery("SELECT id, datediff(Now(),firstseen) as age, whitelist_status, migration_status FROM ss13_player WHERE ckey = '[sql_ckey]'")
query.Execute()
var/sql_id = 0
player_age = 0 // New players won't have an entry so knowing we have a connection we set this to zero to be updated if their is a record.
@@ -300,6 +316,7 @@
sql_id = query.item[1]
player_age = text2num(query.item[2])
whitelist_status = text2num(query.item[3])
need_saves_migrated = text2num(query.item[4])
break
var/DBQuery/query_ip = dbcon.NewQuery("SELECT ckey FROM ss13_player WHERE ip = '[address]'")

View File

@@ -1,732 +0,0 @@
//handles saving to SQL Format
//MAKE SURE YOU KEEP THIS UP TO DATE!
//if the db can't be updated, return 0
//if the db was updated, return 1
/datum/preferences/proc/SQLsave_character(var/cslot)
char_slot = cslot
if(!cslot)
log_debug("invalid slot")
return 0
for(var/ckey in preferences_datums)
var/datum/preferences/D = preferences_datums[ckey]
if(D == src)
log_debug("Ckey is [ckey]")
establish_db_connection(dbcon)
if(!dbcon.IsConnected())
return 0
else
log_debug("db connected, real name is [real_name]")
if(!getCharId(ckey))
log_debug("New Character")
query = dbcon.NewQuery("INSERT INTO ss13_characters (ckey, slot) VALUES ('[ckey]', '[cslot]')")
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
getCharId(ckey)
InsertCharData()
InsertJobsData()
InsertFlavourData()
InsertRobotFlavourData()
InsertMiscData()
InsertSkillsData()
InsertGearData()
InsertOrgansData()
else
log_debug("ID = [char_id]")
log_debug("Update entry")
UpdateCharData()
UpdateJobsData()
UpdateFlavourData()
UpdateRobotFlavourData()
UpdateMiscData()
UpdateSkillsData()
UpdateGearData()
UpdateOrgansData()
TextQuery = "UPDATE SS13_characters SET Character_Name = (SELECT name FROM characters_data WHERE char_id = '[char_id]') WHERE id = '[char_id]'"
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
log_debug("Save query executed")
return 1
log_debug("No ckey in datums")
return 0
/datum/preferences/proc/SQLload_character(var/slot, var/pckey)
establish_db_connection(dbcon)
if(!dbcon.IsConnected())
return 0
char_slot = slot
if(!getCharId(pckey))
return 0
log_debug("Loading character ID [char_id] from slot [char_slot]")
if(LoadCharData())
if(LoadJobsData())
if(LoadFlavourData())
if(LoadRobotFlavourData())
if(LoadMiscData())
if(LoadSkillsData())
if(LoadGearData())
if(LoadOrgansData())
SanitizeCharacter()
return 1
return 0
/datum/preferences/proc/getCharId(var/ckey)
TextQuery = "SELECT id FROM ss13_characters WHERE ckey='[ckey]' AND slot = '[char_slot]'"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
log_debug("Query ready")
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
var/rowDebug = query.RowCount()
log_debug("Query executed, [rowDebug] rows")
if(!query.RowCount())
return 0
query.NextRow()
char_id = query.item[1]
log_debug("GetCharId : [char_id]")
return char_id
/datum/preferences/proc/InsertCharData()
log_debug("Insert Char Data")
TextQuery = "INSERT INTO characters_data (age, backbag, b_type, char_id, eyes_B, eyes_G, eyes_R, facial_B, facial_G, facial_R, facial_style, "
TextQuery += "gender, hair_B, hair_G, hair_R, hair_style, isRandom, language, name, OOC,skin_B, skin_G, skin_R, skin_tone, spawnpoint, species, undershirt, underwear) VALUES "
TextQuery += "('[age]', '[backbag]', '[b_type]', '[char_id]', '[b_eyes]', '[g_eyes]', '[r_eyes]', '[b_facial]', '[g_facial]', '[r_facial]', '[f_style]', "
TextQuery += "'[gender]', '[b_hair]', '[g_hair]', '[r_hair]', '[h_style]', '[be_random_name]', '[language]', '[real_name]', "
TextQuery += "'[metadata]', '[b_skin]', '[g_skin]', '[r_skin]', '[s_tone]', '[spawnpoint]', '[species]', '[undershirt]', '[underwear]')"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
/datum/preferences/proc/UpdateCharData()
log_debug("Update Char Data")
query = dbcon.NewQuery("SELECT id FROM characters_data WHERE char_id = '[char_id]'")
query.Execute()
if(!query.RowCount())
InsertCharData()
TextQuery = "UPDATE characters_data SET age = '[age]', backbag='[backbag]', b_type='[b_type]', eyes_B = '[b_eyes]', eyes_G='[g_eyes]', eyes_R='[r_eyes]',"
TextQuery += "facial_B='[b_facial]', facial_G='[g_facial]', facial_R='[r_facial]', facial_style='[f_style]', gender = '[gender]', hair_B='[b_hair]', hair_G='[g_hair]',"
TextQuery += "hair_R='[r_hair]', hair_style='[h_style]', isRandom='[be_random_name]', language='[language]', name='[real_name]', OOC='[metadata]',skin_B='[b_skin]', skin_G='[g_skin]',"
TextQuery += "skin_R='[r_skin]', skin_tone='[s_tone]', spawnpoint='[spawnpoint]', species='[species]', undershirt='[undershirt]', underwear='[underwear]'"
TextQuery += "WHERE char_id = '[char_id]'"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
/datum/preferences/proc/LoadCharData()
log_debug("Load char data")
TextQuery = "SELECT age, backbag, b_type, eyes_B, eyes_G, eyes_R, facial_B, facial_G, facial_R, facial_style, gender, "
TextQuery += "hair_B, hair_G, hair_R, hair_style, isRandom, language, name, OOC, skin_B, skin_G, skin_R, skin_tone, spawnpoint, species, undershirt, underwear "
TextQuery += "FROM characters_data WHERE char_id = [char_id]"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
if(!query.RowCount())
return 0
log_debug("Load query executed successfully")
query.NextRow()
age = text2num(query.item[1])
backbag = text2num(query.item[2])
b_type = text2num(query.item[3])
b_eyes = text2num(query.item[4])
g_eyes = text2num(query.item[5])
r_eyes = text2num(query.item[6])
b_facial = text2num(query.item[7])
g_facial = text2num(query.item[8])
r_facial = text2num(query.item[9])
f_style = query.item[10]
gender = query.item[11]
b_hair = text2num(query.item[12])
g_hair = text2num(query.item[13])
r_hair = text2num(query.item[14])
h_style = query.item[15]
be_random_name = text2num(query.item[16])
language = query.item[17]
real_name = query.item[18]
metadata = query.item[19]
b_skin = text2num(query.item[20])
g_skin = text2num(query.item[21])
r_skin = text2num(query.item[22])
s_tone = text2num(query.item[23])
spawnpoint = query.item[24]
species = query.item[25]
undershirt = query.item[26]
underwear = query.item[27]
return 1
/datum/preferences/proc/InsertJobsData()
log_debug("Insert jobs")
var/alt_titles_list = list2params(player_alt_titles)
TextQuery = "INSERT INTO characters_jobs (char_id, Alternate, civ_high, civ_med, civ_low, medsci_high, medsci_med, medsci_low, engsec_high, engsec_med, engsec_low, alt_titles) "
TextQuery += " VALUES ('[char_id]','[alternate_option]', '[job_civilian_high]', '[job_civilian_med]', '[job_civilian_low]', '[job_medsci_high]', '[job_medsci_med]', '[job_medsci_low]', "
TextQuery += "'[job_engsec_high]', '[job_engsec_med]', '[job_engsec_low]', '[alt_titles_list]')"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
/datum/preferences/proc/UpdateJobsData()
log_debug("update jobs")
query = dbcon.NewQuery("SELECT id FROM characters_jobs WHERE char_id = '[char_id]'")
query.Execute()
if(!query.RowCount())
InsertJobsData()
var/alt_titles_list = list2params(player_alt_titles)
TextQuery = "UPDATE characters_jobs SET Alternate='[alternate_option]', civ_high='[job_civilian_high]', civ_med='[job_civilian_med]', civ_low='[job_civilian_low]', "
TextQuery += "medsci_high='[job_medsci_high]', medsci_med='[job_medsci_med]', medsci_low='[job_medsci_low]', "
TextQuery += "engsec_high='[job_engsec_high]', engsec_med='[job_engsec_med]', engsec_low='[job_engsec_low]', alt_titles = '[alt_titles_list]' WHERE char_id = [char_id] "
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
/datum/preferences/proc/LoadJobsData()
log_debug("load_jobs")
TextQuery = "SELECT * FROM characters_jobs WHERE char_id = [char_id]"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
if(!query.RowCount())
return 0
log_debug("Load query executed successfully")
query.NextRow()
alternate_option = text2num(query.item[3])
job_civilian_high = text2num(query.item[4])
job_civilian_med = text2num(query.item[5])
job_civilian_low = text2num(query.item[6])
job_medsci_high = text2num(query.item[7])
job_medsci_med = text2num(query.item[8])
job_medsci_low = text2num(query.item[9])
job_engsec_high = text2num(query.item[10])
job_engsec_med = text2num(query.item[11])
job_engsec_low = text2num(query.item[12])
player_alt_titles = params2list(query.item[13])
return 1
/datum/preferences/proc/InsertFlavourData()
log_debug("insert flavour")
TextQuery = "INSERT INTO characters_flavour (char_id, generals, head, face, eyes, torso, arms, hands, legs, feet) "
TextQuery += " VALUES ('[char_id]','[flavor_texts["general"]]', '[flavor_texts["head"]]', '[flavor_texts["face"]]', '[flavor_texts["eyes"]]', '[flavor_texts["torso"]]', "
TextQuery += "'[flavor_texts["arms"]]', '[flavor_texts["hands"]]', '[flavor_texts["legs"]]', '[flavor_texts["feet"]]')"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
/datum/preferences/proc/UpdateFlavourData()
log_debug("update flavour")
query = dbcon.NewQuery("SELECT id FROM characters_data WHERE char_id = '[char_id]'")
query.Execute()
if(!query.RowCount())
InsertFlavourData()
TextQuery = "UPDATE characters_flavour SET generals='[flavor_texts["general"]]', head='[flavor_texts["head"]]', face='[flavor_texts["face"]]', eyes='[flavor_texts["eyes"]]', "
TextQuery += "torso='[flavor_texts["torso"]]', arms='[flavor_texts["arms"]]', hands='[flavor_texts["hands"]]', legs='[flavor_texts["legs"]]', feet='[flavor_texts["feet"]]' "
TextQuery += "WHERE char_id = [char_id]"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
/datum/preferences/proc/LoadFlavourData()
log_debug("load flavour")
TextQuery = "SELECT * FROM characters_flavour WHERE char_id = [char_id]"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
if(!query.RowCount())
return 0
log_debug("Load query executed successfully")
query.NextRow()
flavor_texts["general"] = query.item[3]
flavor_texts["head"] = query.item[4]
flavor_texts["face"] = query.item[5]
flavor_texts["eyes"] = query.item[6]
flavor_texts["torso"] = query.item[7]
flavor_texts["arms"] = query.item[8]
flavor_texts["hands"]= query.item[9]
flavor_texts["legs"] = query.item[10]
flavor_texts["feet"] = query.item[11]
return 1
/datum/preferences/proc/InsertRobotFlavourData()
log_debug("insert robot")
TextQuery = "INSERT INTO characters_robot_flavour (char_id, Default_Robot, Standard, Engineering, Construction, Surgeon, Crisis, Miner, Janitor, Service, Clerical, Security, Research) "
TextQuery += " VALUES ('[char_id]','[flavour_texts_robot["Default"]]', '[flavour_texts_robot["Standard"]]', '[flavour_texts_robot["Engineering"]]', '[flavour_texts_robot["Construction"]]', "
TextQuery += "'[flavour_texts_robot["Surgeon"]]', '[flavour_texts_robot["Crisis"]]', '[flavour_texts_robot["Miner"]]', '[flavour_texts_robot["Janitor"]]', '[flavour_texts_robot["Service"]]', "
TextQuery += "'[flavour_texts_robot["Clerical"]]', '[flavour_texts_robot["Security"]]','[flavour_texts_robot["Research"]]')"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
/datum/preferences/proc/UpdateRobotFlavourData()
log_debug("update robot")
query = dbcon.NewQuery("SELECT id FROM characters_robot_flavour WHERE char_id = '[char_id]'")
query.Execute()
if(!query.RowCount())
InsertRobotFlavourData()
TextQuery = "UPDATE characters_robot_flavour SET Default_Robot='[flavour_texts_robot["Default"]]', Standard='[flavour_texts_robot["Standard"]]', Engineering='[flavour_texts_robot["Engineering"]]', "
TextQuery += "Construction='[flavour_texts_robot["Construction"]]', Surgeon='[flavour_texts_robot["Surgeon"]]', Crisis='[flavour_texts_robot["Crisis"]]', Miner='[flavour_texts_robot["Miner"]]', "
TextQuery += "Janitor='[flavour_texts_robot["Janitor"]]', Service='[flavour_texts_robot["Service"]]', Clerical='[flavour_texts_robot["Clerical"]]', "
TextQuery += "Security='[flavour_texts_robot["Security"]]', Research='[flavour_texts_robot["Research"]]' WHERE char_id = [char_id]"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
/datum/preferences/proc/LoadRobotFlavourData()
log_debug("load robot")
TextQuery = "SELECT * FROM characters_robot_flavour WHERE char_id = [char_id]"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
if(!query.RowCount())
return 0
log_debug("Load query executed successfully")
query.NextRow()
flavour_texts_robot["Default"] = query.item[3]
flavour_texts_robot["Standard"] = query.item[4]
flavour_texts_robot["Engineering"] = query.item[5]
flavour_texts_robot["Construction"] = query.item[6]
flavour_texts_robot["Surgeon"] = query.item[7]
flavour_texts_robot["Crisis"] = query.item[8]
flavour_texts_robot["Miner"] = query.item[9]
flavour_texts_robot["Janitor"] = query.item[10]
flavour_texts_robot["Service"] = query.item[11]
flavour_texts_robot["Clerical"] = query.item[12]
flavour_texts_robot["Security"] = query.item[13]
flavour_texts_robot["Research"] = query.item[14]
return 1
/datum/preferences/proc/InsertMiscData()
log_debug("insert misc")
sanitizePrefs()
TextQuery = "INSERT INTO characters_misc (char_id, med_rec, sec_rec, gen_rec, disab, used_skill, skills_spec, "
TextQuery += "home_sys, citizen, faction, religion, NT_relation, uplink_loc, exploit_rec) VALUES ("
TextQuery += "'[char_id]', '[med_record]', '[sec_record]', '[gen_record]', '[disabilities]', '[used_skillpoints]', "
TextQuery += "'[skill_specialization]', '[home_system]', '[citizenship]', '[faction]', '[religion]', '[nanotrasen_relation]', "
TextQuery += "'[uplinklocation]', '[exploit_record]')"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
/datum/preferences/proc/UpdateMiscData()
log_debug("update misc")
query = dbcon.NewQuery("SELECT id FROM characters_misc WHERE char_id = '[char_id]'")
query.Execute()
if(!query.RowCount())
InsertMiscData()
TextQuery = "UPDATE characters_misc SET med_rec='[med_record]', sec_rec='[sec_record]', gen_rec='[gen_record]', disab='[disabilities]', "
TextQuery += "used_skill='[used_skillpoints]', skills_spec='[skill_specialization]', "
TextQuery += "home_sys='[home_system]', citizen='[citizenship]', faction='[faction]', religion='[religion]', NT_relation='[nanotrasen_relation]', uplink_loc='[uplinklocation]', "
TextQuery += "exploit_rec='[exploit_record]' WHERE char_id = [char_id]"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
/datum/preferences/proc/LoadMiscData()
log_debug("load_misc")
TextQuery = "SELECT * FROM characters_misc WHERE char_id = [char_id]"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
if(!query.RowCount())
return 0
log_debug("Load query executed successfully")
query.NextRow()
med_record = query.item[3]
sec_record = query.item[4]
gen_record = query.item[5]
disabilities = text2num(query.item[6])
used_skillpoints = text2num(query.item[7])
skill_specialization = query.item[8]
home_system = query.item[9]
citizenship = query.item[10]
faction = query.item[11]
religion = query.item[12]
nanotrasen_relation = query.item[13]
uplinklocation = query.item[14]
exploit_record = query.item[15]
return 1
/datum/preferences/proc/InsertSkillsData()
log_debug("insert skills")
TextQuery = "INSERT INTO characters_skills (char_id, Command, Botany, Cooking, Close_Combat, Weapons_Expertise, Forensics, NanoTrasen_Law, EVA, "
TextQuery += "Construction, Electrical, Atmos, Engines, Heavy_Mach, Complex_Devices, Information_Tech, Genetics, Chemistry, Science, Medicine, Anatomy, Virology) VALUES "
TextQuery += "('[char_id]', '[skills["management"]]', '[skills["botany"]]', '[skills["cooking"]]', '[skills["combat"]]', '[skills["weapons"]]', '[skills["forensics"]]', '[skills["law"]]', '[skills["EVA"]]',"
TextQuery += " '[skills["construction"]]', '[skills["electrical"]]', '[skills["atmos"]]', '[skills["engines"]]', '[skills["pilot"]]', '[skills["devices"]]', '[skills["computer"]]', '[skills["genetics"]]',"
TextQuery += " '[skills["chemistry"]]', '[skills["science"]]', '[skills["medical"]]', '[skills["anatomy"]]', '[skills["virology"]]')"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
/datum/preferences/proc/UpdateSkillsData()
log_debug("update skills")
query = dbcon.NewQuery("SELECT id FROM characters_skills WHERE char_id = '[char_id]'")
query.Execute()
if(!query.RowCount())
InsertSkillsData()
TextQuery = "UPDATE characters_skills SET Command='[skills["management"]]', Botany='[skills["botany"]]', Cooking='[skills["cooking"]]', Close_Combat='[skills["combat"]]', "
TextQuery += "Weapons_Expertise='[skills["weapons"]]', Forensics='[skills["forensics"]]', NanoTrasen_Law='[skills["law"]]', EVA='[skills["EVA"]]', "
TextQuery += "Construction='[skills["construction"]]', Electrical='[skills["electrical"]]', Atmos='[skills["atmos"]]', Engines='[skills["engines"]]', Heavy_Mach='[skills["pilot"]]', Complex_Devices='[skills["devices"]]', "
TextQuery += "Information_Tech='[skills["computer"]]', Genetics='[skills["genetics"]]', Chemistry='[skills["chemistry"]]', Science='[skills["science"]]', Medicine='[skills["medical"]]', "
TextQuery += "Anatomy='[skills["anatomy"]]', Virology='[skills["virology"]]' WHERE char_id = '[char_id]'"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
/datum/preferences/proc/LoadSkillsData()
log_debug("load skills")
TextQuery = "SELECT * FROM characters_skills WHERE char_id = '[char_id]'"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
if(!query.RowCount())
return 0
log_debug("Load query executed successfully")
query.NextRow()
skills["management"] = text2num(query.item[3])
skills["botany"] = text2num(query.item[4])
skills["cooking"] = text2num(query.item[5])
skills["combat"] = text2num(query.item[6])
skills["weapons"] = text2num(query.item[7])
skills["forensics"] = text2num(query.item[8])
skills["law"] = text2num(query.item[9])
skills["EVA"] = text2num(query.item[10])
skills["construction"] = text2num(query.item[11])
skills["electrical"] = text2num(query.item[12])
skills["atmos"] = text2num(query.item[13])
skills["engines"] = text2num(query.item[14])
skills["pilot"] = text2num(query.item[15])
skills["devices"] = text2num(query.item[16])
skills["computer"] = text2num(query.item[17])
skills["genetics"] = text2num(query.item[18])
skills["chemistry"] = text2num(query.item[19])
skills["science"] = text2num(query.item[20])
skills["medical"] = text2num(query.item[21])
skills["anatomy"] = text2num(query.item[22])
skills["virology"] = text2num(query.item[23])
return 1
/datum/preferences/proc/InsertGearData()
log_debug("insert gear")
//var/loop_id = 0
var/gear_list = list2params(gear)
//test
TextQuery = "INSERT INTO characters_gear (char_id, gear) VALUES ('[char_id]', '[gear_list]')"
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
/datum/preferences/proc/UpdateGearData()
log_debug("update gear")
query = dbcon.NewQuery("SELECT id FROM characters_gear WHERE char_id = '[char_id]'")
query.Execute()
if(!query.RowCount())
InsertGearData()
//var/loop_id = 0
var/gear_list = list2params(gear)
TextQuery = "UPDATE characters_gear SET gear='[gear_list]' WHERE char_id = '[char_id]'"
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
/datum/preferences/proc/LoadGearData()
log_debug("load gear")
TextQuery = "SELECT * FROM characters_gear WHERE char_id = '[char_id]'"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
if(!query.RowCount())
return 0
log_debug("Load query executed successfully")
query.NextRow()
gear = params2list(query.item[3])
return 1
/datum/preferences/proc/InsertOrgansData()
log_debug("insert organs")
TextQuery = "INSERT INTO characters_organs (char_id, l_leg, r_leg, l_arm, r_arm, l_foot, r_foot, l_hand, r_hand, heart, eyes) VALUES ("
TextQuery += "'[char_id]', '[organ_data["l_leg"]]', '[organ_data["r_leg"]]', '[organ_data["l_arm"]]', '[organ_data["r_arm"]]', '[organ_data["l_foot"]]', '[organ_data["r_foot"]]', "
TextQuery += "'[organ_data["l_hand"]]', '[organ_data["r_hand"]]', '[organ_data["heart"]]', '[organ_data["eyes"]]')"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
InsertRorgansData()
return 1
/datum/preferences/proc/UpdateOrgansData()
log_debug("update organs")
query = dbcon.NewQuery("SELECT id FROM characters_organs WHERE char_id = '[char_id]'")
query.Execute()
if(!query.RowCount())
InsertOrgansData()
TextQuery = "UPDATE characters_organs SET char_id='[char_id]', l_leg='[organ_data["l_leg"]]', r_leg='[organ_data["r_leg"]]', l_arm='[organ_data["l_arm"]]', r_arm='[organ_data["r_arm"]]', "
TextQuery += "l_foot='[organ_data["l_foot"]]', r_foot='[organ_data["r_foot"]]', l_hand='[organ_data["l_hand"]]', r_hand='[organ_data["r_hand"]]', heart='[organ_data["heart"]]', eyes='[organ_data["eyes"]]'"
TextQuery += " WHERE char_id='[char_id]'"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
UpdateRorgansData()
return 1
/datum/preferences/proc/LoadOrgansData()
log_debug("load organs")
TextQuery = "SELECT * FROM characters_organs WHERE char_id = '[char_id]'"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
if(!query.RowCount())
return 0
log_debug("Load query executed successfully")
query.NextRow()
organ_data["l_leg"] = query.item[3]
organ_data["r_leg"] = query.item[4]
organ_data["l_arm"] = query.item[5]
organ_data["r_arm"] = query.item[6]
organ_data["l_foot"] = query.item[7]
organ_data["r_foot"] = query.item[8]
organ_data["l_hand"] = query.item[9]
organ_data["r_hand"] = query.item[10]
organ_data["heart"] = query.item[11]
organ_data["eyes"] = query.item[12]
LoadRorgansData()
return 1
/datum/preferences/proc/InsertRorgansData()
log_debug("insert robotics organs")
TextQuery = "INSERT INTO characters_rlimb (char_id, l_leg, r_leg, l_arm, r_arm, l_foot, r_foot, l_hand, r_hand) VALUES ("
TextQuery += "'[char_id]', '[rlimb_data["l_leg"]]', '[rlimb_data["r_leg"]]', '[rlimb_data["l_arm"]]', '[rlimb_data["r_arm"]]', '[rlimb_data["l_foot"]]', '[rlimb_data["r_foot"]]', "
TextQuery += "'[rlimb_data["l_hand"]]', '[rlimb_data["r_hand"]]')"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
/datum/preferences/proc/UpdateRorgansData()
log_debug("update robotics organs")
TextQuery = "UPDATE characters_rlimb SET char_id='[char_id]', l_leg='[rlimb_data["l_leg"]]', r_leg='[rlimb_data["r_leg"]]', l_arm='[rlimb_data["l_arm"]]', r_arm='[rlimb_data["r_arm"]]', "
TextQuery += "l_foot='[rlimb_data["l_foot"]]', r_foot='[rlimb_data["r_foot"]]', l_hand='[rlimb_data["l_hand"]]', r_hand='[rlimb_data["r_hand"]]'"
TextQuery += " WHERE char_id = '[char_id]'"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
/datum/preferences/proc/LoadRorgansData()
log_debug("load robotics organs")
TextQuery = "SELECT * FROM characters_rlimb WHERE char_id = '[char_id]'"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
if(!query.RowCount())
return 0
log_debug("Load query executed successfully")
query.NextRow()
rlimb_data["l_leg"] = query.item[3]
rlimb_data["r_leg"] = query.item[4]
rlimb_data["l_arm"] = query.item[5]
rlimb_data["r_arm"] = query.item[6]
rlimb_data["l_foot"] = query.item[7]
rlimb_data["r_foot"] = query.item[8]
rlimb_data["l_hand"] = query.item[9]
rlimb_data["r_hand"] = query.item[10]
return 1
/datum/preferences/proc/SavePrefData(var/ckey)
log_debug("Save pref data")
TextQuery = "SELECT * FROM player_preferences WHERE ckey = '[ckey]'"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(!query.RowCount())
sanitizePrefs()
TextQuery = "INSERT INTO player_preferences (ckey, ooccolor, lastchangelog, UI_style, default_slot, toggles, UI_style_color, UI_style_alpha, be_special) "
TextQuery += "VALUES ('[ckey]', '[ooccolor]','[lastchangelog]', '[UI_style]', '[default_slot]', '[toggles]', '[UI_style_color]', '[UI_style_alpha]','[be_special]')"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
else
return UpdatePrefData(ckey)
/datum/preferences/proc/UpdatePrefData(var/ckey)
log_debug("Update pref data")
sanitizePrefs()
TextQuery = "UPDATE player_preferences SET ooccolor='[ooccolor]', lastchangelog='[lastchangelog]', UI_style='[UI_style]', default_slot='[default_slot]', toggles='[toggles]', "
TextQuery += "UI_style_color='[UI_style_color]', UI_style_alpha='[UI_style_alpha]', be_special='[be_special]' WHERE ckey = '[ckey]'"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
return 1
/datum/preferences/proc/LoadPrefData(var/ckey)
log_debug("load pref data")
establish_db_connection(dbcon)
if(!dbcon.IsConnected())
return 0
TextQuery = "SELECT * FROM player_preferences WHERE ckey = '[ckey]'"
log_debug(TextQuery)
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(dbcon.ErrorMsg())
log_debug(dbcon.ErrorMsg())
if(!query.RowCount())
return 0
log_debug("Load query executed successfully")
query.NextRow()
ooccolor = query.item[3]
lastchangelog = text2num(query.item[4])
UI_style = query.item[5]
default_slot = text2num(query.item[6])
toggles = text2num(query.item[7])
UI_style_color = query.item[8]
UI_style_alpha = text2num(query.item[9])
be_special = text2num(query.item[10])
sanitizePrefs()
return 1
/datum/preferences/proc/sanitizePrefs()
ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor))
lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
UI_style = sanitize_inlist(UI_style, list("White", "Midnight","Orange","old"), initial(UI_style))
be_special = sanitize_integer(be_special, 0, 65535, initial(be_special))
default_slot = sanitize_integer(default_slot, 1, config.character_slots, initial(default_slot))
toggles = sanitize_integer(toggles, 0, 65535, initial(toggles))
UI_style_color = sanitize_hexcolor(UI_style_color, initial(UI_style_color))
UI_style_alpha = sanitize_integer(UI_style_alpha, 0, 255, initial(UI_style_alpha))
return 1
/datum/preferences/proc/SanitizeCharacter()
metadata = sanitize_text(metadata, initial(metadata))
real_name = sanitizeName(real_name)
if(isnull(species) || !(species in playable_species))
species = "Human"
if(isnum(underwear))
var/list/undies = gender == MALE ? underwear_m : underwear_f
underwear = undies[undies[underwear]]
if(isnum(undershirt))
undershirt = undershirt_t[undershirt_t[undershirt]]
if(isnull(language)) language = "None"
if(isnull(spawnpoint)) spawnpoint = "Arrivals Shuttle"
if(isnull(nanotrasen_relation)) nanotrasen_relation = initial(nanotrasen_relation)
if(!real_name) real_name = random_name(gender)
be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name))
gender = sanitize_gender(gender)
age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age))
r_hair = sanitize_integer(r_hair, 0, 255, initial(r_hair))
g_hair = sanitize_integer(g_hair, 0, 255, initial(g_hair))
b_hair = sanitize_integer(b_hair, 0, 255, initial(b_hair))
r_facial = sanitize_integer(r_facial, 0, 255, initial(r_facial))
g_facial = sanitize_integer(g_facial, 0, 255, initial(g_facial))
b_facial = sanitize_integer(b_facial, 0, 255, initial(b_facial))
s_tone = sanitize_integer(s_tone, -185, 34, initial(s_tone))
r_skin = sanitize_integer(r_skin, 0, 255, initial(r_skin))
g_skin = sanitize_integer(g_skin, 0, 255, initial(g_skin))
b_skin = sanitize_integer(b_skin, 0, 255, initial(b_skin))
h_style = sanitize_inlist(h_style, hair_styles_list, initial(h_style))
f_style = sanitize_inlist(f_style, facial_hair_styles_list, initial(f_style))
r_eyes = sanitize_integer(r_eyes, 0, 255, initial(r_eyes))
g_eyes = sanitize_integer(g_eyes, 0, 255, initial(g_eyes))
b_eyes = sanitize_integer(b_eyes, 0, 255, initial(b_eyes))
backbag = sanitize_integer(backbag, 1, backbaglist.len, initial(backbag))
b_type = sanitize_text(b_type, initial(b_type))
alternate_option = sanitize_integer(alternate_option, 0, 2, initial(alternate_option))
job_civilian_high = sanitize_integer(job_civilian_high, 0, 65535, initial(job_civilian_high))
job_civilian_med = sanitize_integer(job_civilian_med, 0, 65535, initial(job_civilian_med))
job_civilian_low = sanitize_integer(job_civilian_low, 0, 65535, initial(job_civilian_low))
job_medsci_high = sanitize_integer(job_medsci_high, 0, 65535, initial(job_medsci_high))
job_medsci_med = sanitize_integer(job_medsci_med, 0, 65535, initial(job_medsci_med))
job_medsci_low = sanitize_integer(job_medsci_low, 0, 65535, initial(job_medsci_low))
job_engsec_high = sanitize_integer(job_engsec_high, 0, 65535, initial(job_engsec_high))
job_engsec_med = sanitize_integer(job_engsec_med, 0, 65535, initial(job_engsec_med))
job_engsec_low = sanitize_integer(job_engsec_low, 0, 65535, initial(job_engsec_low))
if(!skills) skills = list()
if(!used_skillpoints) used_skillpoints= 0
if(isnull(disabilities)) disabilities = 0
if(!player_alt_titles) player_alt_titles = new()
if(!organ_data) src.organ_data = list()
if(!rlimb_data) src.rlimb_data = list()
if(!gear) src.gear = list()
if(!home_system) home_system = "Unset"
if(!citizenship) citizenship = "None"
if(!faction) faction = "None"
if(!religion) religion = "None"
return 1

View File

@@ -32,7 +32,7 @@ datum/preferences
//doohickeys for savefiles
var/path
var/default_slot = 1 //Holder so it doesn't default to slot 1, rather the last one used
var/current_slot = 1
var/current_character = 0 //SQL character ID.
var/savefile_version = 0
//non-preference stuff
@@ -135,37 +135,36 @@ datum/preferences
var/metadata = ""
var/slot_name = ""
//SQL Save system vars
var/chardata[]
var/jobsdata[]
var/flavourdata[]
var/miscdata[]
var/DBQuery/query
var/TextQuery
var/char_id
var/char_slot
/datum/preferences/New(client/C)
b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+")
if (config.sql_saves && C.need_saves_migrated)
var/dat = "<center>The server attempted to automatically migrate your saves from the old file-system onto an SQL database.<br>"
dat += "This operation was "
if (!handle_saves_migration(C))
error("Failed migrating saves from [C.ckey] to the database!")
dat += "<font color='red'><b>unsuccessful!</b></font><br><br>"
dat += "There was most likely an error in one of the SQL commands used to handle this migration. Do not worry: your saves are still safe in the old system and retreivable. Please contact Skull132 <b>immediately</b> in order to have the issue resolved. Until such a time, you will have to play without your old characters.</center>"
else
dat += "<font color='green'><b>successful!</b></font><br><br>"
dat += "All of your character and preference data should be now neatly housed on the SQL database. Please look over it to see if anything is wrong or otherwise messed up. If you find something like that, please contact Skull132 <b>immediately.</b> Your old saves are still completely safe on the old system, should anything have gone wrong!<br><br>"
dat += "<b>You should now immediately load a character. Otherwise you risk overriding one of your characters!</b> Once that is done, everything shuold be fine.</center>"
C << browse(dat, "window=migrate_status")
update_migrate_status(C)
if(istype(C))
if(!IsGuestKey(C.key))
load_path(C.ckey)
log_debug("loading data for [C.ckey]")
if(LoadPrefData(C.ckey))
log_debug("Default slot loaded : [default_slot]")
if(SQLload_character(default_slot, C.ckey))
current_slot = default_slot
log_debug("Character [real_name] loaded, slot is [current_slot]")
if(handle_preferences_load(C))
if(handle_character_load(get_default_character(), C))
return
if(load_preferences())
if(load_character(default_slot))
current_slot = getCharSlot_File()
return
//this ensure that if db fail the file system is used to load an initial character
b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+")
gender = pick(MALE, FEMALE)
real_name = random_name(gender,species)
gear = list()
ZeroSkills(1)
/datum/preferences/proc/ZeroSkills(var/forced = 0)
for(var/V in SKILLS) for(var/datum/skill/S in SKILLS[V])
if(!skills.Find(S.ID) || forced)
@@ -262,7 +261,14 @@ datum/preferences
user << browse_rsc(preview_icon_side, "previewicon2.png")
var/dat = "<html><body><center>"
if(path)
if (config.sql_saves)
dat += "<center>"
dat += "<a href=\"byond://?src=\ref[user];preference=open_load_dialog\">Load another character</a> - "
dat += "<a href=\"byond://?src=\ref[user];preference=save\">Save character</a> - "
dat += "<a href=\"byond://?src=\ref[user];preference=reload\">Discard changes</a> - "
dat += "<a href=\"byond://?src=\ref[user];preference=delete_character_sql\">Delete Character</a>"
dat += "</center>"
else if (path)
dat += "<center>"
dat += "Slot <b>[slot_name]</b> - "
dat += "<a href=\"byond://?src=\ref[user];preference=open_load_dialog\">Load slot</a> - "
@@ -468,10 +474,14 @@ datum/preferences
dat += "</td></tr></table><hr><center>"
if(!IsGuestKey(user.key))
dat += "<a href='?_src_=prefs;preference=load'>Undo</a> - "
dat += "<a href='?_src_=prefs;preference=save'>Save Setup</a> - "
dat += "<a href='?_src_=prefs;preference=reset_all'>Reset Setup</a>"
if (config.sql_saves)
dat += "<a href=\"byond://?_src_=prefs;preference=save\">Save character</a> - "
dat += "<a href=\"byond://?_src_=prefs;preference=reload\">Discard changes</a> - "
dat += "<a href=\"byond://?_src_=prefs;preference=delete_character_sql\">Delete Character</a>"
else
dat += "<a href='?_src_=prefs;preference=load'>Undo</a> - "
dat += "<a href='?_src_=prefs;preference=save'>Save Setup</a> - "
dat += "<a href='?_src_=prefs;preference=reset_all'>Reset Setup</a>"
dat += "</center></body></html>"
user << browse(dat, "window=preferences;size=560x736")
@@ -1616,50 +1626,35 @@ datum/preferences
toggles ^= CHAT_GHOSTRADIO
if("save")
for(var/ckey in preferences_datums)
var/datum/preferences/D = preferences_datums[ckey]
if(D == src)
//switch comment to switch to file save system
default_slot = current_slot
SavePrefData(ckey)
SQLsave_character(current_slot, ckey)
//save_preferences()
//save_character()
handle_preferences_save(user.client)
handle_character_save(user.client)
if("reload")
for(var/ckey in preferences_datums)
var/datum/preferences/D = preferences_datums[ckey]
if(D == src)
//switch comment to switch to file save system
LoadPrefData(ckey)
SQLload_character(current_slot, ckey)
//load_preferences()
//load_character()
handle_preferences_load(user.client)
handle_character_load(get_default_character(), user.client)
if("open_load_dialog")
if(!IsGuestKey(user.key))
//file system preferences
//open_load_dialog_file(user)
open_load_dialog(user)
if (config.sql_saves)
open_load_dialog_sql(user)
else
open_load_dialog_file(user)
if("close_load_dialog")
close_load_dialog(user)
if("changeslot")
for(var/ckey in preferences_datums)
var/datum/preferences/D = preferences_datums[ckey]
if(D == src)
current_slot = text2num(href_list["num"])
if(!SQLload_character(current_slot, ckey))
gender = pick(MALE, FEMALE)
real_name = random_name(gender,species)
gear.Cut()
ZeroSkills(1)
ResetJobs()
//file system load
//load_character()
handle_character_load(text2num(href_list["num"]), user.client)
close_load_dialog(user)
if("new_character_sql")
new_character_sql(user.client)
close_load_dialog(user)
if("delete_character_sql")
delete_character_sql(user.client)
new_character_sql(user.client)
ShowChoices(user)
return 1
@@ -1771,37 +1766,38 @@ datum/preferences
message_admins("[character] ([character.ckey]) has spawned with their gender as plural or neuter. Please notify coders.")
character.gender = MALE
/datum/preferences/proc/open_load_dialog(mob/user)
/datum/preferences/proc/open_load_dialog_sql(mob/user)
var/dat = "<body>"
dat += "<tt><center>"
for(var/ckey in preferences_datums)
var/datum/preferences/D = preferences_datums[ckey]
if(D == src)
var/TextQuery = "SELECT Character_Name FROM SS13_characters WHERE ckey = '[ckey]' ORDER BY slot"
var/DBQuery/query
establish_db_connection(dbcon)
if(!dbcon.IsConnected())
open_load_dialog_file(user)
query = dbcon.NewQuery(TextQuery)
query.Execute()
var/rows
if(!query.RowCount())
rows = 0
else
rows = query.RowCount()
dat += "<b>Select a character slot to load (SQL Edition !)</b><hr>"
return open_load_dialog_file(user)
var/DBQuery/query = dbcon.NewQuery("SELECT id, name FROM ss13_characters WHERE ckey = :ckey ORDER BY id ASC")
query.Execute(list(":ckey" = user.client.ckey))
dat += "<b>Select a character slot to load</b><hr>"
var/name
for(var/i=1, i<= config.character_slots, i++)
log_debug("[rows] rows queried, i = [i]")
if(i<=rows)
query.NextRow()
name = query.item[1]
log_debug("adding [query.item[1]] to list")
else name = "Character[i]"
if(i==default_slot)
name = "<b>[name]</b>"
dat += "<a href='?_src_=prefs;preference=changeslot;num=[i];'>[name]</a><br>"
var/id
while (query.NextRow())
id = text2num(query.item[1])
name = query.item[2]
if (id == current_character)
dat += "<b><a href='?_src_=prefs;preference=changeslot;num=[id];'>[name]</a></b><br>"
else
dat += "<a href='?_src_=prefs;preference=changeslot;num=[id];'>[name]</a><br>"
dat += "<hr>"
dat += "<b>[query.RowCount()]/[config.character_slots] slots used</b><br>"
if (query.RowCount() < config.character_slots)
dat += "<a href='byond://?_src_=prefs;preference=new_character_sql;'>New Character</a>"
else
dat += "<strike>New Character</strike>"
dat += "<hr>"
dat += "<a href='byond://?src=\ref[user];preference=close_load_dialog'>Close</a><br>"
@@ -1829,34 +1825,5 @@ datum/preferences
dat += "</center></tt>"
user << browse(dat, "window=saves;size=300x390")
/datum/preferences/proc/getCharSlot()
for(var/ckey in preferences_datums)
var/datum/preferences/D = preferences_datums[ckey]
if(D == src)
var/TextQuery = "SELECT slot FROM SS13_characters WHERE ckey = '[ckey]' AND Character_Name = '[real_name]'"
var/DBQuery/query
establish_db_connection(dbcon)
if(!dbcon.IsConnected())
getCharSlot_File()
query = dbcon.NewQuery(TextQuery)
query.Execute()
if(!query.RowCount())
return 1
query.NextRow()
return text2num(query.item[1])
return 1
/datum/preferences/proc/getCharSlot_File() //get character slot from savefile
var/savefile/S = new /savefile(path)
if(S)
var/name
for(var/i=1, i<= config.character_slots, i++)
S.cd = "/character[i]"
S["real_name"] >> name
if(name == real_name)
return i
return 1
/datum/preferences/proc/close_load_dialog(mob/user)
user << browse(null, "window=saves")

View File

@@ -18,7 +18,7 @@
set category = "Preferences"
set desc = "Toggles hearing ambient sound effects"
prefs.asfx_togs ^= ASFX_AMBIENCE
prefs.save_preferences()
prefs.handle_preferences_save(src)
if(prefs.asfx_togs & ASFX_AMBIENCE)
src << "You will now hear ambient sounds."
else
@@ -33,7 +33,7 @@
set desc = "Toggles hearing footstep sound effects"
prefs.asfx_togs ^= ASFX_FOOTSTEPS
prefs.save_preferences()
prefs.handle_preferences_save(src)
if(prefs.asfx_togs & ASFX_FOOTSTEPS)
src << "You will now hear footstep sounds."
else
@@ -45,10 +45,9 @@
set category = "SoundFx Prefs"
set desc = "Toggles hearing of the vote alarm"
prefs.asfx_togs ^= ASFX_VOTE
prefs.save_preferences()
prefs.handle_preferences_save(src)
if(prefs.asfx_togs & ASFX_VOTE)
src << "You will now hear the vote alarm."
else
src << "<font color='red'>You will no longer hear the vote alarm.</font>"
feedback_add_details("admin_verb","TSFXFV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

View File

@@ -0,0 +1,86 @@
/*
* The method by which player saves are migrated to the SQL database from savefile oriented storage.
*/
/datum/preferences/proc/handle_saves_migration(var/client/C)
if (!C || !C.need_saves_migrated)
return 1
if (!path)
load_path(C.ckey)
if (!path)
log_debug("Migration of [C.ckey]'s saves failed at attaining path to save file.")
return 0
if (!migrate_client_preferences(C))
log_debug("Migration of [C.ckey]'s saves failed at the uploading of client preferences.")
return 0
if (!migrate_client_characters(C))
log_debug("Migration of [C.ckey]'s saves failed at the uploading of client characters.")
return 0
return 1
/*
* Handles the migration of preferences.
* Loads the prefs to the datum, then saves them to SQL.
*/
/datum/preferences/proc/migrate_client_preferences(var/client/C)
load_preferences()
return insert_preferences_sql(C)
/*
* Handles the migration of characters.
* Finds all of your saved characters, loads them into the datum, and saves them onto the SQL.
*/
/datum/preferences/proc/migrate_client_characters(var/client/C)
var/savefile/S = new /savefile(path)
if (!S)
return 1
S.cd = "/"
var/list/character_slots = list()
for (var/a in S.dir)
if (findtext(a, "character"))
var/slot_id = replacetext(a, "character", "")
character_slots.Add(text2num(slot_id))
if (!character_slots.len)
return 1
for (var/slot in character_slots)
load_character(slot)
if (!skills || !skills.len)
ZeroSkills(1)
if (!insert_character_sql(C))
log_debug("Character insert error during migration. Client: [C.ckey], character slot: [slot].")
return 0
return 1
/*
* Update's the client's migrate status.
*/
/datum/preferences/proc/update_migrate_status(var/client/C)
C.need_saves_migrated = 0
establish_db_connection(dbcon)
if (!dbcon.IsConnected())
return
var/DBQuery/query = dbcon.NewQuery("UPDATE ss13_player SET migration_status = 0 WHERE ckey = :ckey")
query.Execute(list(":ckey" = C.ckey))
var/DBQuery/current_query = dbcon.NewQuery("SELECT id FROM ss13_characters WHERE ckey = :ckey ORDER BY id ASC LIMIT 1")
current_query.Execute(list(":ckey" = C.ckey))
if (current_query.NextRow())
current_character = text2num(current_query.item[1])
load_character_sql(current_character, C)
return

View File

@@ -0,0 +1,643 @@
/datum/preferences/proc/load_preferences_sql(var/client/C)
if (!C)
return 0
var/DBQuery/query = dbcon.NewQuery({"SELECT
ooccolor,
lastchangelog,
UI_style,
current_character,
toggles,
UI_style_color,
UI_style_alpha,
be_special,
asfx_togs
FROM ss13_player_preferences
WHERE ckey = :ckey"})
query.Execute(list(":ckey" = C.ckey))
if (!query.NextRow())
return insert_preferences_sql(C)
ooccolor = query.item[1]
lastchangelog = query.item[2]
UI_style = query.item[3]
current_character = text2num(query.item[4])
toggles = text2num(query.item[5])
UI_style_color = query.item[6]
UI_style_alpha = text2num(query.item[7])
be_special = text2num(query.item[8])
asfx_togs = text2num(query.item[9])
//Sanitize
ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor))
lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
UI_style = sanitize_inlist(UI_style, list("White", "Midnight","Orange","old"), initial(UI_style))
be_special = sanitize_integer(be_special, 0, 65535, initial(be_special))
default_slot = sanitize_integer(default_slot, 1, config.character_slots, initial(default_slot))
toggles = sanitize_integer(toggles, 0, 65535, initial(toggles))
asfx_togs = sanitize_integer(asfx_togs, 0, 65535, initial(asfx_togs))
UI_style_color = sanitize_hexcolor(UI_style_color, initial(UI_style_color))
UI_style_alpha = sanitize_integer(UI_style_alpha, 0, 255, initial(UI_style_alpha))
return 1
/datum/preferences/proc/save_preferences_sql(var/client/C)
if (!C)
return 0
var/DBQuery/initial_query = dbcon.NewQuery("SELECT COUNT(*) AS rowsFound FROM ss13_player_preferences WHERE ckey = :ckey")
initial_query.Execute(list(":ckey" = C.ckey))
if (!initial_query.NextRow())
return insert_preferences_sql(C)
var/DBQuery/update_query = dbcon.NewQuery({"UPDATE ss13_player_preferences SET
ooccolor = :ooccolor,
lastchangelog = :lastchangelog,
UI_style = :ui_style,
current_character = :current_character,
toggles = :toggles,
UI_style_color = :ui_color,
UI_style_alpha = :ui_alpha,
be_special = :be_special,
asfx_togs = :asfx_togs
WHERE ckey = :ckey"})
update_query.Execute(get_prefs_update_insert_params(C))
return 1
/datum/preferences/proc/insert_preferences_sql(var/client/C)
if (!C)
return 0
var/DBQuery/query = dbcon.NewQuery({"INSERT INTO ss13_player_preferences (ckey, ooccolor, lastchangelog, UI_style, current_character, toggles, UI_style_color, UI_style_alpha, be_special, asfx_togs)
VALUES (:ckey, :ooccolor, :lastchangelog, :ui_style, :current_character, :toggles, :ui_color, :ui_alpha, :be_special, :asfx_togs);"})
query.Execute(get_prefs_update_insert_params(C))
return 1
//Helper function.
/datum/preferences/proc/get_prefs_update_insert_params(var/client/C)
var/params[] = list()
params[":ckey"] = C.ckey
params[":ooccolor"] = ooccolor
params[":lastchangelog"] = lastchangelog
params[":ui_style"] = UI_style
params[":current_character"] = current_character
params[":toggles"] = toggles
params[":ui_color"] = UI_style_color
params[":ui_alpha"] = UI_style_alpha
params[":be_special"] = be_special
params[":asfx_togs"] = asfx_togs
return params
/datum/preferences/proc/load_character_sql(slot, var/client/C)
if (!C)
return 0
if (!slot || slot == 0)
return new_character_sql(C)
current_character = slot
establish_db_connection(dbcon)
if (!dbcon.IsConnected())
error("Error attempting to connect to MySQL server while loading a character.")
return 0
var/DBQuery/initial_query = dbcon.NewQuery("SELECT name FROM ss13_characters WHERE id = :character_id AND ckey = :ckey")
initial_query.Execute(list(":character_id" = current_character, ":ckey" = C.ckey))
// In case someone got themselves an invalid character ID.
if (!initial_query.NextRow())
error("[C.ckey] attempted to load character #[current_character] and failed. No such character found.")
new_character_sql(C)
return 0
var/DBQuery/character_query = dbcon.NewQuery({"SELECT
dat.name,
dat.metadata,
dat.random_name,
dat.gender,
dat.age,
dat.species,
dat.language,
dat.spawnpoint,
dat.hair_colour,
dat.facial_colour,
dat.skin_tone,
dat.skin_colour,
dat.hair_style,
dat.facial_style,
dat.eyes_colour,
dat.underwear,
dat.undershirt,
dat.backbag,
dat.b_type,
dat.jobs,
dat.alternate_option,
dat.alternate_titles,
flv.flavour_general,
flv.flavour_head,
flv.flavour_face,
flv.flavour_eyes,
flv.flavour_torso,
flv.flavour_arms,
flv.flavour_hands,
flv.flavour_legs,
flv.flavour_feet,
flv.robot_default,
flv.robot_standard,
flv.robot_engineering,
flv.robot_construction,
flv.robot_surgeon,
flv.robot_crisis,
flv.robot_miner,
flv.robot_janitor,
flv.robot_service,
flv.robot_clerical,
flv.robot_security,
flv.robot_research,
flv.records_employment,
flv.records_medical,
flv.records_security,
flv.records_exploit,
dat.disabilities,
dat.skills,
dat.skills_specialization,
dat.home_system,
dat.citizenship,
dat.faction,
dat.religion,
dat.nt_relation,
dat.uplink_location,
dat.organs_data,
dat.organs_robotic,
dat.gear
FROM ss13_characters dat
JOIN ss13_characters_flavour flv ON dat.id = flv.char_id
WHERE dat.id = :char_id"})
if (!character_query.Execute(list(":char_id" = current_character)))
error("Error loading character #[current_character]. SQL error message: '[character_query.ErrorMsg()]'.")
new_character_sql(C)
return 0
if (!character_query.NextRow())
error("Error loading character #[current_character]. No such character exists.")
new_character_sql(C)
return 0
var/DBQuery/char_id_update = dbcon.NewQuery("UPDATE ss13_player_preferences SET current_character = :char_id WHERE ckey = :ckey")
char_id_update.Execute(list(":char_id" = current_character, ":ckey" = C.ckey))
// Character
real_name = character_query.item[1]
metadata = character_query.item[2]
be_random_name = text2num(character_query.item[3])
gender = character_query.item[4]
age = text2num(character_query.item[5])
species = character_query.item[6]
language = character_query.item[7]
spawnpoint = character_query.item[8]
// Other customization data
var/list/hair_rgb = length(character_query.item[9]) == 7 ? GetHexColors(character_query.item[9]) : null
if (hair_rgb)
r_hair = hair_rgb[1]
g_hair = hair_rgb[2]
b_hair = hair_rgb[3]
var/list/facial_rgb = length(character_query.item[10]) == 7 ? GetHexColors(character_query.item[10]) : null
if (facial_rgb)
r_facial = facial_rgb[1]
g_facial = facial_rgb[2]
b_facial = facial_rgb[3]
s_tone = text2num(character_query.item[11])
var/list/skin_rgb = length(character_query.item[12]) == 7 ? GetHexColors(character_query.item[12]) : null
if (skin_rgb)
r_skin = skin_rgb[1]
g_skin = skin_rgb[2]
b_skin = skin_rgb[3]
h_style = character_query.item[13]
f_style = character_query.item[14]
var/list/eyes_rgb = length(character_query.item[15]) == 7 ? GetHexColors(character_query.item[15]) : null
if (eyes_rgb)
r_eyes = eyes_rgb[1]
g_eyes = eyes_rgb[2]
b_eyes = eyes_rgb[3]
underwear = character_query.item[16]
undershirt = character_query.item[17]
backbag = text2num(character_query.item[18])
b_type = character_query.item[19]
var/list/jobs_list = params2list(character_query.item[20])
// Job preferences + alt titles and options
if (jobs_list.len == 9)
job_civilian_high = text2num(jobs_list["civ_high"])
job_civilian_med = text2num(jobs_list["civ_med"])
job_civilian_low = text2num(jobs_list["civ_low"])
job_medsci_high = text2num(jobs_list["medsci_high"])
job_medsci_med = text2num(jobs_list["medsci_med"])
job_medsci_low = text2num(jobs_list["medsci_low"])
job_engsec_high = text2num(jobs_list["engsec_high"])
job_engsec_med = text2num(jobs_list["engsec_med"])
job_engsec_low = text2num(jobs_list["engsec_low"])
alternate_option = text2num(character_query.item[21])
player_alt_titles = params2list(character_query.item[22])
// Flavour texts
flavor_texts["general"] = character_query.item[23]
flavor_texts["head"] = character_query.item[24]
flavor_texts["face"] = character_query.item[25]
flavor_texts["eyes"] = character_query.item[26]
flavor_texts["torso"] = character_query.item[27]
flavor_texts["arms"] = character_query.item[28]
flavor_texts["hands"] = character_query.item[29]
flavor_texts["legs"] = character_query.item[30]
flavor_texts["feet"] = character_query.item[31]
flavour_texts_robot["Default"] = character_query.item[32]
flavour_texts_robot["Standard"] = character_query.item[33]
flavour_texts_robot["Engineering"] = character_query.item[34]
flavour_texts_robot["Construction"] = character_query.item[35]
flavour_texts_robot["Surgeon"] = character_query.item[36]
flavour_texts_robot["Crisis"] = character_query.item[37]
flavour_texts_robot["Miner"] = character_query.item[38]
flavour_texts_robot["Janitor"] = character_query.item[39]
flavour_texts_robot["Service"] = character_query.item[40]
flavour_texts_robot["Clerical"] = character_query.item[41]
flavour_texts_robot["Security"] = character_query.item[42]
flavour_texts_robot["Research"] = character_query.item[43]
// Records
gen_record = character_query.item[44]
med_record = character_query.item[45]
sec_record = character_query.item[46]
exploit_record = character_query.item[47]
// Miscellaneous
disabilities = text2num(character_query.item[48])
skills = params2list(character_query.item[49])
skill_specialization = character_query.item[50]
home_system = character_query.item[51]
citizenship = character_query.item[52]
faction = character_query.item[53]
religion = character_query.item[54]
nanotrasen_relation = character_query.item[55]
uplinklocation = character_query.item[56]
organ_data = params2list(character_query.item[57])
rlimb_data = params2list(character_query.item[58])
gear = params2list(character_query.item[59])
// Sanitization
metadata = sanitize_text(metadata, initial(metadata))
real_name = sanitizeName(real_name)
if (isnull(species) || !(species in playable_species))
species = "Human"
if (isnum(underwear))
var/list/undies = gender == MALE ? underwear_m : underwear_f
underwear = undies[undies[underwear]]
if (isnum(undershirt))
undershirt = undershirt_t[undershirt_t[undershirt]]
if (isnull(language)) language = "None"
if (isnull(spawnpoint)) spawnpoint = "Arrivals Shuttle"
if (isnull(nanotrasen_relation)) nanotrasen_relation = initial(nanotrasen_relation)
if (!real_name) real_name = random_name(gender)
be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name))
gender = sanitize_gender(gender)
age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age))
r_hair = sanitize_integer(r_hair, 0, 255, initial(r_hair))
g_hair = sanitize_integer(g_hair, 0, 255, initial(g_hair))
b_hair = sanitize_integer(b_hair, 0, 255, initial(b_hair))
r_facial = sanitize_integer(r_facial, 0, 255, initial(r_facial))
g_facial = sanitize_integer(g_facial, 0, 255, initial(g_facial))
b_facial = sanitize_integer(b_facial, 0, 255, initial(b_facial))
s_tone = sanitize_integer(s_tone, -185, 34, initial(s_tone))
r_skin = sanitize_integer(r_skin, 0, 255, initial(r_skin))
g_skin = sanitize_integer(g_skin, 0, 255, initial(g_skin))
b_skin = sanitize_integer(b_skin, 0, 255, initial(b_skin))
h_style = sanitize_inlist(h_style, hair_styles_list, initial(h_style))
f_style = sanitize_inlist(f_style, facial_hair_styles_list, initial(f_style))
r_eyes = sanitize_integer(r_eyes, 0, 255, initial(r_eyes))
g_eyes = sanitize_integer(g_eyes, 0, 255, initial(g_eyes))
b_eyes = sanitize_integer(b_eyes, 0, 255, initial(b_eyes))
backbag = sanitize_integer(backbag, 1, backbaglist.len, initial(backbag))
b_type = sanitize_text(b_type, initial(b_type))
alternate_option = sanitize_integer(alternate_option, 0, 2, initial(alternate_option))
job_civilian_high = sanitize_integer(job_civilian_high, 0, 65535, initial(job_civilian_high))
job_civilian_med = sanitize_integer(job_civilian_med, 0, 65535, initial(job_civilian_med))
job_civilian_low = sanitize_integer(job_civilian_low, 0, 65535, initial(job_civilian_low))
job_medsci_high = sanitize_integer(job_medsci_high, 0, 65535, initial(job_medsci_high))
job_medsci_med = sanitize_integer(job_medsci_med, 0, 65535, initial(job_medsci_med))
job_medsci_low = sanitize_integer(job_medsci_low, 0, 65535, initial(job_medsci_low))
job_engsec_high = sanitize_integer(job_engsec_high, 0, 65535, initial(job_engsec_high))
job_engsec_med = sanitize_integer(job_engsec_med, 0, 65535, initial(job_engsec_med))
job_engsec_low = sanitize_integer(job_engsec_low, 0, 65535, initial(job_engsec_low))
if (!skills) ZeroSkills(1)
if (skills.len) CalculateSkillPoints()
if (!used_skillpoints) used_skillpoints = 0
if (isnull(disabilities)) disabilities = 0
if (!player_alt_titles) player_alt_titles = new()
if (!organ_data) organ_data = list()
if (!rlimb_data) rlimb_data = list()
if (!gear) gear = list()
if (!home_system) home_system = "Unset"
if (!citizenship) citizenship = "None"
if (!faction) faction = "None"
if (!religion) religion = "None"
return 1
/datum/preferences/proc/save_character_sql(var/client/C)
if (!C)
return 0
if (!current_character)
return insert_character_sql(C)
establish_db_connection(dbcon)
if (!dbcon.IsConnected())
error("Error attempting to connect to MySQL server while saving a character.")
return 0
var/DBQuery/initial_query = dbcon.NewQuery("SELECT COUNT(*) AS rowCount FROM ss13_characters WHERE id = :char_id")
initial_query.Execute(list(":char_id" = current_character))
if (!initial_query.NextRow())
current_character = 0
return insert_character_sql(C)
var/DBQuery/update_query = dbcon.NewQuery({"UPDATE ss13_characters dat
JOIN ss13_characters_flavour flv ON dat.id = flv.char_id
SET
dat.name = :real_name,
dat.metadata = :metadata,
dat.random_name = :is_random,
dat.gender = :gender,
dat.age = :age,
dat.species = :species,
dat.language = :language,
dat.spawnpoint = :spawnpoint,
dat.hair_colour = :hair_colour,
dat.facial_colour = :facial_colour,
dat.skin_tone = :skin_tone,
dat.skin_colour = :skin_colour,
dat.hair_style = :hair_style,
dat.facial_style = :facial_style,
dat.eyes_colour = :eyes_colour,
dat.underwear = :underwear,
dat.undershirt = :undershirt,
dat.backbag = :backbag,
dat.b_type = :b_type,
dat.jobs = :jobs,
dat.alternate_option = :alternate_option,
dat.alternate_titles = :alternate_titles,
dat.disabilities = :disabilities,
dat.skills = :skills,
dat.skills_specialization = :specialization,
dat.home_system = :home_system,
dat.citizenship = :citizenship,
dat.faction = :faction,
dat.religion = :religion,
dat.nt_relation = :nt_relation,
dat.uplink_location = :uplink_loc,
dat.organs_data = :organ_data,
dat.organs_robotic = :organs_robotic,
dat.gear = :gear,
flv.flavour_general = :flv_general,
flv.flavour_head = :flv_head,
flv.flavour_face = :flv_face,
flv.flavour_eyes = :flv_eyes,
flv.flavour_torso = :flv_torso,
flv.flavour_arms = :flv_arms,
flv.flavour_hands = :flv_hands,
flv.flavour_legs = :flv_legs,
flv.flavour_feet = :flv_feet,
flv.robot_default = :robot_default,
flv.robot_standard = :robot_standard,
flv.robot_engineering = :robot_engineering,
flv.robot_construction = :robot_construction,
flv.robot_surgeon = :robot_surgeon,
flv.robot_crisis = :robot_crisis,
flv.robot_miner = :robot_miner,
flv.robot_janitor = :robot_janitor,
flv.robot_service = :robot_service,
flv.robot_clerical = :robot_clerical,
flv.robot_security = :robot_security,
flv.robot_research = :robot_research,
flv.records_medical = :med_rec,
flv.records_security = :sec_rec,
flv.records_employment = :gen_rec,
flv.records_exploit = :exploit_record
WHERE dat.id = :char_id"})
update_query.Execute(get_update_insert_params())
if (update_query.ErrorMsg())
error("Error updating character #[current_character]: [update_query.ErrorMsg()]")
return 0
return 1
/datum/preferences/proc/insert_character_sql(var/client/C)
if (!C)
return 0
establish_db_connection(dbcon)
if (!dbcon.IsConnected())
error("Error attempting to connect to MySQL server while inserting a character.")
return 0
var/params[] = get_update_insert_params(0, C)
var/DBQuery/insert_query = dbcon.NewQuery({"INSERT INTO ss13_characters (id, ckey, name, metadata, random_name, gender, age, species, language, hair_colour, facial_colour, skin_tone, skin_colour, hair_style, facial_style, eyes_colour, underwear, undershirt, backbag, b_type, spawnpoint, jobs, alternate_option, alternate_titles, disabilities, skills, skills_specialization, home_system, citizenship, faction, religion, nt_relation, uplink_location, organs_data, organs_robotic, gear)
VALUES (NULL, :ckey, :real_name, :metadata, :is_random, :gender, :age, :species, :language, :hair_colour, :facial_colour, :skin_tone, :skin_colour, :hair_style, :facial_style, :eyes_colour, :underwear, :undershirt, :backbag, :b_type, :spawnpoint, :jobs, :alternate_option, :alternate_titles, :disabilities, :skills, :specialization, :home_system, :citizenship, :faction, :religion, :nt_relation, :uplink_loc, :organ_data, :organs_robotic, :gear);"})
insert_query.Execute(params, 1)
if (insert_query.ErrorMsg())
return 0
var/DBQuery/get_query = dbcon.NewQuery("SELECT id FROM ss13_characters WHERE ckey = :ckey AND name = :real_name ORDER BY id DESC LIMIT 1;")
get_query.Execute(list(":ckey" = C.ckey, ":real_name" = real_name))
if (get_query.NextRow())
current_character = text2num(get_query.item[1])
params[":char_id"] = current_character
insert_query = dbcon.NewQuery({"INSERT INTO ss13_characters_flavour (char_id, records_employment, records_medical, records_security, records_exploit, flavour_general, flavour_head, flavour_face, flavour_eyes, flavour_torso, flavour_arms, flavour_hands, flavour_legs, flavour_feet, robot_default, robot_standard, robot_engineering, robot_construction, robot_surgeon, robot_crisis, robot_miner, robot_janitor, robot_service, robot_clerical, robot_security, robot_research)
VALUES (:char_id, :gen_rec, :med_rec, :sec_rec, :exploit_record, :flv_general, :flv_head, :flv_face, :flv_eyes, :flv_torso, :flv_arms, :flv_hands, :flv_legs, :flv_feet, :robot_default, :robot_standard, :robot_engineering, :robot_construction, :robot_surgeon, :robot_crisis, :robot_miner, :robot_janitor, :robot_service, :robot_clerical, :robot_security, :robot_research);"})
insert_query.Execute(params, 1)
if (insert_query.ErrorMsg())
return 0
return 1
// Helper function.
// Returns an array to be used in save_character_sql and insert_character_sql.
/datum/preferences/proc/get_update_insert_params(var/include_id = 1, var/client/C = null)
var/hair_hex = "#" + num2hex(r_hair) + num2hex(g_hair) + num2hex(b_hair)
var/facial_hex = "#" + num2hex(r_facial) + num2hex(g_facial) + num2hex(b_facial)
var/eyes_hex = "#" + num2hex(r_eyes) + num2hex(g_eyes) + num2hex(b_eyes)
var/skin_hex = "#" + num2hex(r_skin) + num2hex(g_skin) + num2hex(b_skin)
var/language_string = "None"
if (!istext(language))
if (istype(language, /datum/language))
for (var/L in all_languages)
if (language == all_languages[L])
language_string = L
break
else
language_string = language
var/jobs_list[] = list()
jobs_list["civ_high"] = job_civilian_high
jobs_list["civ_med"] = job_civilian_med
jobs_list["civ_low"] = job_civilian_low
jobs_list["medsci_high"] = job_medsci_high
jobs_list["medsci_med"] = job_medsci_med
jobs_list["medsci_low"] = job_medsci_low
jobs_list["engsec_high"] = job_engsec_high
jobs_list["engsec_med"] = job_engsec_med
jobs_list["engsec_low"] = job_engsec_low
var/params[] = list()
params[":real_name"] = real_name
params[":metadata"] = metadata
params[":is_random"] = be_random_name
params[":gender"] = gender
params[":age"] = age
params[":species"] = species
params[":language"] = language_string
params[":spawnpoint"] = spawnpoint
params[":hair_colour"] = hair_hex
params[":facial_colour"] = facial_hex
params[":skin_tone"] = s_tone
params[":skin_colour"] = skin_hex
params[":hair_style"] = h_style
params[":facial_style"] = f_style
params[":eyes_colour"] = eyes_hex
params[":underwear"] = underwear
params[":undershirt"] = undershirt
params[":backbag"] = backbag
params[":b_type"] = b_type
params[":alternate_option"] = alternate_option
params[":jobs"] = list2params(jobs_list)
params[":alternate_titles"] = list2params(player_alt_titles)
params[":flv_general"] = flavor_texts["general"]
params[":flv_head"] = flavor_texts["head"]
params[":flv_face"] = flavor_texts["face"]
params[":flv_eyes"] = flavor_texts["eyes"]
params[":flv_torso"] = flavor_texts["torso"]
params[":flv_arms"] = flavor_texts["arms"]
params[":flv_hands"] = flavor_texts["hands"]
params[":flv_legs"] = flavor_texts["legs"]
params[":flv_feet"] = flavor_texts["feet"]
params[":robot_default"] = flavour_texts_robot["Default"]
params[":robot_standard"] = flavour_texts_robot["Standard"]
params[":robot_engineering"] = flavour_texts_robot["Engineering"]
params[":robot_construction"] = flavour_texts_robot["Construction"]
params[":robot_surgeon"] = flavour_texts_robot["Surgeon"]
params[":robot_crisis"] = flavour_texts_robot["Crisis"]
params[":robot_miner"] = flavour_texts_robot["Miner"]
params[":robot_janitor"] = flavour_texts_robot["Janitor"]
params[":robot_service"] = flavour_texts_robot["Service"]
params[":robot_clerical"] = flavour_texts_robot["Clerical"]
params[":robot_security"] = flavour_texts_robot["Security"]
params[":robot_research"] = flavour_texts_robot["Research"]
params[":med_rec"] = med_record
params[":sec_rec"] = sec_record
params[":gen_rec"] = gen_record
params[":disabilities"] = disabilities
params[":skills"] = list2params(skills)
params[":specialization"] = skill_specialization
params[":home_system"] = home_system
params[":citizenship"] = citizenship
params[":faction"] = faction
params[":religion"] = religion
params[":nt_relation"] = nanotrasen_relation
params[":uplink_loc"] = uplinklocation
params[":exploit_record"] = exploit_record
params[":organ_data"] = list2params(organ_data)
params[":organs_robotic"] = list2params(rlimb_data)
params[":gear"] = list2params(gear)
if (include_id)
params[":char_id"] = current_character
if (C)
params[":ckey"] = C.ckey
return params
/datum/preferences/proc/new_character_sql(var/client/C)
if (!C)
return 0
current_character = 0
var/DBQuery/char_id_update = dbcon.NewQuery("UPDATE ss13_player_preferences SET current_character = '0' WHERE ckey = :ckey")
char_id_update.Execute(list(":ckey" = C.ckey))
species = "Human"
language = "None"
spawnpoint = "Arrivals Shuttle"
nanotrasen_relation = initial(nanotrasen_relation)
gender = pick(MALE, FEMALE)
real_name = random_name(gender, species)
gear = list()
b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+")
return 1
/datum/preferences/proc/delete_character_sql(var/client/C)
if (!C)
return 0
if (!current_character)
return 0
establish_db_connection(dbcon)
if (!dbcon.IsConnected())
error("Error attempting to connect to MySQL server while deleting a character.")
return 0
var/DBQuery/query = dbcon.NewQuery("SELECT COUNT(*) AS rowCount FROM ss13_characters WHERE id = :char_id AND ckey = :ckey")
query.Execute(list(":char_id" = current_character, ":ckey" = C.ckey))
if (!query.NextRow())
return 0
var/DBQuery/delete_query = dbcon.NewQuery("DELETE FROM ss13_characters WHERE id = :id")
delete_query.Execute(list(":id" = current_character))
var/DBQuery/select_query = dbcon.NewQuery("SELECT id FROM ss13_characters WHERE ckey = :ckey ORDER BY id ASC LIMIT 1")
select_query.Execute(list(":ckey" = C.ckey))
if (select_query.NextRow())
load_character_sql(text2num(select_query.item[1]), C)
else
new_character_sql(C)
C << "<span class='notice'>Your character has been deleted from the database.</span>"
return 1

View File

@@ -0,0 +1,35 @@
/*
* These procs manage the calling of savefile or SQL oriented save and load procs for characters and preference data.
* This way of doing it is necessary for migration to be possible without a huge load of hacks.
* Will also ensure in neat and modular compatibility between the two systems, and the potential introduction of further systems.
*/
/datum/preferences/proc/handle_preferences_load(var/client/C)
if (config.sql_saves)
return load_preferences_sql(C)
else
return load_preferences()
/datum/preferences/proc/handle_preferences_save(var/client/C)
if (config.sql_saves)
return save_preferences_sql(C)
else
return save_preferences()
/datum/preferences/proc/handle_character_load(var/slot = 0, var/client/C)
if (config.sql_saves)
return load_character_sql(slot, C)
else
return load_character(slot)
/datum/preferences/proc/handle_character_save(var/client/C)
if (config.sql_saves)
return save_character_sql(C)
else
return save_character()
/datum/preferences/proc/get_default_character()
if (config.sql_saves)
return current_character
else
return default_slot

View File

@@ -5,7 +5,7 @@
set desc = ".Toggle Between seeing all mob speech, and only speech of nearby mobs"
prefs.toggles ^= CHAT_GHOSTEARS
src << "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTEARS) ? "see all speech in the world" : "only see speech from nearby mobs"]."
prefs.save_preferences()
prefs.handle_preferences_save(src)
feedback_add_details("admin_verb","TGE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_ghost_sight()
@@ -14,7 +14,7 @@
set desc = ".Toggle Between seeing all mob emotes, and only emotes of nearby mobs"
prefs.toggles ^= CHAT_GHOSTSIGHT
src << "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTSIGHT) ? "see all emotes in the world" : "only see emotes from nearby mobs"]."
prefs.save_preferences()
prefs.handle_preferences_save(src)
feedback_add_details("admin_verb","TGS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_ghost_radio()
@@ -23,7 +23,7 @@
set desc = ".Toggle between hearing all radio chatter, or only from nearby speakers"
prefs.toggles ^= CHAT_GHOSTRADIO
src << "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTRADIO) ? "hear all radio chat in the world" : "only hear from nearby speakers"]."
prefs.save_preferences()
prefs.handle_preferences_save(src)
feedback_add_details("admin_verb","TGR")
/client/proc/toggle_hear_radio()
@@ -32,7 +32,7 @@
set desc = "Toggle seeing radiochatter from radios and speakers"
if(!holder) return
prefs.toggles ^= CHAT_RADIO
prefs.save_preferences()
prefs.handle_preferences_save(src)
usr << "You will [(prefs.toggles & CHAT_RADIO) ? "now" : "no longer"] see radio chatter from radios or speakers"
feedback_add_details("admin_verb","THR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -42,7 +42,7 @@
set desc = "Toggle hearing a notification when admin PMs are recieved"
if(!holder) return
prefs.toggles ^= SOUND_ADMINHELP
prefs.save_preferences()
prefs.handle_preferences_save(src)
usr << "You will [(prefs.toggles & SOUND_ADMINHELP) ? "now" : "no longer"] hear a sound when adminhelps arrive."
feedback_add_details("admin_verb","AHS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -51,7 +51,7 @@
set category = "Preferences"
set desc ="Toggles seeing deadchat"
prefs.toggles ^= CHAT_DEAD
prefs.save_preferences()
prefs.handle_preferences_save(src)
if(src.holder)
src << "You will [(prefs.toggles & CHAT_DEAD) ? "now" : "no longer"] see deadchat."
@@ -65,7 +65,7 @@
set category = "Preferences"
set desc = "Toggles seeing prayers"
prefs.toggles ^= CHAT_PRAYER
prefs.save_preferences()
prefs.handle_preferences_save(src)
src << "You will [(prefs.toggles & CHAT_PRAYER) ? "now" : "no longer"] see prayerchat."
feedback_add_details("admin_verb","TP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -74,7 +74,7 @@
set category = "Preferences"
set desc = "Toggles hearing the GameLobby music"
prefs.toggles ^= SOUND_LOBBY
prefs.save_preferences()
prefs.handle_preferences_save(src)
if(prefs.toggles & SOUND_LOBBY)
src << "You will now hear music in the game lobby."
if(istype(mob, /mob/new_player))
@@ -90,7 +90,7 @@
set category = "Preferences"
set desc = "Toggles hearing sounds uploaded by admins"
prefs.toggles ^= SOUND_MIDI
prefs.save_preferences()
prefs.handle_preferences_save(src)
if(prefs.toggles & SOUND_MIDI)
src << "You will now hear any sounds uploaded by admins."
var/sound/break_sound = sound(null, repeat = 0, wait = 0, channel = 777)
@@ -105,7 +105,7 @@
set category = "Preferences"
set desc = "Toggles seeing OutOfCharacter chat"
prefs.toggles ^= CHAT_OOC
prefs.save_preferences()
prefs.handle_preferences_save(src)
src << "You will [(prefs.toggles & CHAT_OOC) ? "now" : "no longer"] see messages on the OOC channel."
feedback_add_details("admin_verb","TOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -115,7 +115,7 @@
set category = "Preferences"
set desc = "Toggles seeing Local OutOfCharacter chat"
prefs.toggles ^= CHAT_LOOC
prefs.save_preferences()
prefs.handle_preferences_save(src)
src << "You will [(prefs.toggles & CHAT_LOOC) ? "now" : "no longer"] see messages on the LOOC channel."
feedback_add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -126,7 +126,7 @@
set category = "Preferences"
set desc = "Toggles seeing chat tags/icons"
prefs.toggles ^= CHAT_NOICONS
prefs.save_preferences()
prefs.handle_preferences_save(src)
src << "You will [!(prefs.toggles & CHAT_NOICONS) ? "now" : "no longer"] see chat tag icons."
feedback_add_details("admin_verb","TCTAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -137,7 +137,7 @@
set category = "Preferences"
set desc = "Toggles hearing ambient sound effects"
prefs.toggles ^= SOUND_AMBIENCE
prefs.save_preferences()
prefs.handle_preferences_save(src)
if(prefs.toggles & SOUND_AMBIENCE)
src << "You will now hear ambient sounds."
else
@@ -154,7 +154,7 @@
var/role_flag = be_special_flags[role]
if(!role_flag) return
prefs.be_special ^= role_flag
prefs.save_preferences()
prefs.handle_preferences_save(src)
src << "You will [(prefs.be_special & role_flag) ? "now" : "no longer"] be considered for [role] events (where possible)."
feedback_add_details("admin_verb","TBeSpecial") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -193,5 +193,5 @@
prefs.UI_style = UI_style_new
prefs.UI_style_alpha = UI_style_alpha_new
prefs.UI_style_color = UI_style_color_new
prefs.save_preferences()
usr << "UI was saved"
prefs.handle_preferences_save(src)
usr << "UI was saved"

View File

@@ -426,7 +426,7 @@
src << browse('html/changelog.html', "window=changes;size=675x650")
if(prefs.lastchangelog != changelog_hash)
prefs.lastchangelog = changelog_hash
prefs.save_preferences()
prefs.handle_preferences_save(src)
winset(src, "rpane.changelog", "background-color=none;font-style=;")
/mob/verb/observe()

View File

@@ -78,11 +78,11 @@ mob/var/obj/effect/decal/typing_indicator
set category = "Preferences"
set desc = "Toggles showing an indicator when you are typing emote or say message."
prefs.toggles ^= SHOW_TYPING
prefs.save_preferences()
prefs.handle_preferences_save(src)
src << "You will [(prefs.toggles & SHOW_TYPING) ? "no longer" : "now"] display a typing indicator."
// Clear out any existing typing indicator.
if(prefs.toggles & SHOW_TYPING)
if(istype(mob)) mob.set_typing_indicator(0)
feedback_add_details("admin_verb","TID") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
feedback_add_details("admin_verb","TID") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

View File

@@ -362,6 +362,9 @@ STARLIGHT 0
## Uncomment this to house whitelists on the SQL database.
# SQL_WHITELISTS
## Uncomment this to house player preferences and characters on the SQL database.
# SQL_SAVES
## Uncomment this to use the discord bot.
# USE_DISCORD_BOT

View File

@@ -0,0 +1,6 @@
author: Skull132
delete-after: True
changes:
- rscadd: "Characters are now saved to, and loaded from the SQL database. Along with user preferences. All file saves will be automatically transferred over and retained just in case. Hopefully everything makes it there in one piece. Important things to note for players: no more slots, instead, you have characters that you can delete. You can also make new characters."