mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-13 16:13:19 +01:00
catchup with master
This commit is contained in:
@@ -277,6 +277,7 @@ CREATE TABLE `player` (
|
||||
`fupdate` smallint(4) DEFAULT '0',
|
||||
`parallax` tinyint(1) DEFAULT '8',
|
||||
`byond_date` DATE DEFAULT NULL,
|
||||
`2fa_status` ENUM('DISABLED','ENABLED_IP','ENABLED_ALWAYS') NOT NULL DEFAULT 'DISABLED' COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `ckey` (`ckey`),
|
||||
KEY `lastseen` (`lastseen`),
|
||||
@@ -585,3 +586,16 @@ CREATE TABLE `round` (
|
||||
`station_name` VARCHAR(80) NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
|
||||
--
|
||||
-- Table structure for table `2fa_secrets`
|
||||
--
|
||||
CREATE TABLE `2fa_secrets` (
|
||||
`ckey` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`secret` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`date_setup` DATETIME NOT NULL DEFAULT current_timestamp(),
|
||||
`last_time` DATETIME NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`ckey`) USING BTREE
|
||||
)
|
||||
COLLATE='utf8mb4_general_ci' ENGINE=InnoDB;
|
||||
|
||||
@@ -276,6 +276,7 @@ CREATE TABLE `SS13_player` (
|
||||
`fupdate` smallint(4) DEFAULT '0',
|
||||
`parallax` tinyint(1) DEFAULT '8',
|
||||
`byond_date` DATE DEFAULT NULL,
|
||||
`2fa_status` ENUM('DISABLED','ENABLED_IP','ENABLED_ALWAYS') NOT NULL DEFAULT 'DISABLED' COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `ckey` (`ckey`),
|
||||
KEY `lastseen` (`lastseen`),
|
||||
@@ -582,3 +583,15 @@ CREATE TABLE `SS13_round` (
|
||||
`station_name` VARCHAR(80) NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- Table structure for table `2fa_secrets`
|
||||
--
|
||||
CREATE TABLE `SS13_2fa_secrets` (
|
||||
`ckey` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`secret` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`date_setup` DATETIME NOT NULL DEFAULT current_timestamp(),
|
||||
`last_time` DATETIME NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`ckey`) USING BTREE
|
||||
)
|
||||
COLLATE='utf8mb4_general_ci' ENGINE=InnoDB;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# Updates DB from 23 to 24 -AffectedArc07
|
||||
# Add new column to player table for 2FA status
|
||||
ALTER TABLE `player` ADD COLUMN `2fa_status` ENUM('DISABLED','ENABLED_IP','ENABLED_ALWAYS') NOT NULL DEFAULT 'DISABLED' AFTER `byond_date`;
|
||||
|
||||
# Create new table for 2FA tokens
|
||||
CREATE TABLE `2fa_secrets` (
|
||||
`ckey` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`secret` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`date_setup` DATETIME NOT NULL DEFAULT current_timestamp(),
|
||||
`last_time` DATETIME NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`ckey`) USING BTREE
|
||||
)
|
||||
COLLATE='utf8mb4_general_ci' ENGINE=InnoDB;
|
||||
@@ -11168,6 +11168,9 @@
|
||||
icon_state = "tube1";
|
||||
tag = "icon-tube1 (WEST)"
|
||||
},
|
||||
/obj/structure/chair/comfy/shuttle{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/specops)
|
||||
"QL" = (
|
||||
|
||||
@@ -363,7 +363,7 @@
|
||||
#define INVESTIGATE_BOMB "bombs"
|
||||
|
||||
// The SQL version required by this version of the code
|
||||
#define SQL_VERSION 23
|
||||
#define SQL_VERSION 24
|
||||
|
||||
// Vending machine stuff
|
||||
#define CAT_NORMAL 1
|
||||
|
||||
@@ -105,3 +105,12 @@
|
||||
#define PARALLAX_MED 4
|
||||
#define PARALLAX_HIGH 8
|
||||
#define PARALLAX_INSANE 16
|
||||
|
||||
// 2FA Defines. These are the same as the schema DB enums //
|
||||
|
||||
/// Client has 2FA disabled
|
||||
#define _2FA_DISABLED "DISABLED"
|
||||
/// Client will be prompted for 2FA on IP changes
|
||||
#define _2FA_ENABLED_IP "ENABLED_IP"
|
||||
/// Client will be prompted for 2FA always
|
||||
#define _2FA_ENABLED_ALWAYS "ENABLED_ALWAYS"
|
||||
|
||||
@@ -514,6 +514,7 @@
|
||||
text = replacetext(text, "\[logo\]", "​<img src = ntlogo.png>")
|
||||
text = replacetext(text, "\[time\]", "[station_time_timestamp()]") // TO DO
|
||||
text = replacetext(text, "\[date\]", "[GLOB.current_date_string]")
|
||||
text = replacetext(text, "\[station\]", "[SSmapping.map_datum.fluff_name]")
|
||||
if(!no_font)
|
||||
if(P)
|
||||
text = "<font face=\"[deffont]\" color=[P ? P.colour : "black"]>[text]</font>"
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
Remember to update _globalvars/traits.dm if you're adding/removing/renaming traits.
|
||||
*/
|
||||
|
||||
//mob traits
|
||||
//***** MOB TRAITS *****//
|
||||
#define TRAIT_BLIND "blind"
|
||||
#define TRAIT_MUTE "mute"
|
||||
#define TRAIT_DEAF "deaf"
|
||||
@@ -155,6 +155,10 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
/// Blowing kisses actually does damage to the victim
|
||||
#define TRAIT_KISS_OF_DEATH "kiss_of_death"
|
||||
|
||||
//***** ITEM TRAITS *****//
|
||||
/// Show what machine/door wires do when held.
|
||||
#define TRAIT_SHOW_WIRE_INFO "show_wire_info"
|
||||
|
||||
//
|
||||
// common trait sources
|
||||
#define TRAIT_GENERIC "generic"
|
||||
|
||||
@@ -2072,7 +2072,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
return _list
|
||||
|
||||
/// Waits at a line of code until X is true
|
||||
#define UNTIL(X) while(!(X)) stoplag()
|
||||
#define UNTIL(X) while(!(X)) sleep(world.tick_lag)
|
||||
|
||||
// Check if the source atom contains another atom
|
||||
/atom/proc/contains(atom/location)
|
||||
|
||||
@@ -57,7 +57,12 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_NOGERMS" = TRAIT_NOGERMS,
|
||||
"TRAIT_NODECAY" = TRAIT_NODECAY,
|
||||
"TRAIT_NOEXAMINE" = TRAIT_NOEXAMINE,
|
||||
"TRAIT_NOPAIN" = TRAIT_NOPAIN)))
|
||||
"TRAIT_NOPAIN" = TRAIT_NOPAIN
|
||||
),
|
||||
/obj/item = list(
|
||||
"TRAIT_SHOW_WIRE_INFO" = TRAIT_SHOW_WIRE_INFO
|
||||
)
|
||||
))
|
||||
|
||||
/// value -> trait name, generated on use from trait_by_type global
|
||||
GLOBAL_LIST(trait_name_map)
|
||||
|
||||
@@ -278,6 +278,9 @@
|
||||
// Enable map voting
|
||||
var/map_voting_enabled = FALSE
|
||||
|
||||
// 2FA auth host
|
||||
var/_2fa_auth_host = null
|
||||
|
||||
/datum/configuration/New()
|
||||
for(var/T in subtypesof(/datum/game_mode))
|
||||
var/datum/game_mode/M = T
|
||||
@@ -775,6 +778,8 @@
|
||||
auto_profile = TRUE
|
||||
if("enable_map_voting")
|
||||
map_voting_enabled = TRUE
|
||||
if("2fa_host")
|
||||
_2fa_auth_host = value
|
||||
else
|
||||
log_config("Unknown setting in configuration: '[name]'")
|
||||
|
||||
|
||||
@@ -12,8 +12,11 @@ SUBSYSTEM_DEF(http)
|
||||
/// Total requests the SS has processed in a round
|
||||
var/total_requests
|
||||
|
||||
/datum/controller/subsystem/http/Initialize(start_timeofday)
|
||||
/datum/controller/subsystem/http/PreInit()
|
||||
. = ..()
|
||||
rustg_create_async_http_client() // Open the door
|
||||
|
||||
/datum/controller/subsystem/http/Initialize(start_timeofday)
|
||||
active_async_requests = list()
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -935,6 +935,14 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
|
||||
containername = "surgery crate"
|
||||
access = ACCESS_MEDICAL
|
||||
|
||||
/datum/supply_packs/medical/gloves
|
||||
name = "Nitrile Glove Crate"
|
||||
contains = list(/obj/item/clothing/gloves/color/latex/nitrile,
|
||||
/obj/item/clothing/gloves/color/latex/nitrile,
|
||||
/obj/item/clothing/gloves/color/latex/nitrile,
|
||||
/obj/item/clothing/gloves/color/latex/nitrile)
|
||||
cost = 50
|
||||
containername = "nitrile glove crate"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////// Science /////////////////////////////////////////
|
||||
|
||||
@@ -209,7 +209,7 @@
|
||||
/**
|
||||
* Proc called to determine if the user can see wire define information, such as "Contraband", "Door Bolts", etc.
|
||||
*
|
||||
* If the user is an admin, or has a multitool which reveals wire information in their active hand, the proc returns TRUE.
|
||||
* If the user is an admin, or has an item which reveals wire information in their active hand, the proc returns TRUE.
|
||||
*
|
||||
* Arguments:
|
||||
* * user - the mob who is interacting with the wires.
|
||||
@@ -217,10 +217,9 @@
|
||||
/datum/wires/proc/can_see_wire_info(mob/user)
|
||||
if(user.can_admin_interact())
|
||||
return TRUE
|
||||
else if(istype(user.get_active_hand(), /obj/item/multitool))
|
||||
var/obj/item/multitool/M = user.get_active_hand()
|
||||
if(M.shows_wire_information)
|
||||
return TRUE
|
||||
var/obj/item/held_item = user.get_active_hand()
|
||||
if(istype(held_item) && HAS_TRAIT(held_item, TRAIT_SHOW_WIRE_INFO))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
|
||||
@@ -607,53 +607,75 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "fpmaint"
|
||||
|
||||
/area/maintenance/fpmaint
|
||||
name = "EVA Maintenance"
|
||||
name = "Fore-Port Maintenance"
|
||||
icon_state = "fpmaint"
|
||||
|
||||
/area/maintenance/fpmaint2
|
||||
name = "Arrivals North Maintenance"
|
||||
name = "Fore-Port Secondary Maintenance"
|
||||
icon_state = "fpmaint"
|
||||
|
||||
/area/maintenance/fsmaint
|
||||
name = "Dormitory Maintenance"
|
||||
name = "Fore-Starboard Maintenance"
|
||||
icon_state = "fsmaint"
|
||||
|
||||
/area/maintenance/fsmaint2
|
||||
name = "Bar Maintenance"
|
||||
name = "Fore-Starboard Secondary Maintenance"
|
||||
icon_state = "fsmaint"
|
||||
|
||||
/area/maintenance/asmaint
|
||||
name = "Medbay Maintenance"
|
||||
name = "Aft-Starboard Maintenance"
|
||||
icon_state = "asmaint"
|
||||
|
||||
/area/maintenance/asmaint2
|
||||
name = "Science Maintenance"
|
||||
name = "Aft-Starboard Secondary Maintenance"
|
||||
icon_state = "asmaint"
|
||||
|
||||
/area/maintenance/apmaint
|
||||
name = "Cargo Maintenance"
|
||||
name = "Aft-Port Maintenance"
|
||||
icon_state = "apmaint"
|
||||
|
||||
/area/maintenance/apmaint2
|
||||
name = "Aft-Port Secondary Maintenance"
|
||||
icon_state = "apmaint"
|
||||
|
||||
/area/maintenance/maintcentral
|
||||
name = "Bridge Maintenance"
|
||||
name = "Central Maintenance"
|
||||
icon_state = "maintcentral"
|
||||
|
||||
/area/maintenance/maintcentral2
|
||||
name = "Central Secondary Maintenance"
|
||||
icon_state = "maintcentral"
|
||||
/area/maintenance/fore
|
||||
name = "Fore Maintenance"
|
||||
icon_state = "fmaint"
|
||||
|
||||
/area/maintenance/fore2
|
||||
name = "Fore Secondary Maintenance"
|
||||
icon_state = "fmaint"
|
||||
|
||||
/area/maintenance/aft
|
||||
name = "Aft Maintenance"
|
||||
icon_state = "amaint"
|
||||
|
||||
/area/maintenance/aft2
|
||||
name = "Aft Secondary Maintenance"
|
||||
icon_state = "amaint"
|
||||
|
||||
/area/maintenance/starboard
|
||||
name = "Starboard Maintenance"
|
||||
icon_state = "smaint"
|
||||
|
||||
/area/maintenance/starboard2
|
||||
name = "Starboard Secondary Maintenance"
|
||||
icon_state = "smaint"
|
||||
|
||||
/area/maintenance/port
|
||||
name = "Locker Room Maintenance"
|
||||
name = "Port Maintenance"
|
||||
icon_state = "pmaint"
|
||||
|
||||
/area/maintenance/aft
|
||||
name = "Engineering Maintenance"
|
||||
icon_state = "amaint"
|
||||
|
||||
/area/maintenance/port2
|
||||
name = "Port Secondary Maintenance"
|
||||
icon_state = "pmaint"
|
||||
/area/maintenance/storage
|
||||
name = "Atmospherics Maintenance"
|
||||
icon_state = "green"
|
||||
@@ -677,18 +699,18 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/maintenance/electrical
|
||||
name = "Electrical Maintenance"
|
||||
icon_state = "yellow"
|
||||
icon_state = "elec"
|
||||
|
||||
/area/maintenance/abandonedbar
|
||||
name = "Maintenance Bar"
|
||||
icon_state = "yellow"
|
||||
icon_state = "oldbar"
|
||||
power_equip = 0
|
||||
power_light = 0
|
||||
power_environ = 0
|
||||
|
||||
/area/maintenance/electrical_shop
|
||||
name ="Electronics Den"
|
||||
icon_state = "yellow"
|
||||
icon_state = "elec"
|
||||
|
||||
/area/maintenance/gambling_den
|
||||
name = "Gambling Den"
|
||||
@@ -696,7 +718,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/maintenance/consarea
|
||||
name = "Alternate Construction Area"
|
||||
icon_state = "yellow"
|
||||
icon_state = "construction"
|
||||
|
||||
|
||||
//Hallway
|
||||
@@ -836,7 +858,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/comms
|
||||
name = "\improper Communications Relay"
|
||||
icon_state = "tcomsatcham"
|
||||
icon_state = "tcomms"
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/server
|
||||
@@ -846,11 +868,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/ntrep
|
||||
name = "\improper Nanotrasen Representative's Office"
|
||||
icon_state = "bluenew"
|
||||
icon_state = "ntrep"
|
||||
|
||||
/area/blueshield
|
||||
name = "\improper Blueshield's Office"
|
||||
icon_state = "blueold"
|
||||
icon_state = "blueshield"
|
||||
|
||||
/area/centcomdocks
|
||||
name = "\improper Central Command Docks"
|
||||
@@ -919,7 +941,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/crew_quarters/bar
|
||||
name = "\improper Bar"
|
||||
icon_state = "bar"
|
||||
icon_state = "barstation"
|
||||
sound_environment = SOUND_AREA_WOODFLOOR
|
||||
|
||||
/area/crew_quarters/bar/atrium
|
||||
@@ -1048,45 +1070,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/holodeck/source_knightarena
|
||||
name = "\improper Holodeck - Knight Arena"
|
||||
|
||||
|
||||
//Embassies
|
||||
/area/embassy/
|
||||
name = "\improper Embassy Hallway"
|
||||
|
||||
/area/embassy/tajaran
|
||||
name = "\improper Tajaran Embassy"
|
||||
icon_state = "tajaran"
|
||||
|
||||
/area/embassy/skrell
|
||||
name = "\improper Skrell Embassy"
|
||||
icon_state = "skrell"
|
||||
|
||||
/area/embassy/unathi
|
||||
name = "\improper Unathi Embassy"
|
||||
icon_state = "unathi"
|
||||
|
||||
/area/embassy/kidan
|
||||
name = "\improper Kidan Embassy"
|
||||
icon_state = "kidan"
|
||||
|
||||
/area/embassy/diona
|
||||
name = "\improper Diona Embassy"
|
||||
icon_state = "diona"
|
||||
|
||||
/area/embassy/slime
|
||||
name = "\improper Slime Person Embassy"
|
||||
icon_state = "slime"
|
||||
|
||||
/area/embassy/grey
|
||||
name = "\improper Grey Embassy"
|
||||
icon_state = "grey"
|
||||
|
||||
/area/embassy/vox
|
||||
name = "\improper Vox Embassy"
|
||||
icon_state = "vox"
|
||||
|
||||
|
||||
|
||||
//Engineering
|
||||
/area/engine
|
||||
ambientsounds = ENGINEERING_SOUNDS
|
||||
@@ -1310,15 +1293,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/medical/robotics
|
||||
name = "Robotics"
|
||||
icon_state = "medresearch"
|
||||
icon_state = "research"
|
||||
|
||||
/area/medical/research
|
||||
name = "Medical Research"
|
||||
icon_state = "medresearch"
|
||||
|
||||
/area/medical/research_shuttle_dock
|
||||
name = "\improper Research Shuttle Dock"
|
||||
icon_state = "medresearch"
|
||||
name = "Research Division"
|
||||
icon_state = "research"
|
||||
|
||||
/area/medical/virology
|
||||
name = "Virology"
|
||||
@@ -1459,10 +1438,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
name = "Security Equipment Storage"
|
||||
icon_state = "securityequipmentstorage"
|
||||
|
||||
/area/security/interrogationhallway
|
||||
name = "\improper Interrogation Hallway"
|
||||
icon_state = "interrogationhall"
|
||||
|
||||
/area/security/courtroomdandp
|
||||
name = "\improper Courtroom Defense and Prosecution"
|
||||
icon_state = "seccourt"
|
||||
@@ -1505,7 +1480,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "secarmory"
|
||||
|
||||
/area/security/securehallway
|
||||
name = "\improper Security Secure Hallway"
|
||||
name = "\improper Brig Secure Hallway"
|
||||
icon_state = "securehall"
|
||||
|
||||
/area/security/hos
|
||||
@@ -2061,45 +2036,27 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/tcommsat/chamber
|
||||
name = "\improper Telecoms Central Compartment"
|
||||
icon_state = "tcomsatcham"
|
||||
icon_state = "tcomms"
|
||||
|
||||
// These areas are needed for MetaStation's AI sat
|
||||
/area/turret_protected/tcomsat
|
||||
name = "\improper Telecoms Satellite"
|
||||
icon_state = "tcomsatlob"
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
|
||||
|
||||
/area/turret_protected/tcomfoyer
|
||||
name = "\improper Telecoms Foyer"
|
||||
icon_state = "tcomsatentrance"
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
|
||||
|
||||
/area/turret_protected/tcomwest
|
||||
name = "\improper Telecoms West Wing"
|
||||
icon_state = "tcomsatwest"
|
||||
icon_state = "tcomms"
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
|
||||
|
||||
/area/turret_protected/tcomeast
|
||||
name = "\improper Telecoms East Wing"
|
||||
icon_state = "tcomsateast"
|
||||
icon_state = "tcomms"
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
|
||||
|
||||
/area/tcommsat/computer
|
||||
name = "\improper Telecoms Control Room"
|
||||
icon_state = "tcomsatcomp"
|
||||
icon_state = "tcomms"
|
||||
sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR
|
||||
|
||||
/area/tcommsat/server
|
||||
name = "\improper Telecoms Server Room"
|
||||
icon_state = "tcomsatcham"
|
||||
|
||||
/area/tcommsat/lounge
|
||||
name = "\improper Telecoms Lounge"
|
||||
icon_state = "tcomsatlounge"
|
||||
|
||||
/area/tcommsat/powercontrol
|
||||
name = "\improper Telecoms Power Control"
|
||||
icon_state = "tcomsatwest"
|
||||
icon_state = "tcomms"
|
||||
|
||||
// Away Missions
|
||||
/area/awaymission
|
||||
|
||||
@@ -366,6 +366,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
return
|
||||
|
||||
var/sacrifice_fulfilled
|
||||
var/worthless = FALSE
|
||||
var/datum/game_mode/gamemode = SSticker.mode
|
||||
if(offering.mind)
|
||||
GLOB.sacrificed += offering.mind
|
||||
@@ -379,13 +380,16 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
if(sacrifice_fulfilled)
|
||||
to_chat(M, "<span class='cultlarge'>\"Yes! This is the one I desire! You have done well.\"</span>")
|
||||
else
|
||||
if(ishuman(offering) || isrobot(offering))
|
||||
if(ishuman(offering) && offering.mind.offstation_role && offering.mind.special_role != SPECIAL_ROLE_ERT) //If you try it on a ghost role, you get nothing
|
||||
to_chat(M, "<span class='cultlarge'>\"This soul is of no use to either of us.\"</span>")
|
||||
worthless = TRUE
|
||||
else if(ishuman(offering) || isrobot(offering))
|
||||
to_chat(M, "<span class='cultlarge'>\"I accept this sacrifice.\"</span>")
|
||||
else
|
||||
to_chat(M, "<span class='cultlarge'>\"I accept this meager sacrifice.\"</span>")
|
||||
playsound(offering, 'sound/misc/demon_consume.ogg', 100, TRUE)
|
||||
|
||||
if((ishuman(offering) || isrobot(offering) || isbrain(offering)) && offering.mind)
|
||||
if(((ishuman(offering) || isrobot(offering) || isbrain(offering)) && offering.mind) && !worthless)
|
||||
var/obj/item/soulstone/stone = new /obj/item/soulstone(get_turf(src))
|
||||
stone.invisibility = INVISIBILITY_MAXIMUM // So it's not picked up during transfer_soul()
|
||||
stone.transfer_soul("FORCE", offering, user) // If it cannot be added
|
||||
|
||||
@@ -382,7 +382,7 @@ GLOBAL_VAR(bomb_set)
|
||||
else if(off_station == 2)
|
||||
to_chat(world, "<b>A nuclear device was set off, but the device was not on the station!</b>")
|
||||
else
|
||||
to_chat(world, "<b>The station was destoyed by the nuclear blast!</b>")
|
||||
to_chat(world, "<b>The station was destroyed by the nuclear blast!</b>")
|
||||
|
||||
SSticker.mode.station_was_nuked = (off_station < 2) //offstation==1 is a draw. the station becomes irradiated and needs to be evacuated.
|
||||
//kinda shit but I couldn't get permission to do what I wanted to do.
|
||||
|
||||
@@ -95,6 +95,10 @@
|
||||
to_chat(user, "<span class='cultlarge'>\"Come now, do not capture your fellow's soul.\"</span>")
|
||||
return ..()
|
||||
|
||||
if(M.mind.offstation_role && M.mind.special_role != SPECIAL_ROLE_ERT)
|
||||
to_chat(user, "<span class='warning'>This being's soul seems worthless. Not even the stone will absorb it.</span>")
|
||||
return ..()
|
||||
|
||||
if(optional)
|
||||
if(!M.ckey)
|
||||
to_chat(user, "<span class='warning'>They have no soul!</span>")
|
||||
@@ -312,9 +316,9 @@
|
||||
"Wraith" = /mob/living/simple_animal/hostile/construct/wraith,
|
||||
"Artificer" = /mob/living/simple_animal/hostile/construct/builder)
|
||||
/// Custom construct icons for different cults
|
||||
var/list/construct_icons = list("Juggernaut" = image(icon = 'icons/mob/mob.dmi', icon_state = SSticker.cultdat.get_icon("juggernaut")),
|
||||
"Wraith" = image(icon = 'icons/mob/mob.dmi', icon_state = SSticker.cultdat.get_icon("wraith")),
|
||||
"Artificer" = image(icon = 'icons/mob/mob.dmi', icon_state = SSticker.cultdat.get_icon("builder")))
|
||||
var/list/construct_icons = list("Juggernaut" = image(icon = 'icons/mob/cult.dmi', icon_state = SSticker.cultdat.get_icon("juggernaut")),
|
||||
"Wraith" = image(icon = 'icons/mob/cult.dmi', icon_state = SSticker.cultdat.get_icon("wraith")),
|
||||
"Artificer" = image(icon = 'icons/mob/cult.dmi', icon_state = SSticker.cultdat.get_icon("builder")))
|
||||
|
||||
if(shade)
|
||||
var/construct_choice = show_radial_menu(user, shell, construct_icons, custom_check = CALLBACK(src, .proc/radial_check, user), require_near = TRUE)
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
toolspeed = 1
|
||||
tool_behaviour = TOOL_MULTITOOL
|
||||
hitsound = 'sound/weapons/tap.ogg'
|
||||
var/shows_wire_information = FALSE // shows what a wire does if set to TRUE
|
||||
var/obj/machinery/buffer // simple machine buffer for device linkage
|
||||
|
||||
/obj/item/multitool/proc/IsBufferA(typepath)
|
||||
@@ -95,7 +94,10 @@
|
||||
/obj/item/multitool/ai_detect/admin
|
||||
desc = "Used for pulsing wires to test which to cut. Not recommended by doctors. Has a strange tag that says 'Grief in Safety'" //What else should I say for a meme item?
|
||||
track_delay = 5
|
||||
shows_wire_information = TRUE
|
||||
|
||||
/obj/item/multitool/ai_detect/admin/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_SHOW_WIRE_INFO, ROUNDSTART_TRAIT)
|
||||
|
||||
/obj/item/multitool/ai_detect/admin/multitool_detect()
|
||||
var/turf/our_turf = get_turf(src)
|
||||
@@ -112,6 +114,12 @@
|
||||
desc = "Optimised and stripped-down version of a regular multitool."
|
||||
toolspeed = 0.5
|
||||
|
||||
/obj/item/multitool/cyborg/drone
|
||||
|
||||
/obj/item/multitool/cyborg/drone/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_SHOW_WIRE_INFO, ROUNDSTART_TRAIT) // Drones are linked to the station
|
||||
|
||||
/obj/item/multitool/abductor
|
||||
name = "alien multitool"
|
||||
desc = "An omni-technological interface."
|
||||
@@ -119,4 +127,7 @@
|
||||
icon_state = "multitool"
|
||||
toolspeed = 0.1
|
||||
origin_tech = "magnets=5;engineering=5;abductor=3"
|
||||
shows_wire_information = TRUE
|
||||
|
||||
/obj/item/multitool/abductor/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_SHOW_WIRE_INFO, ROUNDSTART_TRAIT)
|
||||
|
||||
@@ -62,11 +62,21 @@
|
||||
origin_tech = "materials=5;engineering=4;abductor=3"
|
||||
random_color = FALSE
|
||||
|
||||
/obj/item/wirecutters/abductor/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_SHOW_WIRE_INFO, ROUNDSTART_TRAIT)
|
||||
|
||||
/obj/item/wirecutters/cyborg
|
||||
name = "wirecutters"
|
||||
desc = "This cuts wires."
|
||||
toolspeed = 0.5
|
||||
|
||||
/obj/item/wirecutters/cyborg/drone
|
||||
|
||||
/obj/item/wirecutters/cyborg/drone/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_SHOW_WIRE_INFO, ROUNDSTART_TRAIT) // Drones are linked to the station
|
||||
|
||||
/obj/item/wirecutters/power
|
||||
name = "jaws of life"
|
||||
desc = "A set of jaws of life, the magic of science has managed to fit it down into a device small enough to fit in a tool belt. It's fitted with a cutting head."
|
||||
|
||||
@@ -35,10 +35,19 @@
|
||||
QDEL_NULL(showpiece)
|
||||
return ..()
|
||||
|
||||
/obj/structure/displaycase/emag_act(mob/user)
|
||||
if(!emagged)
|
||||
to_chat(user, "<span class='warning'>You override the ID lock on [src].</span>")
|
||||
trigger_alarm()
|
||||
|
||||
emagged = TRUE
|
||||
|
||||
/obj/structure/displaycase/examine(mob/user)
|
||||
. = ..()
|
||||
if(alert)
|
||||
. += "<span class='notice'>Hooked up with an anti-theft system.</span>"
|
||||
if(emagged)
|
||||
. += "<span class='warning'>The ID lock has been shorted out.</span>"
|
||||
if(showpiece)
|
||||
. += "<span class='notice'>There's [showpiece] inside.</span>"
|
||||
if(trophy_message)
|
||||
@@ -100,7 +109,7 @@
|
||||
|
||||
/obj/structure/displaycase/attackby(obj/item/I, mob/user, params)
|
||||
if(I.GetID() && !broken && openable)
|
||||
if(allowed(user))
|
||||
if(allowed(user) || emagged)
|
||||
to_chat(user, "<span class='notice'>You [open ? "close":"open"] [src].</span>")
|
||||
toggle_lock(user)
|
||||
else
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//Blocks an attempt to connect before even creating our client datum thing.
|
||||
/world/IsBanned(key, address, computer_id, type, check_ipintel = TRUE)
|
||||
/world/IsBanned(key, address, computer_id, type, check_ipintel = TRUE, check_2fa = TRUE)
|
||||
|
||||
if(!key || !address || !computer_id)
|
||||
log_adminwarn("Failed Login (invalid data): [key] [address]-[computer_id]")
|
||||
@@ -44,6 +44,49 @@
|
||||
return list("reason"="using proxy or vpn", "desc"="\nReason: Proxies/VPNs are not allowed here. [mistakemessage]")
|
||||
|
||||
|
||||
// If 2FA is enabled, makes sure they were authed within the last minute
|
||||
if(check_2fa && config._2fa_auth_host)
|
||||
// First see if they exist at all
|
||||
var/datum/db_query/check_query = SSdbcore.NewQuery("SELECT 2fa_status, ip FROM [format_table_name("player")] WHERE ckey=:ckey", list("ckey" = ckey(key)))
|
||||
|
||||
if(!check_query.warn_execute())
|
||||
message_admins("Failed to do a DB 2FA check for [key]. You have been warned.")
|
||||
qdel(check_query)
|
||||
return
|
||||
|
||||
|
||||
// If a row is returned, the player exists
|
||||
var/_2fa_enabled = FALSE
|
||||
var/always_check = FALSE
|
||||
var/last_ip
|
||||
if(check_query.NextRow())
|
||||
if(check_query.item[1] != _2FA_DISABLED)
|
||||
_2fa_enabled = TRUE
|
||||
if(check_query.item[1] == _2FA_ENABLED_ALWAYS)
|
||||
always_check = TRUE
|
||||
last_ip = check_query.item[2]
|
||||
qdel(check_query)
|
||||
|
||||
// If client has 2FA enabled, and they either:
|
||||
// Have it set to always check, or their IP is different
|
||||
if(_2fa_enabled && (always_check || (address != last_ip)))
|
||||
// They have 2FA enabled, lets make sure they have authed within the last minute
|
||||
var/datum/db_query/verify_query = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("2fa_secrets")] WHERE (last_time BETWEEN NOW() - INTERVAL 1 MINUTE AND NOW()) AND ckey=:ckey LIMIT 1", list(
|
||||
"ckey" = ckey(key)
|
||||
))
|
||||
|
||||
if(!verify_query.warn_execute())
|
||||
message_admins("Failed to do a DB 2FA check for [key]. You have been warned.")
|
||||
qdel(verify_query)
|
||||
return
|
||||
|
||||
if(!verify_query.NextRow())
|
||||
// If no row was returned, fail 2FA
|
||||
qdel(verify_query)
|
||||
return list("reason"="2fa check failed", "desc"="You have 2FA enabled but did not properly authenticate.")
|
||||
|
||||
qdel(verify_query)
|
||||
|
||||
if(config.ban_legacy_system)
|
||||
//Ban Checking
|
||||
. = CheckBan(ckey(key), computer_id, address)
|
||||
|
||||
@@ -133,7 +133,6 @@
|
||||
area_whitelist = list(/area/medical/virology,
|
||||
/area/toxins,
|
||||
/area/medical/research,
|
||||
/area/medical/research_shuttle_dock,
|
||||
/area/crew_quarters/hor,
|
||||
/area/maintenance/asmaint2)
|
||||
|
||||
@@ -164,7 +163,6 @@
|
||||
TYPE_PSYCHIC)
|
||||
area_blacklist = list(/area/toxins,
|
||||
/area/medical/research,
|
||||
/area/medical/research_shuttle_dock,
|
||||
/area/crew_quarters/hor,
|
||||
/area/maintenance/asmaint2,
|
||||
/area/teleporter,
|
||||
|
||||
@@ -358,28 +358,30 @@ GLOBAL_DATUM_INIT(_preloader, /datum/dmm_suite/preloader, new())
|
||||
/datum/dmm_suite/proc/readlist(text, delimiter = ",")
|
||||
var/list/to_return = list()
|
||||
|
||||
var/position
|
||||
var/delimiter_position
|
||||
var/old_position = 1
|
||||
|
||||
do
|
||||
// find next delimiter that is not within "..."
|
||||
position = find_next_delimiter_position(text, old_position, delimiter)
|
||||
delimiter_position = find_next_delimiter_position(text, old_position, delimiter)
|
||||
|
||||
// check if this is a simple variable (as in list(var1, var2)) or an associative one (as in list(var1="foo", var2=7))
|
||||
var/equal_position = findtext(text, "=", old_position, position)
|
||||
var/equal_position = findtext(text, "=", old_position, delimiter_position)
|
||||
|
||||
var/trim_left = trim_text(copytext(text, old_position, (equal_position ? equal_position : position)), 1) // the name of the variable, must trim quotes to build a BYOND compliant associatives list
|
||||
old_position = position + 1
|
||||
// Take the left value of the association or just the value if it isn't an association
|
||||
var/left_value = copytext(text, old_position, (equal_position ? equal_position : delimiter_position))
|
||||
old_position = delimiter_position + 1
|
||||
|
||||
if(equal_position) // associative var, so do the association
|
||||
var/trim_right = trim_text(copytext(text, equal_position + 1, position)) // the content of the variable
|
||||
left_value = trim_text(left_value, TRUE) // the name of the variable, must trim quotes to build a BYOND compliant associatives list
|
||||
var/trim_right = trim_text(copytext(text, equal_position + 1, delimiter_position)) // the content of the variable
|
||||
|
||||
to_return[trim_left] = parse_value(trim_right)
|
||||
to_return[left_value] = parse_value(trim_right)
|
||||
|
||||
else// simple var
|
||||
to_return += parse_value(trim_left)
|
||||
to_return += parse_value(trim_text(left_value)) // Don't trim the quotes
|
||||
|
||||
while(position != 0)
|
||||
while(delimiter_position != 0)
|
||||
|
||||
return to_return
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
// This is in its own file as it has so much stuff to contend with
|
||||
/client/proc/edit_2fa()
|
||||
if(!config._2fa_auth_host)
|
||||
alert(usr, "This server does not have 2FA enabled.")
|
||||
return
|
||||
// Client does not have 2FA enabled. Set it up.
|
||||
if(prefs._2fa_status == _2FA_DISABLED)
|
||||
// Get us an auth token
|
||||
var/datum/http_response/qrcr = wrap_http_get("[config._2fa_auth_host]/generateQR?ckey=[ckey]")
|
||||
// If this fails, shits gone bad
|
||||
if(qrcr.errored)
|
||||
alert(usr, "Something has gone VERY wrong ingame. Please inform the server host.\nError details: [qrcr.error]")
|
||||
return
|
||||
|
||||
if(qrcr.status_code != 200)
|
||||
alert(usr, "2FA QR code generation returned a non-200 code. Please inform the server host.\nError code: [qrcr.status_code]\nError details: [qrcr.body]")
|
||||
return
|
||||
|
||||
var/list/data = json_decode(qrcr.body)
|
||||
var/qr_img_src = data["qr_image"]
|
||||
var/datum/browser/B = new(usr, "2fa_qrc", "2FA QR Code", 600, 400)
|
||||
var/title_text = "<p>Below is a QR code to scan inside your authenticator app to generate 2FA codes. Please verify it before closing this window. (Behind this window is a text box)</p>"
|
||||
var/img_data = "<div style=\"text-align:center;\"><img src=\"[qr_img_src]\"></div>"
|
||||
B.set_content("[title_text][img_data]")
|
||||
B.open(FALSE)
|
||||
|
||||
var/entered_code = input(usr, "Please enter a code from your auth app. Failure to enter the code correctly will abort 2FA setup.", "2FA Validation")
|
||||
if(!entered_code)
|
||||
// Cleanup so they can start again
|
||||
var/datum/db_query/dbq = SSdbcore.NewQuery("DELETE FROM [format_table_name("2fa_secrets")] WHERE ckey=:ckey", list("ckey" = ckey))
|
||||
dbq.warn_execute()
|
||||
alert(usr, "2FA Setup aborted!")
|
||||
B.close()
|
||||
return
|
||||
|
||||
var/datum/http_response/vr = wrap_http_get("[config._2fa_auth_host]/validateCode?ckey=[ckey]&code=[entered_code]")
|
||||
// If this fails, shits gone bad
|
||||
if(vr.errored)
|
||||
alert(usr, "Something has gone VERY wrong ingame. Please inform the server host.\nError details: [vr.error]")
|
||||
B.close()
|
||||
return
|
||||
|
||||
if(vr.status_code != 200)
|
||||
// Cleanup so they can start again
|
||||
var/datum/db_query/dbq = SSdbcore.NewQuery("DELETE FROM [format_table_name("2fa_secrets")] WHERE ckey=:ckey", list("ckey" = ckey))
|
||||
dbq.warn_execute()
|
||||
|
||||
// See if its unauthorised. I used 400 for that dont at me
|
||||
if(vr.status_code == 400)
|
||||
alert(usr, "Invalid code entered. 2FA Setup aborted!")
|
||||
B.close()
|
||||
else
|
||||
alert(usr, "2FA validation returned a non-200 code. Please inform the server host.\nError code: [vr.status_code]\nError details: [vr.body]")
|
||||
B.close()
|
||||
return
|
||||
|
||||
// If we are here, they authed successfully
|
||||
alert(usr, "Congratulations. 2FA is now setup properly for your account. In preferences, you can change whether you want it to ask for a code on every connection or only when your IP changes")
|
||||
B.close()
|
||||
// Default to IP change only
|
||||
prefs._2fa_status = _2FA_ENABLED_IP
|
||||
prefs.save_preferences(src)
|
||||
prefs.ShowChoices(usr)
|
||||
return
|
||||
|
||||
|
||||
// If we are here, they just want to change the mode
|
||||
var/option = alert(usr, "Would you like to change 2FA mode or disable it entirely?", "2FA Mode", "Enable (Always)", "Enable (On IP Change)", "Deactivate")
|
||||
switch(option)
|
||||
if("Enable (Always)")
|
||||
prefs._2fa_status = _2FA_ENABLED_ALWAYS
|
||||
prefs.save_preferences(src)
|
||||
prefs.ShowChoices(usr)
|
||||
if("Enable (On IP Change)")
|
||||
prefs._2fa_status = _2FA_ENABLED_IP
|
||||
prefs.save_preferences(src)
|
||||
prefs.ShowChoices(usr)
|
||||
if("Deactivate")
|
||||
var/confirm = alert(usr, "Are you SURE you want to deactivate 2FA?", "WARNING", "Yes", "No")
|
||||
if(confirm != "Yes")
|
||||
return
|
||||
|
||||
// Prompt them for a code to make sure they know what they are doing
|
||||
var/entered_code = input(usr, "Please enter a code from your auth app", "2FA Validation")
|
||||
if(!entered_code)
|
||||
alert(usr, "2FA deactivation aborted!")
|
||||
return
|
||||
|
||||
var/datum/http_response/vr = wrap_http_get("[config._2fa_auth_host]/validateCode?ckey=[ckey]&code=[entered_code]")
|
||||
// If this fails, shits gone bad
|
||||
if(vr.errored)
|
||||
alert(usr, "Something has gone VERY wrong ingame. Please inform the server host.\nError details: [vr.error]")
|
||||
return
|
||||
|
||||
if(vr.status_code != 200)
|
||||
// See if its unauthorised. I used 400 for that dont at me
|
||||
if(vr.status_code == 400)
|
||||
alert(usr, "Invalid code entered. 2FA deactivation aborted!")
|
||||
else
|
||||
alert(usr, "2FA validation returned non-200 code. Please inform the server host.\nError code: [vr.status_code]\nError details: [vr.body]")
|
||||
return
|
||||
|
||||
// If we are here, they authed properly
|
||||
var/datum/db_query/dbq = SSdbcore.NewQuery("DELETE FROM [format_table_name("2fa_secrets")] WHERE ckey=:ckey", list("ckey" = ckey))
|
||||
dbq.warn_execute()
|
||||
prefs._2fa_status = _2FA_DISABLED
|
||||
prefs.save_preferences(src)
|
||||
prefs.ShowChoices(usr)
|
||||
alert(usr, "2FA disabled successfully")
|
||||
|
||||
/datum/preferences/proc/_2fastatus_to_text()
|
||||
switch(_2fa_status)
|
||||
if(_2FA_DISABLED)
|
||||
return "Disabled"
|
||||
if(_2FA_ENABLED_IP)
|
||||
return "Enabled (Will prompt on IP changes)"
|
||||
if(_2FA_ENABLED_ALWAYS)
|
||||
return "Enabled (Will prompt every time)"
|
||||
|
||||
|
||||
// Proc to wrap HTTP requests properly, without needing SShttp firing
|
||||
/proc/wrap_http_get(url)
|
||||
var/datum/http_request/req = new()
|
||||
req.prepare(RUSTG_HTTP_METHOD_GET, url)
|
||||
req.begin_async()
|
||||
// Check if we are complete
|
||||
UNTIL(req.is_complete())
|
||||
var/datum/http_response/res = req.into_response()
|
||||
|
||||
return res
|
||||
|
||||
@@ -205,6 +205,8 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
|
||||
var/gear_tab = "General"
|
||||
// Parallax
|
||||
var/parallax = PARALLAX_HIGH
|
||||
/// 2FA status
|
||||
var/_2fa_status = _2FA_DISABLED
|
||||
/// Do we want to force our runechat colour to be white?
|
||||
var/force_white_runechat = FALSE
|
||||
|
||||
@@ -448,6 +450,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
|
||||
// LEFT SIDE OF THE PAGE
|
||||
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
|
||||
dat += "<h2>General Settings</h2>"
|
||||
dat += "<b>2FA Setup:</b> <a href='?_src_=prefs;preference=edit_2fa'>[_2fastatus_to_text()]</a><br>"
|
||||
if(user.client.holder)
|
||||
dat += "<b>Adminhelp sound:</b> <a href='?_src_=prefs;preference=hear_adminhelps'><b>[(sound & SOUND_ADMINHELP)?"On":"Off"]</b></a><br>"
|
||||
dat += "<b>AFK Cryoing:</b> <a href='?_src_=prefs;preference=afk_watch'>[(toggles2 & PREFTOGGLE_2_AFKWATCH) ? "Yes" : "No"]</a><br>"
|
||||
@@ -2144,6 +2147,11 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
|
||||
if(parent && parent.mob && parent.mob.hud_used)
|
||||
parent.mob.hud_used.update_parallax_pref()
|
||||
|
||||
if("edit_2fa")
|
||||
// Do this async so we arent holding up a topic() call
|
||||
INVOKE_ASYNC(user.client, /client.proc/edit_2fa)
|
||||
return // We return here to avoid focus being lost
|
||||
|
||||
|
||||
ShowChoices(user)
|
||||
return 1
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
clientfps,
|
||||
atklog,
|
||||
fuid,
|
||||
parallax
|
||||
parallax,
|
||||
2fa_status
|
||||
FROM [format_table_name("player")]
|
||||
WHERE ckey=:ckey"}, list(
|
||||
"ckey" = C.ckey
|
||||
@@ -45,6 +46,7 @@
|
||||
atklog = text2num(query.item[14])
|
||||
fuid = text2num(query.item[15])
|
||||
parallax = text2num(query.item[16])
|
||||
_2fa_status = query.item[17]
|
||||
|
||||
qdel(query)
|
||||
|
||||
@@ -93,7 +95,8 @@
|
||||
volume_mixer=:volume_mixer,
|
||||
lastchangelog=:lastchangelog,
|
||||
clientfps=:clientfps,
|
||||
parallax=:parallax
|
||||
parallax=:parallax,
|
||||
2fa_status=:_2fa_status
|
||||
WHERE ckey=:ckey"}, list(
|
||||
// OH GOD THE PARAMETERS
|
||||
"ooccolour" = ooccolor,
|
||||
@@ -111,7 +114,8 @@
|
||||
"lastchangelog" = lastchangelog,
|
||||
"clientfps" = clientfps,
|
||||
"parallax" = parallax,
|
||||
"ckey" = C.ckey
|
||||
"_2fa_status" = _2fa_status,
|
||||
"ckey" = C.ckey,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
user.visible_message("[user] places \the [src] against [M]'s chest and listens attentively.", "You place \the [src] against [M]'s chest...")
|
||||
var/obj/item/organ/internal/H = M.get_int_organ(/obj/item/organ/internal/heart)
|
||||
var/obj/item/organ/internal/L = M.get_int_organ(/obj/item/organ/internal/lungs)
|
||||
if((H && M.pulse) || (L && !HAS_TRAIT(M, TRAIT_NOBREATH)))
|
||||
if(M.pulse && (H || (L && !HAS_TRAIT(M, TRAIT_NOBREATH))))
|
||||
var/color = "notice"
|
||||
if(H)
|
||||
var/heart_sound
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
if(istype(M))
|
||||
if(isnewplayer(M)) // People in the lobby screen; only have their ckey as a name.
|
||||
continue
|
||||
if(isobserver(M))
|
||||
if(isobserver(M) && M.client)
|
||||
ghosts += list(serialized)
|
||||
else if(M.mind == null)
|
||||
npcs += list(serialized)
|
||||
|
||||
@@ -692,8 +692,8 @@
|
||||
/obj/item/screwdriver/cyborg,
|
||||
/obj/item/wrench/cyborg,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/wirecutters/cyborg,
|
||||
/obj/item/multitool/cyborg,
|
||||
/obj/item/wirecutters/cyborg/drone,
|
||||
/obj/item/multitool/cyborg/drone,
|
||||
/obj/item/lightreplacer/cyborg,
|
||||
/obj/item/gripper,
|
||||
/obj/item/matter_decompiler,
|
||||
|
||||
@@ -449,6 +449,7 @@
|
||||
|
||||
var/dat = "<html><body><center>"
|
||||
dat += "Round Duration: [round(hours)]h [round(mins)]m<br>"
|
||||
dat += "<b>The station alert level is: [get_security_level_colors()]</b><br>"
|
||||
|
||||
if(SSshuttle.emergency.mode >= SHUTTLE_ESCAPE)
|
||||
dat += "<font color='red'><b>The station has been evacuated.</b></font><br>"
|
||||
|
||||
@@ -249,6 +249,8 @@
|
||||
/obj/machinery/power/port_gen/pacman/proc/overheat()
|
||||
overheating++
|
||||
if(overheating > 60)
|
||||
message_admins("Pacman overheated at [ADMIN_JMP(loc)]. Last touched by: [fingerprintslast ? "[fingerprintslast]" : "*null*"].")
|
||||
log_game("Pacman overheated at [COORD(loc)]. Last touched by: [fingerprintslast ? "[fingerprintslast]" : "*null*"].")
|
||||
explode()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/explode()
|
||||
|
||||
@@ -188,7 +188,7 @@
|
||||
return
|
||||
if(being_used || !ismob(M))
|
||||
return
|
||||
if(!isanimal(M) || M.ckey) //only works on animals that aren't player controlled
|
||||
if(!isanimal(M) || M.mind) //only works on animals that aren't player controlled
|
||||
to_chat(user, "<span class='warning'>[M] is already too intelligent for this to work!</span>")
|
||||
return ..()
|
||||
if(M.stat)
|
||||
|
||||
@@ -173,3 +173,18 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur
|
||||
return SEC_LEVEL_EPSILON
|
||||
if("delta")
|
||||
return SEC_LEVEL_DELTA
|
||||
|
||||
/proc/get_security_level_colors()
|
||||
switch(GLOB.security_level)
|
||||
if(SEC_LEVEL_GREEN)
|
||||
return "<font color='limegreen'>Green</font>"
|
||||
if(SEC_LEVEL_BLUE)
|
||||
return "<font color='dodgerblue'>Blue</font>"
|
||||
if(SEC_LEVEL_RED)
|
||||
return "<font color='red'>Red</font>"
|
||||
if(SEC_LEVEL_GAMMA)
|
||||
return "<font color='gold'>Gamma</font>"
|
||||
if(SEC_LEVEL_EPSILON)
|
||||
return "<font color='blueviolet'>Epsilon</font>"
|
||||
if(SEC_LEVEL_DELTA)
|
||||
return "<font color='orangered'>Delta</font>"
|
||||
|
||||
@@ -474,3 +474,6 @@ ENABLE_AUTO_PROFILER
|
||||
|
||||
## Uncomment to enable map voting
|
||||
#ENABLE_MAP_VOTING
|
||||
|
||||
## Host for a custom 2FA server. Comment to disable. Do not use a trailing slash or https.
|
||||
#2FA_HOST http://127.0.0.1:8080
|
||||
|
||||
@@ -18,7 +18,7 @@ FEEDBACK_DATABASE feedback
|
||||
## This value must be set to the version of the paradise schema in use.
|
||||
## If this value does not match, the SQL database will not be loaded and an error will be generated.
|
||||
## Roundstart will be delayed.
|
||||
DB_VERSION 23
|
||||
DB_VERSION 24
|
||||
|
||||
## Prefix to be added to the name of every table, older databases will require this be set to erro_
|
||||
## If left out defaults to erro_ for legacy reasons, if you want no table prefix, give a blank prefix rather then comment out
|
||||
|
||||
@@ -185,7 +185,7 @@ var/list/chatResources = list(
|
||||
var/list/row = connectionHistory[i]
|
||||
if(!row || row.len < 3 || !(row["ckey"] && row["compid"] && row["ip"]))
|
||||
return
|
||||
if(world.IsBanned(key=row["ckey"], address=row["ip"], computer_id=row["compid"], type=null, check_ipintel=FALSE))
|
||||
if(world.IsBanned(key=row["ckey"], address=row["ip"], computer_id=row["compid"], type=null, check_ipintel=FALSE, check_2fa=FALSE))
|
||||
found = row
|
||||
break
|
||||
CHECK_TICK
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 30 KiB |
@@ -1345,6 +1345,7 @@
|
||||
#include "code\modules\buildmode\submodes\save.dm"
|
||||
#include "code\modules\buildmode\submodes\throwing.dm"
|
||||
#include "code\modules\buildmode\submodes\variable_edit.dm"
|
||||
#include "code\modules\client\2fa.dm"
|
||||
#include "code\modules\client\asset_cache.dm"
|
||||
#include "code\modules\client\client_defines.dm"
|
||||
#include "code\modules\client\client_procs.dm"
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"glob": "^7.1.4",
|
||||
"source-map": "^0.7.3",
|
||||
"stacktrace-parser": "^0.1.7",
|
||||
"ws": "^7.1.2"
|
||||
"ws": "^7.4.6"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ const AtmosControlMapView = (_properties, context) => {
|
||||
return (
|
||||
<Box height="526px" mb="0.5rem" overflow="hidden">
|
||||
<NanoMap onZoom={v => setZoom(v)}>
|
||||
{alarms.filter(a => a.z === 1).map(aa => (
|
||||
{alarms.filter(a => a.z === 2).map(aa => (
|
||||
// The AA means air alarm, and nothing else
|
||||
<NanoMap.Marker
|
||||
key={aa.ref}
|
||||
|
||||
File diff suppressed because one or more lines are too long
+4
-4
@@ -6263,10 +6263,10 @@ ws@^6.0.0:
|
||||
dependencies:
|
||||
async-limiter "~1.0.0"
|
||||
|
||||
ws@^7.1.2:
|
||||
version "7.2.3"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46"
|
||||
integrity sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==
|
||||
ws@^7.4.6:
|
||||
version "7.4.6"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
|
||||
integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
|
||||
|
||||
xregexp@^4.3.0:
|
||||
version "4.3.0"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Dont use it ingame
|
||||
# Remember to update this when you increase the SQL version! -aa
|
||||
SQL_ENABLED
|
||||
DB_VERSION 23
|
||||
DB_VERSION 24
|
||||
ADDRESS 127.0.0.1
|
||||
PORT 3306
|
||||
FEEDBACK_DATABASE feedback
|
||||
|
||||
Reference in New Issue
Block a user