Random silliness: Quest's "invoke" in JS

Random I know.
This was an issue back with QuestJS, the one that tried to convert Quest 5.x games to javascript code. They had a problem that a function's parameters weren't known when it was created. Because Quest's invoke takes a script parameter, and a dictionary of parameters, and the parameter names come from the dictionary.

It randomly popped into my head how you could do this lately. So I present: a javascript function that messes with another javascript function.

function Quest_invoke (script, params) {
  eval("(" + script.toString().replace(/^\s*(function\s*.*?\()/, "$1"+Object.keys(params).join(",")) + ")").apply(null, Object.values(params));
}

function Quest_do (object, scriptname, params) {
  eval("(" + object[scriptname].toString().replace(/^\s*(function\s*.*?\()/, "$1"+Object.keys(params).join(",")) + ")").apply(object, Object.values(params));
}

This is probably useless now; but if someone wants to revive the idea of making a new engine to work with the old files it could be useful.


By default, you can't do eval due to the security settings in Quest 6.

https://github.com/ThePix/QuestJS/wiki/Code-guidelines#content-security-policy


Sorry. You can delete this post if you want to keep irrelevant stuff off the forum.

But if you want to do this without eval, you should be able to use some terrible voodoo code like:

function Quest_invoke (script, params) {
  var stash = Object.keys(params);
  stash.push(script.toString().replace(/^.*?\{(.*)\}.*?$/s, "$1"));
  stash.unshift(undefined);
  var modified_script = new (Function.prototype.bind.apply(Function, stash));
  modified_script.apply(null, Object.values(params));
}

(more proof that I can't let go of an unsolved problem even when it's years past being relevant)

For reference:

new (Function.prototype.bind.apply(SomeClassName, some_array));

is equivalent to:

new SomeClassName(some_array[1], some_array[2], some_array[3] …)

I'm using that with the Function constructor, because I have an array of parameter names (from Object.keys(params)). So I can then call the newly created function by using its apply method to supply an array of parameter values rather than the parameters individually.


Curses!

Uncaught EvalError: call to Function() blocked by CSP
    Quest_invoke debugger eval code:4
    <anonymous> debugger eval code:12
debugger eval code:4:25

I can't let go of an unsolved problem even when it's years past being relevant

Neither can I, good sir. Neither can I.

Unsolved problems haunt me.


I wasn't sure if the Function constructor would count as an eval or not; guess I'm out of luck there.


It was a valiant effort.

I would have used it, just to prove it could be done.


Log in to post a reply.

Support

Forums