pulviscriptor / agario-client

Node.js agar.io client implementation
MIT License
80 stars 43 forks source link

Facebook Broken with Agar.io Update #42

Closed Sonicmaster13 closed 8 years ago

Sonicmaster13 commented 8 years ago

The Facebook key system has been broken due to the new update of Agar.io. The Facebook login system, i think, has changed, and the way the client is using the Facebook keys no longer works.

pulviscriptor commented 8 years ago

For anybody who waiting fix, i'm working on it, but new auth system got much more complicated than it was. For every new connection new auth key requested. I do not know when i will fix it, and will i be able at all.

Sonicmaster13 commented 8 years ago

If this helps, the extension Agario Powerups seems to be working with facebook, even after the update. You could look at that code for help.

lukemagdalin commented 8 years ago

agar.io powerups by even kara does not work after a while and i wanted 100 bots on my facebook

Sonicmaster13 commented 8 years ago

The Eren Kara one is outdated to that's why it does not work i mean the newest one by the real creator.

pulviscriptor commented 8 years ago

Okay, i need help. I do not have experience with websites development and agar uses some "facebook sdk" which i never used and i need help with using it in Node.js There is some window.fbAsyncInit which SDK calls and

window.FB.init({
    appId: A.fb_app_id,
    cookie: !0,
    xfbml: !0,
    status: !0,
    version: "v2.2"
});

inside it. While this voodoo magic happens, SDK receives data with variables

_FB_f3a372f6ce2ef5cb=...
domain=agar.io
origin=http%3A%2F%2Fagar.io%2Ff3a372f6ce2ef5
relation=parent
code=...
signed_request=...
access_token=CAAJoMBwWJiMBAKU095...
expires_in=6298
base_domain=agar.io
https=1

Who have experience with this should understand this list. And what i need is that access_token to authorize client on agar server. I found some https://www.npmjs.com/package/fb but its uses some https://www.npmjs.com/package/passport and that uses something other and i have no idea what is happening and how to make it work. How to get that access_token in Node.js?

Sonicmaster13 commented 8 years ago

One thing that may help is that the Opcode for Facebook login changed from 81 to 82.

gthgame commented 8 years ago

Any news pulviscriptor ?

pulviscriptor commented 8 years ago

gthgame, No news at the moment.

gthgame commented 8 years ago

ok pulviscriptor i hope to see an update soon if you find a fix , Good luck man ...

Endromede commented 8 years ago

i think is not possible without "login dialog". when the user is connected. it's possible to have a accessToken with this url (https://facebook.com/dialog/oauth?client_id=677505792353827&redirect_uri=https://agar.io&scope=public_profile,%20email&response_type=token). He return the token in url but need connection before.

Look here: https://developers.facebook.com/docs/facebook-login/access-tokens

all in npm is for the developper of application and need app_secret key

Sonicmaster13 commented 8 years ago
    if(this.facebook_key) {
        buf = new Buffer(1 + this.facebook_key.length);
        buf.writeUInt8(81, 0);
        for (i=1;i<=this.facebook_key.length;++i) {
            buf.writeUInt8(this.facebook_key.charCodeAt(i-1), i);
        }
        this.send(buf);
    }

    this.emit('connected');
},

NEEDS to be changed to

    if(this.facebook_key) {
        buf = new Buffer(1 + this.facebook_key.length);
        buf.writeUInt8(82, 0);     // <------ the opcode changed from 81 to 82 in the update
        for (i=1;i<=this.facebook_key.length;++i) {
            buf.writeUInt8(this.facebook_key.charCodeAt(i-1), i);
        }
        this.send(buf);
    }

    this.emit('connected');
},

and this:

    '81': function(client, packet) {
        var level       = packet.readUInt32LE();
        var curernt_exp = packet.readUInt32LE();
        var need_exp    = packet.readUInt32LE();

        if(client.debug >= 2)
            client.log('experience update: ' + [level, curernt_exp, need_exp].join(','));

        client.emit('experienceUpdate', level, curernt_exp, need_exp);
    },

