EvilMindDevs / hms-unity-plugin

The HMS Unity Plugin makes it easy to include Huawei Mobile Services into Unity-based games. Authentication, in-app purchases, push alerts, ads, and interaction with gaming services are just a few of the basic capabilities that this formidable tool makes available to your applications.
https://evilminddevs.gitbook.io/hms-unity-plugin/
309 stars 44 forks source link

Game Service not working #51

Closed Totoro83 closed 4 years ago

Totoro83 commented 4 years ago

I'm trying to use Game Service but I'm not able to. With Huawei support I verified that both console and manifest seems to be ok, but when I try to use anything in the game service nothing seems to work (probably it can be helpful to know that IAPs works as expected in sandboxing mode.)

I am attaching a minimal demo so you can see how I try to access to the game service and the relative logcat (the only difference from the files I'm attaching and the ones in my demo is that I removed removing the leaderboard ID from the TestHMS inspector, both because it would not be useful for you to know mine and because I'm not sure if it is a sensible information, to test it you have to insert an ID ok for you and obviously to correctly install the plugin.) If I do something wrong it would be helpful to have some documentation or explanation about how to correctly use the APIs.

Totoro83 commented 4 years ago

As requested from the Huawei support I'm using now just the SDK, without the plugin's GameObjects.

Rewriting everything this way I noticed that in the AccountManager there is not any request to the Game Service scope. It should be documented at least (and probably would be even better to have a flag in the AccountManager interface to add it if wanted, I'll pull a request with it if it will turn out to be the problem).

Having said that, the problems are exactly the same as before, except that now the first time the app is running it is necessary to authorize the game service. I'm attaching the files again so you can check:

demo logcat

m0skit0 commented 4 years ago

Hi @Totoro83 ! Currently Game GameObjects are not up-to-date, we're working to bring them up-to-date asap. As a workaround you can directly use the Unity HMS SDK included in the plugin, which directly relates to the native Android Java SDK. Please check the Java docs for Game Service on how to use it.

Totoro83 commented 4 years ago

In the second demo I does not use GameObjects at all, and I use directly the SDK. And I simply can't use that SDK using the java docs, because there are functions with different interfaces. For example, getJosAppsClient in the doc you gave me does not require any auth Huawei ID, while the one in the Unity SDK requires one.

Obviously I can use directly the native java APIs, not using your project at all, but if I have to use the solution you're suggesting me I'm puzzled.

m0skit0 commented 4 years ago

As far as I can see both methods are available. The method without the second parameter was added recently to the SDK.

Totoro83 commented 4 years ago

Yep, both exists in the native side (even if the one without the second parameter is deprecated). But if you're talking about the master version of the SDK, and if the SDK is contained in HuaweiMobileServices.dll (I can't find any source) there is just one single version of it, the one that requires AuthHuaweiId, whose implementation is (according to dotpeek)

public static IJosAppsClient GetJosAppsClient(AuthHuaweiId authHuaweiId)
    {
      return (IJosAppsClient) new JosAppsClientWrapper((AndroidJavaObject) ((AndroidJavaObject) JosApps.sJavaClass).CallStatic<AndroidJavaObject>("getJosAppsClient", new object[2]
      {
        (object) AndroidContext.ActivityContext,
        (object) authHuaweiId.JavaObject
      }));
    }

so the deprecated method is used.

But ok, I can try to follow the doc and fill the holes as I undestand, hoping that all will go ok.

Totoro83 commented 4 years ago

I think I followed the best I could the doc, and the only thing changed is the TestHSM.cs source, so I'm publishing just that one:

