mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-25 06:00:16 +01:00
[MIRROR] Brings DNA Console behaviour server-side to prevent href exploitation. [MDB IGNORE] (#12148)
* Brings DNA Console behaviour server-side to prevent href exploitation. (#65507) * Brings DNA Console behaviour server-side to prevent href exploitation. Co-authored-by: Timberpoes <silent_insomnia_pp@hotmail.co.uk>
This commit is contained in:
@@ -40,6 +40,13 @@
|
||||
#define GENETIC_DAMAGE_PULSE_UNIQUE_IDENTITY "ui"
|
||||
#define GENETIC_DAMAGE_PULSE_UNIQUE_FEATURES "uf"
|
||||
|
||||
/// Input from tgui interface. X the gene out.
|
||||
#define CLEAR_GENE 0
|
||||
/// Input from tgui interface. Progress to the next gene.
|
||||
#define NEXT_GENE 1
|
||||
/// Input from tgui interface. Progress to previous gene.
|
||||
#define PREV_GENE 2
|
||||
|
||||
/obj/machinery/computer/scan_consolenew
|
||||
name = "DNA Console"
|
||||
desc = "Scan DNA."
|
||||
@@ -372,6 +379,9 @@
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/scan_consolenew/ui_act(action, list/params)
|
||||
var/static/list/gene_letters = list("A", "T", "C", "G");
|
||||
var/static/gene_letter_count = length(gene_letters)
|
||||
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
@@ -474,9 +484,9 @@
|
||||
// ---------------------------------------------------------------------- //
|
||||
// params["alias"] - Alias of a mutation. The alias is the "hidden" name of
|
||||
// the mutation, for example "Mutation 5" or "Mutation 33"
|
||||
// params["gene"] - The letter of the new gene
|
||||
// params["pulseAction"] - The action to perform on this gene.
|
||||
// params["pos"] - The BYOND index of the letter in the gene sequence to be
|
||||
// changed. Expects a text string from TGUI and will convert to a number
|
||||
// changed.
|
||||
if("pulse_gene")
|
||||
// GUARD CHECK - Can we genetically modify the occupant? Includes scanner
|
||||
// operational guard checks.
|
||||
@@ -505,29 +515,39 @@
|
||||
// Resolve BYOND path to genome sequence of scanner occupant
|
||||
var/sequence = GET_GENE_STRING(path, scanner_occupant.dna)
|
||||
|
||||
var/newgene = params["gene"]
|
||||
if(length(newgene) > 1) // Oh come on
|
||||
return // fuck off
|
||||
var/newgene
|
||||
var/pulse_action = params["pulseAction"]
|
||||
var/genepos = text2num(params["pos"])
|
||||
|
||||
// If the new gene is J, this means we're dealing with a JOKER
|
||||
// GUARD CHECK - Is JOKER actually ready?
|
||||
if((newgene == "J") && (jokerready < world.time))
|
||||
var/truegenes = GET_SEQUENCE(path)
|
||||
newgene = truegenes[genepos]
|
||||
jokerready = world.time + JOKER_TIMEOUT - (JOKER_UPGRADE * (connected_scanner.precision_coeff-1))
|
||||
if(genepos > length(sequence))
|
||||
CRASH("Unexpected input for \[\"pos\"\] param sent to [type] tgui interface. Consult tgui logs for error.")
|
||||
|
||||
// If the gene is an X, we want to update the default genes with the new
|
||||
// X to allow highlighting logic to work on the tgui interface.
|
||||
if(newgene == "X")
|
||||
var/defaultseq = scanner_occupant.dna.default_mutation_genes[path]
|
||||
defaultseq = copytext(defaultseq, 1, genepos) + newgene + copytext(defaultseq, genepos + 1)
|
||||
scanner_occupant.dna.default_mutation_genes[path] = defaultseq
|
||||
switch(pulse_action)
|
||||
// X out the gene.
|
||||
if(CLEAR_GENE)
|
||||
newgene = "X"
|
||||
var/defaultseq = scanner_occupant.dna.default_mutation_genes[path]
|
||||
scanner_occupant.dna.default_mutation_genes[path] = copytext(defaultseq, 1, genepos) + "X" + copytext(defaultseq, genepos + 1)
|
||||
// Either try to apply a joker if selected in the interface, or iterate the next gene.
|
||||
if(NEXT_GENE)
|
||||
if((tgui_view_state["jokerActive"]) && (jokerready < world.time))
|
||||
var/truegenes = GET_SEQUENCE(path)
|
||||
newgene = truegenes[genepos]
|
||||
jokerready = world.time + JOKER_TIMEOUT - (JOKER_UPGRADE * (connected_scanner.precision_coeff-1))
|
||||
else
|
||||
var/current_letter = gene_letters.Find(sequence[genepos])
|
||||
newgene = (current_letter == gene_letter_count) ? gene_letters[1] : gene_letters[current_letter + 1]
|
||||
// Iterate previous gene.
|
||||
if(PREV_GENE)
|
||||
var/current_letter = gene_letters.Find(sequence[genepos]) || 1
|
||||
newgene = (current_letter == 1) ? gene_letters[gene_letter_count] : gene_letters[current_letter - 1]
|
||||
// Unknown input.
|
||||
else
|
||||
CRASH("Unexpected input for \[\"pulseAction\"\] param sent to [type] tgui interface. Consult tgui logs for error.")
|
||||
|
||||
// Copy genome to scanner occupant and do some basic mutation checks as
|
||||
// we've increased the occupant genetic damage
|
||||
sequence = copytext(sequence, 1, genepos) + newgene + copytext(sequence, genepos + 1)
|
||||
scanner_occupant.dna.mutation_index[path] = sequence
|
||||
scanner_occupant.dna.mutation_index[path] = copytext(sequence, 1, genepos) + newgene + copytext(sequence, genepos + 1)
|
||||
scanner_occupant.AddComponent(/datum/component/genetic_damage, GENETIC_DAMAGE_STRENGTH_MULTIPLIER/connected_scanner.damage_coeff)
|
||||
scanner_occupant.domutcheck()
|
||||
|
||||
@@ -2257,3 +2277,7 @@
|
||||
#undef SEARCH_STORED
|
||||
#undef SEARCH_DISKETTE
|
||||
#undef SEARCH_ADV_INJ
|
||||
|
||||
#undef CLEAR_GENE
|
||||
#undef NEXT_GENE
|
||||
#undef PREV_GENE
|
||||
|
||||
@@ -3,7 +3,7 @@ import { resolveAsset } from '../../assets';
|
||||
import { useBackend } from '../../backend';
|
||||
import { Box, Button, Section, Stack } from '../../components';
|
||||
import { MutationInfo } from './MutationInfo';
|
||||
import { GENES, GENE_COLORS, MUT_NORMAL, SUBJECT_DEAD, SUBJECT_TRANSFORMING } from './constants';
|
||||
import { CLEAR_GENE, GENE_COLORS, MUT_NORMAL, NEXT_GENE, PREV_GENE, SUBJECT_DEAD, SUBJECT_TRANSFORMING } from './constants';
|
||||
|
||||
const GenomeImage = (props, context) => {
|
||||
const { url, selected, onClick } = props;
|
||||
@@ -26,9 +26,8 @@ const GenomeImage = (props, context) => {
|
||||
};
|
||||
|
||||
const GeneCycler = (props, context) => {
|
||||
const { gene, onChange, disabled, ...rest } = props;
|
||||
const length = GENES.length;
|
||||
const index = GENES.indexOf(gene);
|
||||
const { act } = useBackend(context);
|
||||
const { alias, gene, index, disabled, ...rest } = props;
|
||||
const color = (disabled && GENE_COLORS['X']) || GENE_COLORS[gene];
|
||||
return (
|
||||
<Button
|
||||
@@ -36,27 +35,31 @@ const GeneCycler = (props, context) => {
|
||||
color={color}
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
if (!onChange) {
|
||||
if (e.ctrlKey) {
|
||||
act('pulse_gene', {
|
||||
pos: index + 1,
|
||||
pulseAction: CLEAR_GENE,
|
||||
alias: alias,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (index === -1) {
|
||||
onChange(e, GENES[0]);
|
||||
return;
|
||||
}
|
||||
const nextGene = GENES[(index + 1) % length];
|
||||
onChange(e, nextGene);
|
||||
|
||||
act('pulse_gene', {
|
||||
pos: index + 1,
|
||||
pulseAction: NEXT_GENE,
|
||||
alias: alias,
|
||||
});
|
||||
|
||||
return;
|
||||
}}
|
||||
oncontextmenu={e => {
|
||||
e.preventDefault();
|
||||
if (!onChange) {
|
||||
return;
|
||||
}
|
||||
if (index === -1) {
|
||||
onChange(e, GENES[length - 1]);
|
||||
return;
|
||||
}
|
||||
const prevGene = GENES[(index - 1 + length) % length];
|
||||
onChange(e, prevGene);
|
||||
|
||||
act('pulse_gene', {
|
||||
pos: index + 1,
|
||||
pulseAction: PREV_GENE,
|
||||
alias: alias,
|
||||
});
|
||||
}}>
|
||||
{gene}
|
||||
</Button>
|
||||
@@ -65,8 +68,6 @@ const GeneCycler = (props, context) => {
|
||||
|
||||
const GenomeSequencer = (props, context) => {
|
||||
const { mutation } = props;
|
||||
const { data, act } = useBackend(context);
|
||||
const { jokerActive } = data.view;
|
||||
if (!mutation) {
|
||||
return (
|
||||
<Box color="average">
|
||||
@@ -101,32 +102,8 @@ const GenomeSequencer = (props, context) => {
|
||||
: false
|
||||
}
|
||||
gene={gene}
|
||||
onChange={(e, nextGene) => {
|
||||
if (e.ctrlKey) {
|
||||
act('pulse_gene', {
|
||||
pos: i + 1,
|
||||
gene: 'X',
|
||||
alias: mutation.Alias,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (jokerActive) {
|
||||
act('pulse_gene', {
|
||||
pos: i + 1,
|
||||
gene: 'J',
|
||||
alias: mutation.Alias,
|
||||
});
|
||||
act('set_view', {
|
||||
jokerActive: '',
|
||||
});
|
||||
return;
|
||||
}
|
||||
act('pulse_gene', {
|
||||
pos: i + 1,
|
||||
gene: nextGene,
|
||||
alias: mutation.Alias,
|
||||
});
|
||||
}} />
|
||||
index={i}
|
||||
alias={mutation.Alias} />
|
||||
);
|
||||
buttons.push(button);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ export const CONSOLE_MODE_FEATURES = 'features';
|
||||
export const CONSOLE_MODE_SEQUENCER = 'sequencer';
|
||||
export const CONSOLE_MODE_STORAGE = 'storage';
|
||||
|
||||
export const GENES = ['A', 'T', 'C', 'G'];
|
||||
export const GENE_COLORS = {
|
||||
A: 'green',
|
||||
T: 'green',
|
||||
@@ -47,3 +46,7 @@ export const MUT_COLORS = {
|
||||
[NEGATIVE]: 'bad',
|
||||
[MINOR_NEGATIVE]: 'average',
|
||||
};
|
||||
|
||||
export const CLEAR_GENE = 0;
|
||||
export const NEXT_GENE = 1;
|
||||
export const PREV_GENE = 2;
|
||||
|
||||
Reference in New Issue
Block a user