Announcement

Collapse
No announcement yet.

Facebook Progress...

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Facebook Progress...

    Hi folks,

    I thought I'd share some work in progress code for facebook integration.

    I've tried Epic's suggested approach described here http://udn.epicgames.com/Three/FacebookIntegration.html and present in the CloudGame but I have resulted to creating something a bit different as it left me with the following problems:-

    1) The authorization process doesn't appear to work for me using builds from August 2011 -> Jan 2012. The game loads the Facebook application and never returns to the UDK app.

    2) The game crashes upon restarting the level. From what I can figure the clear delegate stuff isn't happening and some kind of memory leak maybe happening. I posted a possible bug on the Twitter process covering a similar issue.

    Anyhow I have it so that I can authorize my app, post to my wall, restart/ change level but then if I run the function to post it after a level change the game crashes... So not perfect perhaps I'm doing something stupid or the memory leak is still occuring.

    Here’s the code, I worked out the authorization dialogue using the Facebook Developer Page. I guess this is an alternative method compared to using the +Permissions option in the Engine.ini I have no idea if it is correct or advisable.

    Any suggestions / ideas would be appreciated

    All the best

    Greg

    Code:
    class CloudPC2 extends SimplePC;
    
    var FacebookIntegration Facebook;
    var bool facebookgregauthorized;
    
    
    simulated function PostBeginPlay()
    {
    	super.PostBeginPlay();
    
    	Facebook = class'PlatformInterfaceBase'.static.GetFacebookIntegration();
    }
    
    // Cleanup              Originally this had clear delegate lines in but it didn't seem to be working as any time I have the add and clear delegate lines in the game crashes upon restart level. 
    event Destroyed()
    {
    	super.Destroyed();
    	facebookgregauthorized = false;
    	facebook.disconnect();
    }
    
    
    // this function works but as soon as you restart the level it causes the game to crash if you execute it... not sure why yet. I'm presumming the dialogue method leaves a delegate that needs clearing, but the attempts I've tried in the paste in the destroy event does not seem to get rid of anything.
    exec function postfacebook()
    {
    local array<string>Params;
    local array<string>Params2;
    
    	//if (!Facebook.IsAuthorized()) This is not playing nice so I  made my own temporary bool until I figure out why Epic's example is not working
    	if (facebookgregauthorized == false)
    	{
    	Params.AddItem("scope"); Params.AddItem("email,publish_stream,publish_actions,read_stream");
    	Params.AddItem("client_id"); Params.AddItem("PUT YOUR FACEBOOK APPID HERE, DO NOT INCLUDE THE FB");
    	Params.AddItem("redirect_uri"); Params.AddItem("http://www.google.com");
    	Params.AddItem("response_type"); Params.AddItem("token");
    	Facebook.FacebookDialog("oauth", Params);	
    	facebookgregauthorized = true;
    	}
    	else
    	{
    	// post to wall this is just the epic example I believe
    	Params2.AddItem("message"); Params2.AddItem("Shouldn't see this");
    	Params2.AddItem("link"); Params2.AddItem("www.google.com");
    	Params2.AddItem("picture"); Params2.AddItem("http://yourkidsartsucks.com/wp-content/uploads/2011/10/Funny_Art_223.jpg");
    	Params2.AddItem("name"); Params2.AddItem("Yes, hotness");
    	Params2.AddItem("caption"); Params2.AddItem("This is an post");
    	Params2.AddItem("description"); Params2.AddItem("I'm playing with posting to wall from UE3. Enjoy this mightily.");
    	Facebook.FacebookDialog("feed", Params2);	
    	}
    }

    You'll know if you get any of the above working as it'll look like this ....

    Attached Files

    #2
    Hi Showster, I started my facebook integration two days ago, and I did the same as you using the Facebook.FacebookDialog with the feed parameter, I'm able to post something in the wall but as soon as i change to another map and go back to the one which has the facebook integration it crashes, i was thinking too that it is a bug about not clearing some of the delegates.

    I also tried the example in the UDN documentation and it doesn't work.

    Is it possible to post in a wall, without the Dialog? like to post something automaticaly without the user's permission, I mean the user has already given the permission of the "publish_stream" so the app should be able to post without the dialog.

    The authorization process does works fine for me, it opens the Facebook app asking for the permissions and then goes back to the game.

    Comment


      #3
      Ah cool would you mind sharing your authorization code (if its different to epic's tut)? I've tested the cloud game on January 2012 release on iOS 5 iPad2 and iPod.

      Its sad to hear your having the same crashes I get the same with Twitter and other things, it's odd because this implementation works on Infinity Blade and other full engine versions.

      All the best

      Greg

      Comment


        #4
        Here's my code, i'm doing it in my main menu's MobileMenuScene, i just deleted what wasn't important in here,

        I'm using the January 2012 release by the way:


        Code:
        class BWMainMenuUI extends MobileMenuScene;
        
        var FacebookIntegration Facebook;
        var bool bIsFBAuthenticating;
        
        function Opened(string Mode) 
        {
        	FacebookIntegrate();
        }
        
        function OnTouch(MobileMenuObject Sender, ETouchType EventType, float TouchX, float TouchY)
        {
        
        .
        .
        .
        
        
        	if(Sender.Tag ~= "FBButton" && EventType==Touch_Ended && Sender.bIsTouched)
        	{
        		if (!Facebook.IsAuthorized())
        		{
        		  if (Facebook.Authorize() == true)
        		  {
        			 bIsFBAuthenticating = true;
        		  }
        		  return;
        		}
        
        	}
        
        .
        .
        .
        
        }
        
        
        
        function FacebookIntegrate()
        {
        	if(Facebook==none)
        		Facebook = class'PlatformInterfaceBase'.static.GetFacebookIntegration();
        
        	Facebook.AddDelegate(FID_AuthorizationComplete, OnFBAuthComplete);
        	Facebook.AddDelegate(FID_FacebookRequestComplete, OnFBRequestComplete);
        	Facebook.AddDelegate(FID_WebRequestComplete, OnWebRequestComplete);
        }
        
        function OnFBAuthComplete(const out PlatformInterfaceDelegateResult Result)
        {
        	MobileMenuLabel(FindMenuObject("Status")).Caption = "Facebook Auth Complete:"$Result.bSuccessful;
        	bIsFBAuthenticating = false;
        }
        
        function OnFBRequestComplete(const out PlatformInterfaceDelegateResult Result)
        {
        }
        
        function OnWebRequestComplete(const out PlatformInterfaceDelegateResult Result)
        {
        }
        
        .
        .
        .

        So when my MobileMenuScene opens, it creates the Facebook object and adds the delegates, so i guess that's where the crash happens 'cause the authorization only happens if i click a button I set in the scene.

        Is there a way to know if a delegate is already added?
        I can't think any other reason why would it crash.

        Comment


          #5
          Question, Is it crashing if you test it in PC? with the mobile previewer?

          'cause i just run the game in PC with the mobile previewer and did the same thing, went to another map, and then went back to the main menu and it crashed in PC too, and the weird thing is that look what it logged:

          [0009.85] Critical: appError called: Failed to find function AddDelegate in RB_BodyInstance BWEnemies.SmallEnemy_Physics:PhysicsAssetInstance_ 20.RB_BodyInstance_668
          [0009.85] Critical: Windows GetLastError: No se puede crear un archivo que ya existe. (183)
          [0013.48] Log: === Critical error: ===
          Failed to find function AddDelegate in RB_BodyInstance BWEnemies.SmallEnemy_Physics:PhysicsAssetInstance_ 20.RB_BodyInstance_668

          Address = 0x75b9b9bc (filename not found) [in C:\Windows\syswow64\KERNELBASE.dll]
          Address = 0x15033b1 (filename not found) [in D:\UDK\UDK-2012-01\Binaries\Win32\UDK.exe]
          Address = 0x6c0069 (filename not found)
          Address = 0x640065 (filename not found)
          Address = 0x740020 (filename not found)
          Address = 0x20006f (filename not found) [in D:\UDK\UDK-2012-01\Binaries\Win32\wxmsw28u_aui_vc_custom.dll]
          Address = 0x690066 (filename not found)
          Address = 0x64006e (filename not found)
          Address = 0x146f98d (filename not found) [in D:\UDK\UDK-2012-01\Binaries\Win32\UDK.exe]
          Address = 0x71d10000 (filename not found) [in C:\Windows\System32\msxml6.dll]
          Address = 0xfbc00149 (filename not found)
          Address = 0x79e10541 (filename not found)
          Address = 0xd1e00150 (filename not found)
          Address = 0x90e32189 (filename not found)
          Address = 0xd1e04821 (filename not found)
          Address = 0xd1e04821 (filename not found)
          and i don't know why the hell is saying this:

          Failed to find function AddDelegate in RB_BodyInstance BWEnemies.SmallEnemy_Physics:PhysicsAssetInstance_ 20.RB_BodyInstance_668

          when my main menu map is empty

          Comment


            #6
            I tried using the code and mine has a similar thing, It doesn't appear to know what to do with the delegate at all...

            Code:
            [0016.17] ScriptLog: CloudGame2::PostLogin BWMainMenuUI
            [0016.17] Critical: appError called: Failed to find function AddDelegate in ExponentialHeightFogComponent UEDP****itled_2.TheWorld:PersistentLevel.ExponentialHeightFog_0.ExponentialHeightFogComponent_0
            [0016.17] Critical: Windows GetLastError: The operation completed successfully. (0)
            [0032.96] Log: === Critical error: ===
            Failed to find function AddDelegate in ExponentialHeightFogComponent UEDP****itled_2.TheWorld:PersistentLevel.ExponentialHeightFog_0.ExponentialHeightFogComponent_0
            
            Address = 0x76a5b9bc (filename not found) [in C:\Windows\syswow64\KERNELBASE.dll]
            Address = 0x15533b1  (filename not found) [in c:\udk\udk-2012-01\binaries\win32\udk.exe]
            Address = 0x6c0069   (filename not found) 
            Address = 0x640065   (filename not found) 
            Address = 0x740020   (filename not found) 
            Address = 0x20006f   (filename not found) 
            Address = 0x690066   (filename not found) 
            Address = 0x64006e   (filename not found) 
            Address = 0x660020   (filename not found)

            Comment


              #7
              wow yeah it looks like it's just taking any random thing in memory and crashes...

              So it's probably a bug?, who could confirm this?

              Comment


                #8
                I haven't added facebook to my game yet, but I did In App Purchases. When using the code provided on the cloudgame to set microtransactions to work, it crashes as well when switching into another map.

                I tracked the bug down, and found that there is a problem with the singletons provided. So that if you call this function

                MicroTrans = class'PlatformInterfaceBase'.static.GetMicroTransa ctionInterface();

                you get the microtrans singleton that should remain the same during the entire game, however if you close the map and open any other map and request for that singleton again, it crashes later on.

                To solve the issue I implemented my own GameEngine class and stored a reference into that singleton. As the GameEngine class is not destroyed when the maps gets switched then I don't have to ask for that singleton again and therefore the game no longer crashes when switching maps.

                I haven't tested facebook integration but I think the problem maybe resolved in a similar way.

                Hope it helps.

                Comment


                  #9
                  Oh that sounds very reasonable login, thanks for that tip, could you tell me how do I implement the GameEngine class? I mean where would I define it? I guess it's in some of the .ini files. If it does, doesn't give you any other problem when setting a different GameEngine class?

                  Comment


                    #10
                    That appears to have worked a treat Login!!!! I couldn't figure the GameEngine.uc way, so I used GameViewportClient and sub classed from that which works the same way as its not changed on level loaded. A note for anyone who wants to use this, you'll have to put your GameViewportClients name into all the inis and I had to add the code package to the Engine.StartupPackages section.

                    Code:
                    class CloudGameViewportClient extends GameViewportClient;
                    /** Facebook Setup */
                    var FacebookIntegration Facebook;
                    
                    var bool bIsFBAuthenticating;
                    function SetupFacebook()
                    {
                    	// added facebook junk
                    	Facebook = class'PlatformInterfaceBase'.static.GetFacebookIntegration();
                    	Facebook.AddDelegate(FID_AuthorizationComplete, OnFBAuthComplete);
                    	Facebook.AddDelegate(FID_FacebookRequestComplete, OnFBRequestComplete);
                    	Facebook.AddDelegate(FID_WebRequestComplete, OnWebRequestComplete);
                    }
                    
                    function OnFBAuthComplete(const out PlatformInterfaceDelegateResult Result)
                    {
                    `log("facebook auth'd"$Result.bSuccessful);
                    bIsFBAuthenticating = false;
                    }
                    
                    function OnFBRequestComplete(const out PlatformInterfaceDelegateResult Result)
                    {
                    }
                    
                    function OnWebRequestComplete(const out PlatformInterfaceDelegateResult Result)
                    {
                    }

                    I linked the gameviewport stuff in the setupzones function on the player controller just because really... Again not sure if its a good idea but it works I've got some redundant code for authorisation that needs removing. I use the PostFacebook function via the console at the moment to post data on walls, it only works if I remove Epic's default authorisation code.

                    Code:
                    class CloudPC2 extends SimplePC;
                    
                    var bool facebookgregauthorized;
                    var CloudGameViewportClient GVC;
                    var bool bIsFBAuthenticating;
                    
                    simulated function PostBeginPlay()
                    {
                    	super.PostBeginPlay();
                    }
                    
                    /**  */   
                    function SetupZones()
                    {
                    	super.SetupZones();
                    	GVC = CloudGameViewportClient(LocalPlayer(Player).ViewportClient);
                    	GVC.SetupFacebook();
                    }
                    
                    exec function postfacebook()
                    {
                    	local array<string>Params;
                    	local array<string>Params2;
                    
                    	//if (!GVC.Facebook.IsAuthorized())
                    	if (!GVC.Facebook.IsAuthorized())
                    	//if (facebookgregauthorized == false)
                    	{
                    	GVC.Facebook.Authorize();
                    	if (facebookgregauthorized == true)
                    	{
                    	Params.AddItem("scope"); Params.AddItem("email,publish_stream,publish_actions,read_stream");
                    	Params.AddItem("client_id"); Params.AddItem("203395029739848");
                    	Params.AddItem("redirect_uri"); Params.AddItem("http://www.google.com");
                    	Params.AddItem("response_type"); Params.AddItem("token");
                    	GVC.Facebook.FacebookDialog("oauth", Params);	
                    	//facebookgregauthorized = true;
                    	}
                    	}
                    	else
                    	{
                    	// post to wall
                    	Params2.AddItem("message"); Params2.AddItem("Shouldn't see this");
                    	Params2.AddItem("link"); Params2.AddItem("www.google.com");
                    	Params2.AddItem("picture"); Params2.AddItem("http://yourkidsartsucks.com/wp-content/uploads/2011/10/Funny_Art_223.jpg");
                    	Params2.AddItem("name"); Params2.AddItem("Yes, hotness");
                    	Params2.AddItem("caption"); Params2.AddItem("This is an post");
                    	Params2.AddItem("description"); Params2.AddItem("I'm playing with posting to wall from UE3. Enjoy this mightily.");
                    	Params2.AddItem("to"); Params2.AddItem(GVC.Facebook.FriendsList[2].Id);
                    	GVC.Facebook.FacebookDialog("feed", Params2);	
                    	}
                    }

                    I still can't get it to authorize properly can do it manually but I'd love for it to work nicely like your experience Juan. I wander if its becuause of my .plist or something. I've modified the file located C:\UDK\UDK-2012-01\UDKGame\Build\iPhone\UDKGameOverrides.plist

                    Heres mine

                    Code:
                    <?xml version="1.0" encoding="UTF-8"?>
                    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
                    <plist version="1.0">
                    	<dict>
                    		<key>UIFileSharingEnabled</key>
                    		<true />
                    		<key>CFBundleIdentifier</key>
                    		<string>com.YourCompany.GameNameNoSpaces</string>
                    		<key>CFBundleName</key>
                    		<string>MyUDKGame</string>
                    		<key>CFBundleDisplayName</key>
                    		<string>UDK Game</string>
                    	</dict>	
                    	<key>CFBundleURLTypes</key> 
                    <array> 
                        <dict> 
                            <key>CFBundleURLSchemes</key> 
                            <array> 
                                <string>fbMYAPPID</string> 
                            </array> 
                        </dict> 
                    </array> 
                    </plist>
                    The facebook app I made on the facebook developers website is just a generic created app it has no code in it really, did your work anything into yours Juan?

                    Oh the only other settings I think I've played with is in the defaultengine.ini

                    Again heres mine

                    [FacebookIntegration]
                    AppID=MYAPPID
                    +Permissions=email
                    +Permissions=read_stream
                    +Permissions=publish_actions
                    +Permissions=read_stream
                    +Permissions=publish_stream


                    This is a bit of a monster post apologies but hopefully some of it might help others or show that I'm doing some daft stuff

                    Regards and gluck!

                    Greg

                    Comment


                      #11
                      Hi Showster, thanks for sharing that code, i'll try it now, 'cause i tried the GameEngine aproach but couldn't get it to work.

                      By the way, i think your problem is your plist, it looks wrong i think you're closing the tags wrong, here's how my plist looks like:

                      Code:
                      <?xml version="1.0" encoding="UTF-8"?>
                      <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
                      <plist version="1.0">
                      	<dict>
                      		<key>UIFileSharingEnabled</key>
                      		<true />
                      		<key>CFBundleIdentifier</key>
                      		<string>com.YourCompany.GameNameNoSpaces</string>
                      		<key>CFBundleName</key>
                      		<string>MyUDKGame</string>
                      		<key>CFBundleDisplayName</key>
                      		<string>UDK Game</string>
                      		<key>CFBundleURLTypes</key>
                      		<array>
                      			<dict>
                      				<key>CFBundleURLSchemes</key>
                      				<array>
                      					<string>fbMYAPPID</string>
                      				</array>
                      			</dict>
                      		</array>
                      	</dict>
                      </plist>

                      Comment


                        #12
                        I love you Juan!, that did the trick working facebook huzzah!

                        If anyone gets stuck with crashing facebook hopefully this thread has the answers for you If my work allows it I'll write a tutorial or something

                        All the best folks

                        Greg

                        Comment


                          #13
                          i'm glad it worked for you
                          I'm still trying the GameViewportClient way, can you explain what do you mean here exactly?

                          and I had to add the code package to the Engine.StartupPackages section.
                          i placed in that section the name of my game's folder inside my Src folder but i'm not sure it was like that, 'cause the facebook worked on my ipad but in the ipod crashed at startup.
                          Also after setting that in the StartupPackages my game went from 400 MB to 200 MB and in the ipad is working so fast but with weird things happening, so i'm not sure if that's what you meant there.

                          Comment


                            #14
                            This is from my DefaultEngine.ini

                            [Engine.PackagesToAlwaysCook]
                            +Package=EnvyEntry
                            +Package=Cloud2


                            [Engine.StartupPackages]
                            +Package=FX_HitEffects
                            +Package=UDKFonts
                            +Package=UTGame
                            +Package=Cloud2 <- my .u file not .upk
                            +Package=DinoUIAlwaysLoaded <- my .upk file for my viewportclient I had some images for transitions and stuff in there

                            [Engine.PackagesToForceCookPerMap]
                            .Map=UDKFrontEndMap
                            .Package=UDKFrontEnd
                            .Package=UI_FrontEnd_Art
                            .Package=Cloud2

                            I also made sure that stuff was in my UDKEngine.ini and checked all the others to make sure it had it as loading at startup.

                            If it increases your file size that sucks do you have a .u * .upk that share the same name? It could be loading all of your assets by mistake perhaps.

                            Maybe login can share how he connected to the GameEngine class. Perhaps that will have less side effects.

                            All the best

                            Greg

                            Comment


                              #15
                              Maybe login can share how he connected to the GameEngine class. Perhaps that will have less side effects.
                              The GameEngine tweak is just for avoiding crash when reloading a map.

                              Its actually really simple, you just need to inherit from GameEngine and add in the new class all the variables you need to keep even when transitioning between levels:

                              Code:
                              class IOS_GameEngine extends GameEngine;
                              
                              var MicroTransactionBase MicroTrans;
                              
                              DefaultProperties
                              {
                              }
                              then make that class your default engine class. The initial reference to the GameEngine class is made on UDK\Engine\Configs\BaseEngine.ini
                              But if you add the following to Configs\Mobile\Engine.ini it will work

                              Code:
                              [Engine.Engine]
                              GameEngine=IOSShared.IOS_GameEngine
                              BTW, IOSShared is the name of the project were the IOS_GameEngine class is created

                              Thats all I did for having it work. During the Store inialization I did this:

                              Code:
                              function StartStore()
                              {
                              	local IOS_GameEngine mEngine;
                              	mEngine = IOS_GameEngine(Class'Engine'.static.GetEngine());
                              	if (mEngine==none) return;
                              
                              	if ( mEngine.MicroTrans == none)
                              	{
                              		mEngine.MicroTrans = class'PlatformInterfaceBase'.static.GetMicroTransactionInterface();
                              	}
                                    .........
                              }
                              Thats an example for the in app purchases, but I guess that it can be adapted to the facebook singleton as well to avoid the crash.

                              Comment

                              Working...
                              X