edit global variable using Execute javascript action(SOLVED)

0 favourites
From the Asset Store
Globals 2.0
$3.99 USD
Globals 2.0 stores and group variables. You can also load and save data (variables) from/to JSON files.
  • Is it possible to change the value in the global variable using the execute JavaScript action? I'm trying to integrate fgl's sdk and I'm having issues with integrating their premium feature.

    Here's what I have tried so far in pseudo-code:

    global variable number premium = 0;

    Following this format-->Event>Action

    OnTouched premiumButton > Browser.Execute javascript "fgl.inApp.initiateUnlockFunction(function(){"&premium=1&"},function(){"&premium=2&"});"

    Problem:

    This doesn't seem to change the global variable in Construct2 when the function call is made. It does initially make the call and create the menu to accept or cancel it but once again it doesn't change the variable when the function is called. Is there another way to accomplish this?

    Such as declaring a variable within the execute javascript command?

  • Hey,

    it's really dirty what you're doing there! You can't access the global variable, cause it's stored somewhere in the runtime.

    What exactly you want to do?

  • You can still access global variables using the execute javascript command in construct2. I'm wondering how I can directly change the value of the global variable using the javascript browser command in the events.

  • maybe you'll find them here: this.runtime.get_all_globals

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • I appreciate the input. But I read that there's some compatibility issues with that command. It doesn't seem to work on all devices. I guess i'll find a workaround then.

  • I could be totally wrong, but couldn't you try to use a function to do this? like if you can call the function in execute JS you should be able to do this with the way C2 does it.

    Aka: you just set the variable with a function, but call it with the execute javascript command

  • Aphrodite

    Can the execute javascript command use system function expressions from C2? I tried creating a function called "p" which set's the sprite objects opacity to 100 when called. I also created a function called"q" which sets the objects opacity to 0.

    But when I tried doing

    Browser.Execute javascript "fgl.inApp.initiateUnlockFunction(function(){"&functon.call("p")&"},function(){""&functon.call("q")&"});"

    It doesn't work. I don't even think it can be used this way, can it?

  • I am having trouble understanding the:

    "fgl.inApp.initiateUnlockFunction(function(){"&premium=1&"},function(){"&premium=2&"});"

    {"&premium=1&"} is interrupting the string of the execute javascript I think, as well as {"&premium=2&"} so I am missing totally the purpose of this. What this {"&premium=1&"} and {"&premium=2&"} are supposed to do?

    If they are supposed to set the value, then you should do

    on function "p": set premium value to 1

    on function "q": set premium value to 1

    you might want to set return values too, but I don't know exactly so..

    also:

    Browser.Execute javascript "fgl.inApp.initiateUnlockFunction(function(){"&functon.call("p")&"},function(){""&functon.call("q")&"});"

    It is not functon.call but function.call (don't forget the "i"), maybe it was the error

    Browser.Execute javascript "fgl.inApp.initiateUnlockFunction(function(){"&function.call("p")&"},function(){""&function.call("q")&"});"

    EDIT: I think that won't work, since you are doing the function calls, they'll both be executed :/

  • Aphrodite

    "It is not functon.call but function.call (don't forget the "i")"

    I misspelled it in the forums by accident, I didn't actually misspell it in the C2 editor.

    This is the javascript code I'm trying to imitate using browser execute javascript (not including the comments):

    fgl.inApp.initiateUnlockFunction(

    function(){

    // The 'FULL VERSION!' text appears:

    this.updateMenu();

    },

    function(){

    // The unlock was canceled, the user didn't pay, or some other

    // failure happened. Let's just refresh the menu to be sure it's up

    // to date:

    this.updateMenu();

    }

    );

    Instead of this.updateMenu(), I would do a function call to a function in the C2 editor functon.call("q") or change the value of a global variable.

    If I could either one of those things then it would have worked out.

    This is the javascript code with no comments, it might be easier to read:

    fgl.inApp.initiateUnlockFunction(

    function(){this.updateMenu();},

    function(){this.updateMenu();}

    );

  • Changing the value of a global variables is way more complex than what you think.

    Global variables in construct2 aren't javascript variables, they are objects with, amongst other things, "name", "data", "initial" properties.

    They are indeed in the all_global_vars array of the c2runtime.

    But the big problem is that when you export your project, a lot of that stuff gets minified.

    Nonetheless, it seems there's enough to write something that can parse the runtime and find the objects which "look like" global variables and then narrow down the search on the name.

    Here is what you can put in the Browser Execute javascript:

    function getGlobalObject(name) {
        var runtime = document.getElementById('c2canvas').c2runtime;
        for (var p in runtime) {
            if(Object.prototype.hasOwnProperty.call(runtime,p)) {
                var prop = runtime[p];
                if(prop === undefined) continue;
                if(prop === null) continue;
                if(typeof prop !== 'object') continue;
                if(prop.length === undefined) continue;
    
                for(var i = 0; i < prop.length; i++) {
                    if(prop[i].parent !== undefined && 
                       prop[i].data !== undefined   && 
                       prop[i].sheet !== undefined  && 
                       prop[i].name !== undefined) {
                        // probably the global var array
                        if(prop[i].name === name) {
                            // that one!
                            return prop[i];
                        }
                    } else {
                        // no need to loop if not global var array
                        break;
                    }
                }
            }
        }
        return null;
    }
    
    function setGlobalVar(name,value) {
        var g = getGlobalObject(name);
        if(g === null) return;
        g.data = value;
    }
    
    function getGlobalVar(name) {
        var g = getGlobalObject(name);
        if(g === null) return 0;
        return g.data;
    }
    
    setGlobalVar('myGlobal',4); // here is where you set your global
    [/code:1ve38njy]
    This code gets the runtime from the canvas (assuming it has the id "c2canvas")
    Then go through all the properties looking for arrays (which are objects with a length property)
    And then loop through all the element of the array to find objects with parent, data, sheet and name properties.
    Those properties are hopefully not minified (at least for now) and it seems enough to narrow down the search
    Then just checking for the name property gives you the proper global variable object you can get/set.
    
    As a word of advice, don't do that everytick... I don't think it's super efficient. Also... You should probably make a plugin for that kind of stuff. Since the plugin code gets minified the same way, you get something more reliable.
  • Yann

    I appreciate the input Yann, it was in-depth. The reason I didn't want to make a plugin was mainly because I had all the other features in the sdk working without a plugin, so making a plugin just to run that one function is kinda over the top. I know other c2 users have started to make their own fgl plugin for the sdk (there's about 3 by now ) but it seems none of them have this properly working yet either.

    I appreciate that you put effort into actually explaining why its more or less not possible this way. I guess the method I was thinking of was rather inefficient. And for optimization issues I think I may avoid executing javascript from the browser object for this function.

    I have read some guides on making plugins and I may just release one, but as of right now I'm a bit busy with my first year of university. If I notice that fgl is unable to make there own and C2 users aren't able to get one working with all features, then I'll eventually make one. But this of course is when I can actually find some spare time.

  • You can create a var in JavaScript with for example execute js( 'this.premium=1337‘ ) and just set your global with an event with eval js( 'this.premium'). That will work with minifying as well. As a rule of thumb it's not reliable to access the runtime stuff unless you use the sdk with a plugin.

  • Would indeed be a simpler approach than my bloated unreliable example =)

  • I tried to use C2 programs, inserted using userscripts, inside a page I didn't host, to add functionality to a browser game. I had to trade some data between C2 and the webpage. I used a "notification system" to dialog between the two, meaning :

    • each time the JS needed to send data to C2, it would store a request (see below) in an array, using a function "sendNotification".
    • a request was a string with a C2 function name (function meaning the Function plugin), and arguments, separated with a "__".
    • each tick, C2 would execute a code "getNotification()" with execJS, and would be returned the string of the first waiting request, with a "this.lastRequest" evaluation like R0j0 explained. The request was then analysed and the correct function was called with the correct arguments in C2, handling the request (depending on type of request, like update life, ...)
    • the other way was quite simple, as you can just execJS the functions you want in the webpage from C2.

    This was for intensive exchanges, but the method can be used in other ways, including simple ones. (2 C2 games running on the same page, chatting with each other ?)

  • R0J0hound

    Much appreciated Rojo, this is what I was looking for. I'm gonna try it later this week.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)