Advertisement
Guest User

Unity Facebook login

a guest
Dec 9th, 2014
496
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 12.04 KB | None | 0 0
  1. using UnityEngine;
  2. using UnityEngine.Events;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5.  
  6. public class FacebookUserInfo {
  7.     public string id = null;
  8.     public string firstName = "Unknown";
  9.     public string lastName = "";
  10.     public string gender = "unknown";
  11.     public Sprite profilePicture = null;
  12. }
  13.  
  14. public class FacebookManager : MonoBehaviour {
  15.     private static FacebookManager instance = null;
  16.    
  17.     // you can assign event handler methods in the inspector
  18.     public UnityEvent loginStatusChangedEvent;
  19.     public UnityEvent userInfoDownloadedEvent;
  20.     public UnityEvent friendsInfoDownloadedEvent;
  21.  
  22.     public enum LoginStatusCode {
  23.         LoggingOut,
  24.         NotLoggedIn,
  25.         AttemptingFBLogin,
  26.         LoggedIn,
  27.         WaitingForConnection
  28.     }
  29.    
  30.     private static LoginStatusCode loginStatus = LoginStatusCode.WaitingForConnection;
  31.    
  32.     public static LoginStatusCode LoginStatus {
  33.         private set {
  34.             loginStatus = value;
  35.             if (instance != null) {
  36.                 instance.OnLoginStatusChanged();
  37.             }
  38.         }
  39.         get {
  40.             return loginStatus;
  41.         }
  42.     }
  43.    
  44.     private static FacebookUserInfo currentUserFacebookUserInfo = new FacebookUserInfo();
  45.     public static FacebookUserInfo CurrentUserFacebookUserInfo {
  46.         get { return currentUserFacebookUserInfo; }
  47.         private set { currentUserFacebookUserInfo = value; }
  48.     }
  49.    
  50.     private static List<FacebookUserInfo> friendUserFacebookInfos = new List<FacebookUserInfo>();
  51.     public static List<FacebookUserInfo> FriendUserFacebookInfos {
  52.         get { return friendUserFacebookInfos; }
  53.         private set { friendUserFacebookInfos = value; }
  54.     }
  55.    
  56.     private static Dictionary<string, bool> userFacebookPermissions = new Dictionary<string, bool>();
  57.  
  58.     public static bool FriendsPermissionRequested {
  59.         get {
  60.             return userFacebookPermissions.ContainsKey("user_friends");
  61.         }
  62.         private set { ;}
  63.     }
  64.  
  65.     public static bool FriendsPermissionGranted {
  66.         get {
  67.             return FriendsPermissionRequested && userFacebookPermissions["user_friends"] == true;
  68.         }
  69.         private set { ;}
  70.     }
  71.     public static bool PublishPermissionRequested {
  72.         get {
  73.             return userFacebookPermissions.ContainsKey("publish_actions");
  74.         }
  75.         private set { ;}
  76.     }
  77.     public static bool PublishPermissionGranted {
  78.         get {
  79.             return PublishPermissionRequested && userFacebookPermissions["publish_actions"] == true;
  80.         }
  81.         private set { ;}
  82.     }
  83.  
  84.     private static bool Connected {
  85.         get {
  86.             return Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork
  87.                 || Application.internetReachability == NetworkReachability.ReachableViaCarrierDataNetwork;
  88.         }
  89.         set { ;}
  90.     }
  91.    
  92.     void Awake() {
  93.         if (instance != null) {
  94.             Debug.LogError("More than one FacebookManager component in the scene! GameObject: \"" + gameObject.name + "\" Tag: \"" + gameObject.tag + "\"");
  95.             Destroy(this);
  96.         }
  97.         else {
  98.             instance = this;
  99.         }
  100.     }
  101.    
  102.     void Start() {
  103.         #if UNITY_IPHONE || UNITY_ANDROID
  104.         StartCoroutine(InitialiseFacebook());
  105.         #else
  106.         LoginStatus = LoginStatusCode.NotLoggedIn;
  107.         #endif
  108.     }
  109.  
  110.     void OnDestroy() {
  111.         if (instance == this) {
  112.             instance = null;
  113.         }
  114.     }
  115.  
  116.     void OnLoginStatusChanged() {
  117.         loginStatusChangedEvent.Invoke();
  118.     }
  119.  
  120.     IEnumerator InitialiseFacebook() {
  121.         LoginStatus = LoginStatusCode.WaitingForConnection;
  122.         // keep repeating until FB initialises
  123.         while (!FB.IsInitialized) {
  124.             if (Connected && LoginStatus != LoginStatusCode.AttemptingFBLogin) {
  125.                 LoginStatus = LoginStatusCode.AttemptingFBLogin;
  126.                 FB.Init(OnFBInitComplete, null, null);
  127.                 yield return StartCoroutine(WaitForSecondsUnscaled(10.0f));
  128.             }
  129.             else if (!Connected && LoginStatus != LoginStatusCode.WaitingForConnection) {
  130.                 LoginStatus = LoginStatusCode.WaitingForConnection;
  131.             }
  132.             else {
  133.                 yield return StartCoroutine(WaitForSecondsUnscaled(5.0f));
  134.             }
  135.         }
  136.     }
  137.  
  138.     // use unscaled time so that it still works when game is paused
  139.     IEnumerator WaitForSecondsUnscaled(float seconds) {
  140.         float startTime = Time.realtimeSinceStartup;
  141.         while (Time.realtimeSinceStartup - startTime < seconds) {
  142.             yield return null;
  143.         }
  144.     }
  145.  
  146.     void OnFBInitComplete() {
  147.         if (FB.IsLoggedIn) {
  148.             LoginStatus = LoginStatusCode.LoggedIn;
  149.             GetFBUserInfo();
  150.         }
  151.         else {
  152.             LoginStatus = LoginStatusCode.NotLoggedIn;
  153.         }
  154.     }
  155.    
  156.     void GetFBUserInfo() {
  157.         // Use an anonymous function in place of delegate
  158.         // It is like calling FB.API("...", Facebook.HttpMethod.GET, DelegateMethodName)
  159.         FB.API("/me/permissions", Facebook.HttpMethod.GET, (FBResult result) => {
  160.             if (result.Error != null) {
  161.                 Debug.LogError("Error getting FB permissions: " + result.Error);
  162.             }
  163.             else {
  164.                 // use Facebook method supplied to deserialize the result
  165.                 // we don't need to know how they do it, just what data type is returned :)
  166.                 Dictionary<string, object> dataObjects = Facebook.MiniJSON.Json.Deserialize(result.Text) as Dictionary<string, object>;
  167.                 List<object> permissionObjects = dataObjects["data"] as List<object>;
  168.            
  169.                 // lets store all the permission info in case we need to know what's been granted
  170.                 userFacebookPermissions = new Dictionary<string, bool>();
  171.            
  172.                 foreach (object permissionObject in permissionObjects) {
  173.                     Dictionary<string, object> permissionObjectDict = permissionObject as Dictionary<string, object>;
  174.                     foreach (KeyValuePair<string, object> pair in permissionObjectDict) {
  175.                         userFacebookPermissions.Add(pair.Key, System.Convert.ToBoolean(pair.Value));              
  176.                     }
  177.                 }
  178.              
  179.                 // get the current user's info.
  180.                 // /me graph URL always points to current user
  181.                 StartCoroutine(GetFacebookUserInfo("/me", true));
  182.             }
  183.         });
  184.     }
  185.    
  186.     void OnFriendsDownloaded(FBResult result) {
  187.         if (result.Error != null) {
  188.             Debug.LogError("Error getting FB friends: " + result.Error);
  189.         }
  190.         else {
  191.             Dictionary<string, object> responseObject = Facebook.MiniJSON.Json.Deserialize(result.Text) as Dictionary<string, object>;            
  192.             StartCoroutine(GetFriendsFacebookUserInfo(responseObject["data"] as List<object>));
  193.         }
  194.     }
  195.  
  196.     IEnumerator GetFriendsFacebookUserInfo(List<object> responseDataObjects) {
  197.         int numFriends = responseDataObjects.Count;
  198.         foreach (object friendDataObject in responseDataObjects) {
  199.             Dictionary<string, object> friendDataObjectDict = friendDataObject as Dictionary<string, object>;
  200.             // get one friend info at a time
  201.             yield return StartCoroutine(GetFacebookUserInfo("/" + friendDataObjectDict["id"].ToString(), false));
  202.             if (FriendUserFacebookInfos.Count == numFriends) {
  203.                 friendsInfoDownloadedEvent.Invoke();
  204.             }
  205.         }
  206.     }
  207.    
  208.     IEnumerator GetFacebookUserInfo(string graphURL, bool currentUser) {
  209.         bool finishedGettingInfo = false;
  210.    
  211.         FacebookUserInfo userInfo = new FacebookUserInfo();
  212.    
  213.         // get user info
  214.         FB.API(graphURL, Facebook.HttpMethod.GET, (FBResult userInfoResult) => {
  215.             if (userInfoResult.Error != null) {
  216.                 Debug.LogError("Error getting FB friend info: " + userInfoResult.Error);
  217.             }
  218.             else {
  219.                 Dictionary<string, object> userInfoObjects = Facebook.MiniJSON.Json.Deserialize(userInfoResult.Text) as Dictionary<string, object>;
  220.                 userInfo.id = userInfoObjects["id"].ToString();
  221.                 userInfo.firstName = userInfoObjects["first_name"].ToString();
  222.                 userInfo.lastName = userInfoObjects["last_name"].ToString();
  223.                 userInfo.gender = userInfoObjects["gender"].ToString();
  224.             }            
  225.             finishedGettingInfo = true;
  226.         });
  227.  
  228.         // wait until info got
  229.         while (!finishedGettingInfo) {
  230.             yield return null;
  231.         }
  232.  
  233.         // if we successfully got info and id, get the profile picture
  234.         if (userInfo.id != null) {          
  235.             bool finishedGettingPictureURL = false;
  236.             string pictureURL = null;
  237.        
  238.             // get profile picture url
  239.             FB.API(FacebookUtil.GetPictureURL(userInfo.id, 128, 128), Facebook.HttpMethod.GET, (FBResult pictureResult) => {
  240.                 if (pictureResult.Error != null) {
  241.                     Debug.LogError("Error getting FB friend picture: " + pictureResult.Error);
  242.                 }
  243.                 else {
  244.                     pictureURL = FacebookUtil.DeserializePictureURLString(pictureResult.Text);
  245.                 }
  246.                 finishedGettingPictureURL = true;
  247.             });
  248.  
  249.             // wait for it...
  250.             while (!finishedGettingPictureURL) {
  251.                 yield return null;
  252.             }
  253.        
  254.             // get profile picture
  255.             if (pictureURL != null) {
  256.                 WWW www = new WWW(pictureURL);
  257.                 yield return www;
  258.                 userInfo.profilePicture = Sprite.Create(www.texture,
  259.                                                     new Rect(0, 0, 128, 128),
  260.                                                     new Vector2(0.5f, 0.5f));
  261.             }
  262.         }
  263.  
  264.         // if we're getting this user's info
  265.         if (currentUser) {
  266.             CurrentUserFacebookUserInfo = userInfo;
  267.             userInfoDownloadedEvent.Invoke();
  268.             // now get friend user info
  269.             if (FriendsPermissionGranted) {
  270.                 FB.API("/v2.1/me/friends", Facebook.HttpMethod.GET, OnFriendsDownloaded);
  271.             }
  272.         }
  273.         else {
  274.             // otherwise we were getting a friend's info. add it.
  275.             FriendUserFacebookInfos.Add(userInfo);
  276.         }
  277.     }
  278.        
  279.     public static void TryFBLogin() {
  280.         if (instance != null) {
  281.             #if UNITY_IPHONE || UNITY_ANDROID
  282.             if (FB.IsInitialized && !FB.IsLoggedIn && LoginStatus == LoginStatusCode.NotLoggedIn) {
  283.                 LoginStatus = LoginStatusCode.AttemptingFBLogin;
  284.                 // just asking for some basic permissions. you can add more as required.
  285.                 FB.Login("public_profile,user_friends", instance.OnFBLoginAttempted);
  286.             }
  287.             #endif
  288.         }
  289.     }
  290.    
  291.     void OnFBLoginAttempted(FBResult fbResult) {
  292.         if (FB.IsLoggedIn) {
  293.             LoginStatus = LoginStatusCode.LoggedIn;
  294.             GetFBUserInfo();
  295.         }
  296.         else {
  297.             LoginStatus = LoginStatusCode.NotLoggedIn;
  298.         }
  299.     }
  300.    
  301.     public static void LogoutUser() {
  302.         if (instance != null && LoginStatus == LoginStatusCode.LoggedIn) {
  303.             instance.StartCoroutine(instance.DoLogout());
  304.         }
  305.     }
  306.  
  307.     IEnumerator DoLogout() {
  308.         while (LoginStatus == LoginStatusCode.AttemptingFBLogin) {
  309.             yield return null;
  310.         }
  311.          
  312.         LoginStatus = LoginStatusCode.LoggingOut;
  313.         yield return null;
  314.  
  315.         // add any other cleanup code you need
  316.  
  317.         CurrentUserFacebookUserInfo = new FacebookUserInfo();
  318.         FriendUserFacebookInfos = new List<FacebookUserInfo>();
  319.  
  320.         if (FB.IsLoggedIn) {
  321.             FB.Logout();
  322.         }
  323.  
  324.         LoginStatus = LoginStatusCode.NotLoggedIn;
  325.     }
  326. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement