[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:
SkyratBot
2022-03-17 16:18:08 -07:00
committed by GitHub
co-authored by Timberpoes
parent 2927438046
commit a7c86d598a
3 changed files with 72 additions and 68 deletions
+43 -19
View File
@@ -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;