MUST be changed to

    '82': function(client, packet) {   // <------ changed opcode again
        var level       = packet.readUInt32LE();
        var curernt_exp = packet.readUInt32LE();
        var need_exp    = packet.readUInt32LE();

        if(client.debug >= 2)
            client.log('experience update: ' + [level, curernt_exp, need_exp].join(','));

        client.emit('experienceUpdate', level, curernt_exp, need_exp);
    },

this is not all but this is one minor change

pulviscriptor commented 8 years ago

Endromede, thank you very much, i will look into that.

Sonicmaster13, also you need to change buffer size to +1 since there is ID of auth provider (google/facebook), write that provider to second byte and move all token bytes to one to right. But this does not helps access_token requesting.

The problem is that previously player FB key was static and was not changing every time you update page like it does now. And i can't request new tokens from node.js, and i can't say how long these tokens will work if you will not generate them for every new connection, like original client does. And even more, looks like player experience/level is now requested through some new WSS server that have his own protocol. So i need to do something with that too if it is working like that now. I will test token, if it will live more than 8 hours, i will post script to request tokens that i made while experimenting. lets hope that will work. Now i go sleep to test token later.

pulviscriptor commented 8 years ago

By the way here is modified part of facebook key send if anybody needs it. You need set key to token. But again, i do not know for how long tokens will work without re-requesting them so this is untested solution.

        if(this.facebook_key) {
            buf = new Buffer(2 + this.facebook_key.length);
            buf.writeUInt8(82, 0);
            buf.writeUInt8(1, 1);
            for (i=1;i<=this.facebook_key.length;++i) {
                buf.writeUInt8(this.facebook_key.charCodeAt(i-1), i+1);
            }
            this.send(buf);
        }

For google replace buf.writeUInt8(1, 1); to buf.writeUInt8(2, 1);

Sonicmaster13 commented 8 years ago

I can try to help. I have been staring at agario's client code for about 2 hours now so i'm getting to understand it better.

Endromede commented 8 years ago

pulviscriptor, the token is valid only 1hour .... that's the problem. go on agar.io site, in console write FB.getAccessToken() and test here:https://developers.facebook.com/tools/debug/

edit: and the token is invalid if you disconnect of facebook account. Close the browser without logout is nothing. If you generate many access token, the validity is from the first token generate on this session and all token is invalid in same time.

pulviscriptor commented 8 years ago

the token is valid only 1hour

My idea was that agar itself disables tokens when you request them on main page. So my standalone script in that case would work. But now i see that this is facebook disables key. Thanks for that link! So... All my ideas that i made has failed.

Endromede commented 8 years ago

oh. before needed 1 token by bot ( client ) in same map with same account. Now 1 token for all bot in same map with same account work ! Ok need change all hour but only one needed. i had created a generator of token ( client side) but is useless.

the token is disable when you logout and after the "cycle" is finish. When you generate the first token a setinterval for remove token is launch. ( the time is recorded in secondes in "expires_in" ) test with that (https://facebook.com/dialog/oauth?client_id=677505792353827&redirect_uri=https://agar.io&scope=public_profile,%20email&response_type=token) launch in browser url and look url.

ps: unknow if the timer is reset to zero when you logout or if continue and remove token after x secondes same if not token is generated because it's strange never same time when i logout/login and generate token. ok now. the only solution( in node) is to connect in facebook, set the "email" and "pass".but unknow if possible to record the session in node ( cookie, a "localStorage", ... )

pulviscriptor commented 8 years ago

Good news here. Endromede contacted me and with his help now we have working token requester. Is uses cookies from domain "facebook.com" so i need to see if they will work 24 hours later or they will expire like tokens. I will post results here some time later.

pulviscriptor commented 8 years ago

I updated package. Please check if it works for you. My test show that everything is fine, but i could forget something. If anybody have problems with new update, report them please.

Sonicmaster13 commented 8 years ago

Ok. Does this mean that i can use the same token for many "bots" in the same map?

pulviscriptor commented 8 years ago

Sonicmaster13, i do not know. It depends on agar's server-side code.