Skip to content

Commit

Permalink
[MIRROR] Fixes infinite loop in bitrunning [MDB IGNORE] (#242)
Browse files Browse the repository at this point in the history
* Fixes infinite loop in bitrunning (#79194)

---------

Co-authored-by: Jeremiah <[email protected]>
Co-authored-by: Mothblocks <35135081+Mothblocks@ users.noreply.github.com>
  • Loading branch information
3 people authored Oct 23, 2023
1 parent 1f3bfdc commit 9c21af4
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 111 deletions.
3 changes: 3 additions & 0 deletions code/__DEFINES/dcs/signals/signals_bitrunning.dm
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@

/// from /obj/machinery/quantum_server/scrub_vdom()
#define COMSIG_BITRUNNER_DOMAIN_SCRUBBED "bitrunner_domain_scrubbed"

/// from /obj/machinery/netpod/open_machine()
#define COMSIG_BITRUNNER_NETPOD_OPENED "bitrunner_netpod_opened"
1 change: 1 addition & 0 deletions code/modules/bitrunning/components/avatar_connection.dm
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
avatar.key = old_body.key
ADD_TRAIT(old_body, TRAIT_MIND_TEMPORARILY_GONE, REF(src))

RegisterSignals(old_body, list(COMSIG_LIVING_DEATH, COMSIG_MOVABLE_MOVED, COMSIG_LIVING_STATUS_UNCONSCIOUS), PROC_REF(on_sever_connection))
RegisterSignal(pod, COMSIG_BITRUNNER_CROWBAR_ALERT, PROC_REF(on_netpod_crowbar))
RegisterSignal(pod, COMSIG_BITRUNNER_NETPOD_INTEGRITY, PROC_REF(on_netpod_damaged))
RegisterSignal(pod, COMSIG_BITRUNNER_SEVER_AVATAR, PROC_REF(on_sever_connection))
Expand Down
52 changes: 21 additions & 31 deletions code/modules/bitrunning/components/netpod_healing.dm
Original file line number Diff line number Diff line change
@@ -1,36 +1,18 @@
#define BASE_HEAL 4

/datum/component/netpod_healing
/// Brute damage to heal over a second
var/brute_heal = 0
/// Burn damage to heal over a second
var/burn_heal = 0
/// Toxin damage to heal over a second
var/toxin_heal = 0
/// Amount of cloning damage to heal over a second
var/clone_heal = 0
/// Amount of blood to heal over a second
var/blood_heal = 0

/datum/component/netpod_healing/Initialize(
brute_heal = 0,
burn_heal = 0,
toxin_heal = 0,
clone_heal = 0,
blood_heal = 0,
)
var/mob/living/carbon/player = parent
if (!iscarbon(player))

/datum/component/netpod_healing/Initialize(obj/machinery/netpod/pod)
if (!iscarbon(parent))
return COMPONENT_INCOMPATIBLE

RegisterSignal(pod, COMSIG_BITRUNNER_NETPOD_OPENED, PROC_REF(on_opened))

var/mob/living/carbon/player = parent
player.apply_status_effect(/datum/status_effect/embryonic, STASIS_NETPOD_EFFECT)

START_PROCESSING(SSmachines, src)

src.brute_heal = brute_heal
src.burn_heal = burn_heal
src.toxin_heal = toxin_heal
src.clone_heal = clone_heal
src.blood_heal = blood_heal

/datum/component/netpod_healing/Destroy(force, silent)
STOP_PROCESSING(SSmachines, src)

Expand All @@ -46,17 +28,23 @@
return

var/need_mob_update = FALSE
need_mob_update += owner.adjustBruteLoss(-brute_heal * seconds_per_tick, updating_health = FALSE)
need_mob_update += owner.adjustFireLoss(-burn_heal * seconds_per_tick, updating_health = FALSE)
need_mob_update += owner.adjustToxLoss(-toxin_heal * seconds_per_tick, updating_health = FALSE, forced = TRUE)
need_mob_update += owner.adjustCloneLoss(-clone_heal * seconds_per_tick, updating_health = FALSE)
need_mob_update += owner.adjustBruteLoss(-BASE_HEAL * seconds_per_tick, updating_health = FALSE)
need_mob_update += owner.adjustFireLoss(-BASE_HEAL * seconds_per_tick, updating_health = FALSE)
need_mob_update += owner.adjustToxLoss(-BASE_HEAL * seconds_per_tick, updating_health = FALSE, forced = TRUE)
need_mob_update += owner.adjustCloneLoss(-BASE_HEAL * seconds_per_tick, updating_health = FALSE)

if(owner.blood_volume < BLOOD_VOLUME_NORMAL)
owner.blood_volume += blood_heal * seconds_per_tick
owner.blood_volume += BASE_HEAL * seconds_per_tick

if(need_mob_update)
owner.updatehealth()

/// Deletes itself when the machine was opened
/datum/component/netpod_healing/proc/on_opened()
SIGNAL_HANDLER

qdel(src)

/datum/status_effect/embryonic
id = "embryonic"
alert_type = /atom/movable/screen/alert/status_effect/embryonic
Expand All @@ -65,3 +53,5 @@
name = "Embryonic Stasis"
icon_state = "netpod_stasis"
desc = "You feel like you're in a dream."

#undef BASE_HEAL
142 changes: 63 additions & 79 deletions code/modules/bitrunning/objects/netpod.dm
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,10 @@
disconnect_damage = BASE_DISCONNECT_DAMAGE
find_server()

RegisterSignals(src, list(
COMSIG_QDELETING,
COMSIG_MACHINERY_BROKEN,
COMSIG_MACHINERY_POWER_LOST,
),
PROC_REF(on_broken),
)
RegisterSignal(src, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
RegisterSignal(src, COMSIG_ATOM_TAKE_DAMAGE, PROC_REF(on_take_damage))
RegisterSignal(src, COMSIG_ATOM_TAKE_DAMAGE, PROC_REF(on_damage_taken))
RegisterSignal(src, COMSIG_MACHINERY_POWER_LOST, PROC_REF(on_power_loss))
RegisterSignals(src, list(COMSIG_QDELETING, COMSIG_MACHINERY_BROKEN),PROC_REF(on_broken))

register_context()
update_appearance()
Expand Down Expand Up @@ -89,7 +84,7 @@
if(!iscarbon(player))
return

if((HAS_TRAIT(player, TRAIT_UI_BLOCKED) && !player.resting) || !Adjacent(player) || !player.Adjacent(target) || !ISADVANCEDTOOLUSER(player) || !is_operational)
if((HAS_TRAIT(player, TRAIT_UI_BLOCKED) && !player.resting) || !Adjacent(player) || !ISADVANCEDTOOLUSER(player) || !is_operational)
return

close_machine(target)
Expand Down Expand Up @@ -142,9 +137,10 @@
open_machine()

/obj/machinery/netpod/open_machine(drop = TRUE, density_to_set = FALSE)
unprotect_and_signal()
playsound(src, 'sound/machines/tramopen.ogg', 60, TRUE, frequency = 65000)
flick("[base_icon_state]_opening", src)
SEND_SIGNAL(src, COMSIG_BITRUNNER_NETPOD_OPENED)
update_use_power(IDLE_POWER_USE)

return ..()

Expand All @@ -156,10 +152,6 @@
flick("[base_icon_state]_closing", src)
..()

if(!iscarbon(occupant))
open_machine()
return

enter_matrix()

/obj/machinery/netpod/default_pry_open(obj/item/crowbar, mob/living/pryer)
Expand All @@ -184,6 +176,7 @@

if(do_after(pryer, 15 SECONDS, src))
if(!state_open)
SEND_SIGNAL(src, COMSIG_BITRUNNER_SEVER_AVATAR)
open_machine()

return TRUE
Expand Down Expand Up @@ -232,17 +225,22 @@
if(isnull(our_target) || !our_observer.orbit(our_target))
return ..()

/// Puts the occupant in netpod stasis, basically short-circuiting environmental conditions
/obj/machinery/netpod/proc/add_healing(mob/living/target)
if(target != occupant)
return

target.AddComponent(/datum/component/netpod_healing, pod = src)
target.playsound_local(src, 'sound/effects/submerge.ogg', 20, vary = TRUE)
target.extinguish_mob()
update_use_power(ACTIVE_POWER_USE)

/// Disconnects the occupant after a certain time so they aren't just hibernating in netpod stasis. A balance change
/obj/machinery/netpod/proc/auto_disconnect()
if(isnull(occupant) || state_open || connected)
return

if(!iscarbon(occupant))
open_machine()
return

var/mob/living/carbon/player = occupant

var/mob/player = occupant
player.playsound_local(src, 'sound/effects/splash.ogg', 60, TRUE)
to_chat(player, span_notice("The machine disconnects itself and begins to drain."))
open_machine()
Expand All @@ -252,7 +250,7 @@
connected = FALSE

var/mob/living/mob_occupant = occupant
if(isnull(occupant) || !isliving(occupant) || mob_occupant.stat == DEAD)
if(isnull(occupant) || mob_occupant.stat == DEAD)
open_machine()
return

Expand All @@ -261,6 +259,10 @@
mob_occupant.set_temp_blindness(1 SECONDS)
mob_occupant.Paralyze(2 SECONDS)

if(!is_operational)
open_machine()
return

var/heal_time = 1
if(mob_occupant.health < mob_occupant.maxHealth)
heal_time = (mob_occupant.stat + 2) * 5
Expand Down Expand Up @@ -299,9 +301,8 @@
return

var/mob/living/carbon/current_avatar = avatar_ref?.resolve()
var/obj/structure/hololadder/wayout
if(isnull(current_avatar) || current_avatar.stat != CONSCIOUS) // We need a viable avatar
wayout = server.generate_hololadder()
var/obj/structure/hololadder/wayout = server.generate_hololadder()
if(isnull(wayout))
balloon_alert(neo, "out of bandwidth!")
return
Expand All @@ -310,7 +311,7 @@
server.stock_gear(current_avatar, neo, generated_domain)

neo.set_static_vision(3 SECONDS)
protect_occupant(occupant)
add_healing(occupant)
if(!do_after(neo, 2 SECONDS, src))
return

Expand Down Expand Up @@ -372,27 +373,50 @@
/obj/machinery/netpod/proc/on_broken(datum/source)
SIGNAL_HANDLER

if(!state_open)
open_machine()
if(isnull(occupant) || !connected)
return

if(occupant)
unprotect_and_signal()
SEND_SIGNAL(src, COMSIG_BITRUNNER_SEVER_AVATAR)

/// Checks the integrity, alerts occupants
/obj/machinery/netpod/proc/on_damage_taken(datum/source, damage_amount)
SIGNAL_HANDLER

if(isnull(occupant) || !connected)
return

var/total = max_integrity - damage_amount
var/integrity = (atom_integrity / total) * 100
if(integrity > 50)
return

SEND_SIGNAL(src, COMSIG_BITRUNNER_NETPOD_INTEGRITY)

/// Puts points on the current occupant's card account
/obj/machinery/netpod/proc/on_domain_complete(datum/source, atom/movable/crate, reward_points)
SIGNAL_HANDLER

if(isnull(occupant) || !connected || !iscarbon(occupant))
if(isnull(occupant) || !connected)
return

var/mob/living/carbon/player = occupant
var/mob/living/player = occupant

var/datum/bank_account/account = player.get_bank_account()
if(isnull(account))
return

account.bitrunning_points += reward_points * 100

/// The domain has been fully purged, so we should double check our avatar is deleted
/obj/machinery/netpod/proc/on_domain_scrubbed(datum/source)
SIGNAL_HANDLER

var/mob/avatar = avatar_ref?.resolve()
if(isnull(avatar))
return

QDEL_NULL(avatar)

/// User inspects the machine
/obj/machinery/netpod/proc/on_examine(datum/source, mob/examiner, list/examine_text)
SIGNAL_HANDLER
Expand All @@ -408,66 +432,26 @@
examine_text += span_notice("It is currently occupied by [occupant].")
examine_text += span_notice("It can be pried open with a crowbar, but its safety mechanisms will alert the occupant.")

/// The domain has been fully purged, so we should double check our avatar is deleted
/obj/machinery/netpod/proc/on_domain_scrubbed(datum/source)
/// Boots out anyone in the machine && opens it
/obj/machinery/netpod/proc/on_power_loss(datum/source)
SIGNAL_HANDLER

var/mob/living/current_avatar = avatar_ref?.resolve()
if(isnull(current_avatar))
if(state_open)
return

if(isnull(occupant) || !connected)
connected = FALSE
open_machine()
return

QDEL_NULL(current_avatar)
SEND_SIGNAL(src, COMSIG_BITRUNNER_SEVER_AVATAR)

/// When the server is upgraded, drops brain damage a little
/obj/machinery/netpod/proc/on_server_upgraded(datum/source, servo_rating)
SIGNAL_HANDLER

disconnect_damage = BASE_DISCONNECT_DAMAGE * (1 - servo_rating)

/// Checks the integrity, alerts occupants
/obj/machinery/netpod/proc/on_take_damage(datum/source, damage_amount)
SIGNAL_HANDLER

if(isnull(occupant))
return

var/total = max_integrity - damage_amount
var/integrity = (atom_integrity / total) * 100
if(integrity > 50)
return

SEND_SIGNAL(src, COMSIG_BITRUNNER_NETPOD_INTEGRITY)

/// Puts the occupant in netpod stasis, basically short-circuiting environmental conditions
/obj/machinery/netpod/proc/protect_occupant(mob/living/target)
if(target != occupant)
return

target.AddComponent(/datum/component/netpod_healing, \
brute_heal = 4, \
burn_heal = 4, \
toxin_heal = 4, \
clone_heal = 4, \
blood_heal = 4, \
)

target.playsound_local(src, 'sound/effects/submerge.ogg', 20, TRUE)
target.extinguish_mob()
update_use_power(ACTIVE_POWER_USE)

/// On unbuckle or break, make sure the occupant ref is null
/obj/machinery/netpod/proc/unprotect_and_signal()
unprotect_occupant(occupant)
SEND_SIGNAL(src, COMSIG_BITRUNNER_SEVER_AVATAR)

/// Removes the occupant from netpod stasis
/obj/machinery/netpod/proc/unprotect_occupant(mob/living/target)
var/datum/component/netpod_healing/healing_eff = target?.GetComponent(/datum/component/netpod_healing)
if(healing_eff)
qdel(healing_eff)

update_use_power(IDLE_POWER_USE)

/// Resolves a path to an outfit.
/obj/machinery/netpod/proc/resolve_outfit(text)
var/path = text2path(text)
Expand Down
3 changes: 2 additions & 1 deletion code/modules/bitrunning/server/obj_generation.dm
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@
if(domain_forbids_spells)
import_ban += "imported_abilities"
disk_ban += "powers"
if(import_ban)

if(length(import_ban))
to_chat(neo, span_warning("This domain forbids the use of [english_list(import_ban)], your disk [english_list(disk_ban)] will not be granted!"))

var/failed = FALSE
Expand Down

0 comments on commit 9c21af4

Please sign in to comment.