danielyxie / bitburner

Bitburner Game
https://danielyxie.github.io/bitburner/
2.81k stars 768 forks source link

TERMINAL: Provide (unsupported) method for printing arbitrary rich content to terminal via React #4233

Closed Snarling closed 2 years ago

Snarling commented 2 years ago

A recent PR patched a common exploit that, among other things, allowed easy access to the Terminal internal object. This access to Terminal was the main way the player could print arbitrary rich content, via Terminal.printRaw.

This PR provides renewed access to the printRaw function through ns, as an undocumented function that is for use at a player's own risk. Because this function allows printing React content to the page, and React errors cause a recovery page, this is meant for advanced users only. Typechecking the input also would have been very difficult due to the broadness of the ReactNode type - so instead the input is assumed to be the right type (again, player's own risk).

As suggested, this has been moved to a global context (where React already resides) as window.tprintRaw.

TODO: Perhaps it should be hidden better, to make it more obvious this is not a "supported" feature. TODO is done, see other comment.

Other than adding tprintRaw, it's just some minor formatting changes:

  1. I removed the explicit return types from the Extra functions because ts already knows the return types implicitly. In some cases this meant a multiline wrapped function declaration could be moved to one line, which changed the indentation level of the entire wrapped function.
  2. Un-decapitalized Player, just to match how it is right now in most of the codebase. If we decapitalize, it should be everywhere.

Example usage:

/** @param {NS} ns */
export async function main(ns) {
  globalThis.tprintRaw(
    React.createElement("span",null,[
      "This ",
      React.createElement("i",null,"is "),
      React.createElement("b",null,"printRaw!!!")
    ])
  );
}

image

stalefishies commented 2 years ago

If we're doing advanced, undocumented stuff, would it perhaps be better to just make it global instead of being on NS? It's always been annoying to me to need an NS context to print stuff, since debugging scripts often means modifying functions to take ns just to get some output from them. There actually already is a globally-accessible print bundled in with the electron stuff, so I don't think it's too big a deal to add this globally.

(In fact, getting a global print function is the reason my own scripts get at the terminal object in the first place, so I can make a global print to avoid that debugging problem. So this PR wouldn't actually be a valid replacement for my Terminal-object-accessing use case unless it ends up being global.)

It also might be better named tprintRaw, for consistency with tprint vs print.

Snarling commented 2 years ago

Changed to global. I think I want to change the way this is accessed though so it's obvious it's unsupported and no one complains that they keep getting recovery screens when they misuse it.

Snarling commented 2 years ago

Updated with an extra required step before tprintRaw becomes exposed at global scope: must run ns.iKnowWhatImDoing() first.

Attempting to use tprintRaw before doing the above: image

After running iKnowWhatImDoing, same functionality as described in the main post.