[MIRROR] Chem duplication exploit fix (#11966)

Co-authored-by: Cameron Lennox <killer65311@gmail.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2025-11-11 13:38:22 -07:00
committed by GitHub
parent 3bc63ff7bf
commit 6aafb58257
5 changed files with 14 additions and 11 deletions

View File

@@ -237,7 +237,7 @@
var/has_clonexa = occupant.reagents.get_reagent_amount(REAGENT_ID_CLONEXADONE) >= 1
var/has_cryo_medicine = has_cryo || has_clonexa
if(beaker && !has_cryo_medicine)
beaker.reagents.trans_to_mob(occupant, 1, CHEM_BLOOD, 10)
beaker.reagents.trans_to_mob(occupant, 1, CHEM_BLOOD, 10, can_dialysis = FALSE)
/obj/machinery/atmospherics/unary/cryo_cell/proc/heat_gas_contents()
if(air_contents.total_moles < 1)

View File

@@ -116,7 +116,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(ishuman(loc))
var/mob/living/carbon/human/C = loc
if (src == C.wear_mask && C.check_has_mouth()) // if it's in the human/monkey mouth, transfer reagents to the mob
reagents.trans_to_mob(C, amount, CHEM_INGEST, 1.5) // I don't predict significant balance issues by letting blunts actually WORK.
reagents.trans_to_mob(C, amount, CHEM_INGEST, 1.5, can_dialysis = FALSE) // I don't predict significant balance issues by letting blunts actually WORK.
else // else just remove some of the reagents
reagents.remove_any(REM)

View File

@@ -107,7 +107,7 @@
/* Holder-to-chemical */
/datum/reagents/proc/add_reagent(var/id, var/amount, var/data = null, var/safety = 0, var/was_from_belly)
/datum/reagents/proc/add_reagent(var/id, var/amount, var/data = null, var/safety = 0, var/was_from_belly, var/can_dialysis = TRUE)
if(!isnum(amount) || amount <= 0)
return 0
@@ -122,6 +122,7 @@
if(was_from_belly)
current.from_belly = was_from_belly
current.dialysis_returnable = can_dialysis
current.volume += amount
if(!isnull(data)) // For all we know, it could be zero or empty string and meaningful
current.mix_data(data, amount)
@@ -249,7 +250,7 @@
handle_reactions()
return amount
/datum/reagents/proc/trans_to_holder(var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]).
/datum/reagents/proc/trans_to_holder(var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0, var/can_dialysis = TRUE) // Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]).
if(!target || !istype(target))
return
@@ -267,7 +268,8 @@
for(var/datum/reagent/current in reagent_list)
var/amount_to_transfer = current.volume * part
target.add_reagent(current.id, amount_to_transfer * multiplier, current.get_data(), safety = 1, was_from_belly = (current.from_belly || target_is_belly)) // We don't react until everything is in place
if(current.dialysis_returnable || (!current.dialysis_returnable && ismob(target))) //Prevents duplication of reagents.
target.add_reagent(current.id, amount_to_transfer * multiplier, current.get_data(), safety = 1, was_from_belly = (current.from_belly || target_is_belly), can_dialysis = can_dialysis) // We don't react until everything is in place
if(!copy)
remove_reagent(current.id, amount_to_transfer, 1)
@@ -403,7 +405,7 @@
perm = L.reagent_permeability()
return trans_to_mob(target, amount, CHEM_TOUCH, perm, copy)
/datum/reagents/proc/trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0) // Transfer after checking into which holder...
/datum/reagents/proc/trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0, var/can_dialysis = TRUE) // Transfer after checking into which holder...
if(!target || !istype(target))
return
if(iscarbon(target))
@@ -415,16 +417,16 @@
var/mob/living/carbon/C = target
if(type == CHEM_BLOOD)
var/datum/reagents/R = C.reagents
return trans_to_holder(R, amount, multiplier, copy)
return trans_to_holder(R, amount, multiplier, copy, can_dialysis)
if(type == CHEM_INGEST)
var/datum/reagents/R = C.ingested
return C.ingest(src, R, amount, multiplier, copy)
return C.ingest(src, R, amount, multiplier, copy, can_dialysis)
if(type == CHEM_TOUCH)
var/datum/reagents/R = C.touching
return trans_to_holder(R, amount, multiplier, copy)
return trans_to_holder(R, amount, multiplier, copy, can_dialysis)
else
var/datum/reagents/R = new /datum/reagents(amount)
. = trans_to_holder(R, amount, multiplier, copy)
. = trans_to_holder(R, amount, multiplier, copy, can_dialysis)
R.touch_mob(target)
/datum/reagents/proc/trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Turfs don't have any reagents (at least, for now). Just touch it.

View File

@@ -68,7 +68,7 @@
var/contained = reagentlist()
add_attack_logs(user,target,"Used [src.name] containing [contained]")
trans += reagents.trans_to_mob(target, min(amount_per_transfer_from_this, reagents.total_volume)/2, CHEM_INGEST) //Half injected, half ingested
trans += reagents.trans_to_mob(target, min(amount_per_transfer_from_this, reagents.total_volume)/2, CHEM_INGEST, can_dialysis = FALSE) //Half injected, half ingested
trans += reagents.trans_to_mob(target, min(amount_per_transfer_from_this, reagents.total_volume), CHEM_BLOOD) //I guess it gets into the bloodstream through the eyes or something
user.visible_message(span_warning("[user] squirts something into [target]'s eyes!"), span_notice("You transfer [trans] units of the solution."))

View File

@@ -42,6 +42,7 @@
var/list/glass_special = null // null equivalent to list()
var/from_belly = FALSE
var/dialysis_returnable = TRUE
var/wiki_flag = 0 // Bitflags for secret/food/drink reagent sorting
var/supply_conversion_value = null
var/industrial_use = null // unique description for export off station