Learn what Felgo offers to help your business succeed. Start your free evaluation today! Felgo for Your Business

GameNetworkExample

 import Felgo 3.0
 import QtQuick 2.0

 /*
   If the deviceId is changed, but the fbId stays the same, the new login will cause the deviceId to be connected with the old fb user!
   So to create a new user, first change the fbId and set it to an empty string, and then change the deviceId.
   As soon as the deviceId gets changed, also a new login request is sent. This may be changed to ease debugging later.
  */
 TestBase {

   // can either be deviceId or fbId
   property string textInputState

   // by default, to not merge the data of the old user with the newly loggedin one
   property bool mergeDataOfOldUserWithNewUser: false

  Column {
  spacing: 5

  Flow {
   width: scene.width
   spacing: 5
   SimpleButton {
     text: "Login"
     onClicked: {
       // use a forced login here, as it is more interesting to test; it is auto-logged in anyway at a restart where this functionality can be tested
       gameNetwork.authenticateLocalPlayer(true)
     }
   }

   SimpleButton {
     text: "Merge old WebStorage data with new user: "+ mergeDataOfOldUserWithNewUser
     onClicked: {
       // make sure to set it to the desired value before "Switch to User with DeviceId" is pressed below
       mergeDataOfOldUserWithNewUser = !mergeDataOfOldUserWithNewUser
     }
   }

   SimpleButton {
     text: "Switch to User with DeviceId"
     onClicked: {
       textInputState = "deviceId"
       nativeUtils.displayTextInput("Enter DeviceId", "", "", gameNetwork.user.deviceId)
     }
   }

   // MacAddress doesnt work on iOS7 upwards and thus shouldnt be used any more
 //  SimpleButton {
 //    text: "Change DevId to MacAdd"
 //    onClicked: {
 //      gameNetwork.user.facebookId = ""
 //      gameNetwork.user.deviceId = system.macAddress
 //      // re-login with the new user
 //      gameNetwork.authenticateLocalPlayer()
 //    }
 //  }
   SimpleButton {
     text: "Change DevId to UDID"
     onClicked: {
       gameNetwork.user.facebookId = ""
       gameNetwork.user.deviceId = system.UDID
       // re-login with the new user, a forced login request not using the old token
       gameNetwork.authenticateLocalPlayer(true)
     }
   }

   SimpleButton {
     text: "Change FbId"
     onClicked: {
       textInputState = "fbId"
       nativeUtils.displayTextInput("Enter FacebookId", "", "", gameNetwork.facebookId)
     }
   }
   SimpleButton {
     text: "Change FbToken"
     onClicked: {
       textInputState = "fbToken"
       nativeUtils.displayTextInput("Enter FacebookToken", "", "", gameNetwork.facebookToken)
     }
   }

   /*
     Users can connect their device with facebook. To do that, call the openSession() method of the fb plugin. Then vpgn.connectFacebookUser() is called as soon as the userId and accessToken are valid.

     To disconnect from fb, call vpgn.disconnectFacebookUser(). It calls closeSession() and thus logs out the fb user and removes the connection between device and user.
    */
   SimpleButton {
     text: "Fb Connect"
     color: "green"
     // make it transparent if user is already logged in - if not logged in, show it completely
     // but dont add this test here, for verbose debugging and to check what happens if it is called multiple times accidentally by user)
     opacity: !gameNetwork.facebookConnectionSuccessful ? 1 : 0.2
     onClicked: {
       console.log("Facebook connect button clicked");

       if(system.desktopPlatform) {
         // on desktop, we simulate the fb user and fb token - these must be entered by the user before calling connect here!
         // this is useful for testing
         // see the developer tool for the access token of test users
         gameNetwork.loginWithFacebookCredentials(gameNetwork.facebookId, gameNetwork.facebookToken)
       } else {
         // on mobile, the fbId and fbToken are read from the fb SDK

         // the token is read in the FelgoGameNetwork implementation, and then the userId gets read
         // if autoLoginFacebook is set to true (default), the user is then connected with facebook

         // after a connect with the fb plugin, the facebookId and facebookToken are updated in the VPGN and the device is connected to the new user
         gameNetwork.connectFacebookUser()
       }
     }
   }

   SimpleButton {
     id: fbLogoutButton
     text: "Disc. Fb"
     color: "brown"
     // make it transparent if user is not logged in - if not logged in, he should not be able to logout
     // but dont add this test here, for verbose debugging and to check what happens if it is called multiple times accidentally by user)
     opacity: gameNetwork.facebookConnectionSuccessful ? 1 : 0.2
     onClicked: {
       console.log("Facebook logout button clicked");
       // calls facebook.closeSession() and removes connection of this device with the fb user!
       // make sure to clear the local cache before if you want to avoid storing the webStorage data to the new account!
       gameNetwork.disconnectFacebookUser()
     }
   }

   SimpleButton {
     text: gameNetwork.askForWritePermissionsAtFacebookConnect ? "AskWriteOn" : "AskWriteOff"
     onClicked: {
       // if this is set to false, there wont be shown a write permission dialog at initial connect (this is the default for future use!)
       // so if set to false, the permission dialog is shown when posting a highscore or achievement!
       // this has only an effect if disconnecting from fb, and then connect again
       gameNetwork.askForWritePermissionsAtFacebookConnect = !gameNetwork.askForWritePermissionsAtFacebookConnect
     }
   }

   /*SimpleButton {
     text: "Fb open"
     onClicked: {
       facebook.openSession()
     }
   }*/

   SimpleButton {
     text: "Fb GET"
     onClicked: {
       // by starting an empty get request, we can show the permission request (for all readPermissions) dialog on purpose, before really sending a post request
       facebook.getGraphRequest("")
     }
   }

   SimpleButton {
     text: "Fb POST"
     // if the user already allowed the permissions, we dont need to make this choice that obvious
     // also tests if the property works
     opacity: !gameNetwork.facebookWritePermissionsAllowed ? 1 : 0.2
     onClicked: {
       // by starting an empty post request, we can show the permission request (for all publishPermissions) dialog on purpose, before really sending a post request
       facebook.postGraphRequest("")
     }
   }

   SimpleButton {
     id: fbDeleteData
     text: "Delete Fb Data"
     color: "red"
     onClicked: {
       console.log("Facebook Delete Data button clicked");
       // this clears all data associated for this user with facebook!
       // what else does it do?
       gameNetwork.deleteFacebookData()
     }
   }

   SimpleButton {
     id: userDelete
     text: "Delete User"
     color: "red"
     onClicked: {
       console.log("Delete Profile button clicked");
       // this clears all data associated for this user with facebook!
       // what else does it do?
       gameNetwork.deleteUser()
     }
   }

   Connections {
     target: nativeUtils
     onTextInputFinished: {

       if(textInputState === "deviceId" && accepted) {
         // reset the fbId, because if this device was connected with fb it gets retrieved from the login
         // this makes it impossible to change the fbId though, because with changing the deviceId the fbId is lost! change this!
         gameNetwork.facebookId = ""
         gameNetwork.facebookToken = ""
         gameNetwork.user.deviceId = enteredText

         // if you want to simulate a fresh connect to another user, clear the local webStorage before
         // we can use this by default, as normally a new user will be received
         // NOTE: existing queued write requests will be removed here! thus any previos write calls that were not transmitted are lost here!
         // if this would not be called, the existing WebStorage data would be merged with the new logged in user! thus it would simulate a facebook connect where existing data is merged to the new user
         // thus it depends what should be tested - if the merging should be tested, set the mergeDataOfOldUserWithNewUser to true
         if(mergeDataOfOldUserWithNewUser === false) {
           gameNetwork.clearAllStoragesLocally()
         }

         // this is also called automatically in disconnectFacebookuser(), to make sure the old userScores and userAchievements are deleted
         // for testing the disconnect process, it is useful to also simulate this behavior here when another deviceId is faked
         gameNetwork.__clearUserData()

         // by calling this, all WebStorage elements get set their inServerSync and initiallyInServerSync to false
         gameNetwork.userIdChangedOrAboutToChange()

         // re-login with the new user
         gameNetwork.authenticateLocalPlayer(true)
       } else if(textInputState === "fbId" && accepted) {
         gameNetwork.facebookId = enteredText
         // do not re-login automatically - press the "Connect with fb" button manually to allow changing the fbId AND the token without auto-login
         // on desktop, we can call a re-login automatically when we change either the fbId or fbToken
         if(system.desktopPlatform) {
           gameNetwork.authenticateLocalPlayer(true)
         }
       } else if(textInputState === "fbToken" && accepted) {
         gameNetwork.facebookToken = enteredText
         // do not re-login automatically - press the "Connect with fb" button manually to allow changing the fbId AND the token without auto-login
         // on desktop, we can call a re-login automatically when we change either the fbId or fbToken
         if(system.desktopPlatform) {
           gameNetwork.authenticateLocalPlayer(true)
         }
       }else if(textInputState === "username" && accepted) {
         gameNetwork.updateUserName(enteredText)
       }else if(textInputState === "userdata" && accepted) {
       gameNetwork.updateUserCustomData(enteredText)
     }

       textInputState = ""
     }
   }

   Connections {
     target: gameNetwork.user
     onUserBlocked: nativeUtils.displayAlertDialog("User blocked", "User got blocked")
   }

   SimpleButton {
     text: "Change Username"
     onClicked: {
       textInputState = "username"
       nativeUtils.displayTextInput("Enter Username", "", "", gameNetwork.user.name)
     }
   }

   SimpleButton {
     text: "Change Custom User data"
     onClicked: {
       textInputState = "userdata"
       nativeUtils.displayTextInput("Enter Userdata", "", "", gameNetwork.user.customData)
     }
   }

   SimpleButton {
     text: gameNetwork.pauseRequests ? "PauseRequestsOn" : "PauseRequestsOff"
     onClicked: {
       // allows to delay the requests until you want to explicitly start them, useful e.g. to avoid blocks in animations
       gameNetwork.pauseRequests = !gameNetwork.pauseRequests
     }
   }

   SimpleButton {
     text: gameNetwork.api.simulateConnectionError ? "Network Off (network errors are simulated)" : "Network On"
     onClicked: {
       // by changing this property, network errors can be simulated with every request
       // try the following: set the simulateConnectionError to false, and then call a write-call, like submitting a highscore or an achievement
       // then you can de-activate it again, the user gets then logged in and all write-calls are created
       gameNetwork.api.simulateConnectionError = !gameNetwork.api.simulateConnectionError

       if(!gameNetwork.api.simulateConnectionError) {
         // re-login if simulateConnectionError is disabled, so when switched to normal moder
         // after authentication the cached requests are sent
         // do not call that automatically - a login can be started manually
         // on mobiles, we also dont get a notification when connection gets available, so we re-login in applicationResumed if user is not authenticated
         // not relogin here, also allows us to better test that any request could be sent after the internet connection is gone
         //gameNetwork.authenticateLocalPlayer()
       }

     }
   }
  }// Flow

  Text {
    width: parent.width
    wrapMode: Text.Wrap
    text: "UserId: " + gameNetwork.user.userId + ", UserName: " + gameNetwork.userName + ", DisplayName: " + gameNetwork.displayName + ", DeviceId: " + gameNetwork.user.deviceId + ", CustomData: " + gameNetwork.user.customData + ", Blocked: " + gameNetwork.user.blocked + ", Locale: " + gameNetwork.user.locale + ", Timestamp: " + gameNetwork.user.timestamp + ", Token: " + gameNetwork.user.authenticationToken +
          "\nFBId: " + gameNetwork.facebookId + ", FBTokenValid: " + gameNetwork.facebookTokenValid + ", " + (gameNetwork.facebookToken === "" ? "FBTokenEmpty" : "FBTokenSet") + ", grantedFbReadPerm: " + gameNetwork.grantedFacebookReadPermissions + ", grantedFbWritePerm: " + gameNetwork.grantedFacebookWritePermissions + ", grantedFbPerm: " + JSON.stringify(gameNetwork.grantedFacebookPermissions) + // + ", FBToken: " + gameNetwork.facebookToken
          "\nfacebookConnectionState: " + gameNetwork.facebookConnectionState + ", facebookConnectionSuccessful: " + gameNetwork.facebookConnectionSuccessful + ", facebook.sessionState: " + facebook.sessionState
    color: "white"
    font.pixelSize: 7
  }
Qt_Technology_Partner_RGB_475 Qt_Service_Partner_RGB_475_padded