using HuaweiMobileServices.Base;
using HuaweiMobileServices.Game;
using HuaweiMobileServices.Id;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class TestHMS : MonoBehaviour
{
    public UnityEvent OnSignInSuccess;
    public UnityEvent OnSignInFailure;
    public UnityEvent OnGetPlayerInfoSuccess;
    public UnityEvent OnGetPlayerInfoFailure;

    public string leaderboardId;

    public bool? signInSuccess;
    public bool? getPlayerInfoSuccess;

    HuaweiIdAuthService authService;
    AuthHuaweiId id;
    IPlayersClient playersClient;
    IRankingsClient rankingsClient;

    void Awake() => HuaweiMobileServicesUtil.SetApplication();

    public void Connect()
    {
        var authParams = new HuaweiIdAuthParamsHelper(HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
            .SetScopeList(new List<Scope> { HuaweiIdAuthParams.SCOPE_GAMES }).SetAuthorizationCode().CreateParams();
        authService = HuaweiIdAuthManager.GetService(authParams);
        Debug.Log("Signing in");
        authService.StartSignIn(
            (id) => { this.id = id; signInSuccess = true; },
            (e)  => { Debug.Log($"Not Connected: {e.Message} {e.ErrorCode}");  signInSuccess = false; });
    }

    void Update()
    {
        if (signInSuccess != null)
        {
            if (signInSuccess.Value)
            {
                IJosAppsClient josAppsClient = JosApps.GetJosAppsClient(id);
                josAppsClient.Init();
                playersClient = Games.GetPlayersClient(id);
                rankingsClient = Games.GetRankingsClient(id);
            }
            (signInSuccess.Value ? OnSignInSuccess : OnSignInFailure).Invoke();
        }
        signInSuccess = null;
        if (getPlayerInfoSuccess != null)
            (getPlayerInfoSuccess.Value ? OnGetPlayerInfoSuccess : OnGetPlayerInfoFailure).Invoke();
        getPlayerInfoSuccess = null;
    }

    public void GetPlayerInfo() => playersClient.CurrentPlayer
        .AddOnSuccessListener(r => getPlayerInfoSuccess = true)
        .AddOnFailureListener(e =>
        {
            Debug.Log($"GetPlayerInfo Failure: {e.Message} {e.ErrorCode}");
            getPlayerInfoSuccess = false;
        });

    public void SendScore() => rankingsClient.SubmitScoreWithResult(leaderboardId, 100)
        .AddOnSuccessListener(r => Debug.Log("SubmitScore Success"))
        .AddOnFailureListener(e => Debug.Log($"SubmitScore Failure: {e.Message} {e.ErrorCode}"));
}

From the doc:

  1. https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/ame-pre-dev-0000001050121524

The pre-check should be ok, I'll have a double check just to be sure, but it should be correct

  1. https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/game-start-0000001050123475

I moved SetApplication at start. I have not do the same with GetJosAppsClient because I need the AuthHuaweiId. I call it at the same moment I get the Id.

  1. https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/game-login-0000001050121526

I sign in as explained in https://developer.huawei.com/consumer/en/doc/HMSCore-Guides-V5/login-authorization-code-0000001050050845-V5

I stopped at step 5 because the doc at point 3 says that the remaining steps are optional, and the only modification I made in the authParams is to require the AutorizationCode (removing the request to the IdToken), as specified in the doc.

The moment I try to call GetPlayerInfo (as specified from the doc) I obtain an error.

So, the only things I changed following the doc as much as I could with the exposed APIs are:

  1. Now I call SetApplication at the very start.
  2. I call SetAuthorizationCode instead of SetIdToken in generating HuaweiIdAuthParams.

Everything else seemed to be like the doc explains (at least until that point).

Because I'm obtaining exactly the same errors as before it would be really useful to have a functioning code calling something inherent to game service (GetPlayersInfo would be perfect, because it gives error to me) to test if the problem is in my code or somewhere else.

m0skit0 commented 4 years ago

Source code for the SDK wrapper is here. You're welcome if you want to contribute.

Are you sure when you call GetPlayerInfo() this part

IJosAppsClient josAppsClient = JosApps.GetJosAppsClient(id);
josAppsClient.Init();
playersClient = Games.GetPlayersClient(id);
rankingsClient = Games.GetRankingsClient(id);

has already executed? I can't see where is GetPlayerInfo() called there.

Totoro83 commented 4 years ago

Yep, I'm sure because to call GetPlayersInfo I have to press a UI button (as you can see opening the scene in the demo). And that button is showed only if OnSignInSuccess is called. And OnSignInSuccess is called after that code block.

However thanks for the code wrapper, i'll try that one.

m0skit0 commented 4 years ago

Ok yes, I see that on the demo, sorry. The DLL is generated from that source code. Feel free to tinker with the SDK. Can you check what's the message in the WrappedExceptionMessage of the exception you´re receiving on the failure lambda?

Totoro83 commented 4 years ago

Yeah, the WrapperExceptionMessage is a very simple "6004: ". The next step will be to use the SDK without a plugin, and create a project from scratch with only this very demo, to make everything from scratch and see if I made something wrong.

Totoro83 commented 4 years ago

Some update. I'm using directly the SDK now, and I wrote an app from scratch, creating an app from scratch in the appgallery too. Strangely it worked as a charm, so I investigated and for some strange reasons even my starting app worked with the newly created appgallery app. I double checked all the data again in the appgallery for the app I'm developing, but nothing was wrong, so I deleted the appgallery app, I recreated it, and now all works. If you ask me why I can't give you an answer... I suppose we can consider the issue closed, as it does not seem to be a plugin problem.