Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

From The Blog: Update on the new GPGS v2 plugin
Started by CoronaBot Oct 31 2018 01:49 PM

11 replies to this topic
[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

CoronaBot

[GLOBAL: userInfoPane.html]
CoronaBot
  • Contributor

  • 416 posts
  • Corona Staff

Corona Labs would like to update you about our recent plugin for Google Play Games Services. This plugin is known as GPGS v2 and there is a breaking change to be aware of.

We’ve worked hard to make it call compatible with the older GPGS v1 plugin, however Google has changed their initialization and login process significantly. We had to make a change that you will need to adapt to so that you can successfully login and know if your app is connected.

Simply remove any calls to the gpgs.init() API and instead call gpgs.login() directly:

gpgs.login( { userInitiated=true, listener=gpgsLoginListener } )

Where gpgsLoginListener is the name of your function to handle a successful login. If you have questions about the plugin, please joins us in our community forums.


View the full article

[TOPIC: post.html]
#2

TawaNicolas

[GLOBAL: userInfoPane.html]
TawaNicolas
  • Observer

  • 17 posts
  • Corona SDK

I tried using this plugin, but I'm getting a crash when I try to show leaderboards or to submit scores to it.

 

Here's the logcat:

D plugin.gpgs.v2: leaderboards.show()
I Corona  : ERROR: Runtime error
I Corona  : java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.ContextWrapper.getApplicationContext()' on a null object reference
I Corona  : Java Stack Trace:
I Corona  : 	plugin.gpgs.v2.Connector.getContext(Connector.java:58)
I Corona  : 	plugin.gpgs.v2.Connector.isConnected(Connector.java:50)
I Corona  : 	plugin.gpgs.v2.Utils.checkConnection(Utils.java:52)
I Corona  : 	plugin.gpgs.v2.Leaderboards.show(Leaderboards.java:278)
I Corona  : 	plugin.gpgs.v2.Leaderboards$4.invoke(Leaderboards.java:51)
I Corona  : 	com.ansca.corona.JavaToNativeShim.nativeTouchEvent(Native Method)
I Corona  : 	com.ansca.corona.JavaToNativeShim.touchEvent(JavaToNativeShim.java:430)
I Corona  : 	com.ansca.corona.input.RaiseTouchEventTask.executeUsing(RaiseTouchEventTask.java:39)
I Corona  : 	com.ansca.corona.CoronaRuntimeTaskDispatcher$TaskEvent.Send(CoronaRuntimeTaskDispatcher.java:170)
I Corona  : 	com.ansca.corona.events.EventManager.sendEvents(EventManager.java:91)
I Corona  : 	com.ansca.corona.Controller.updateRuntimeState(Controller.java:318)
I Corona  : 	com.ansca.corona.graphics.opengl.CoronaGLSurfaceView$CoronaRen
I Corona  : ERROR: Runtime error
I Corona  : java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.ContextWrapper.getApplicationContext()' on a null object reference
I Corona  : Java Stack Trace:
I Corona  : 	plugin.gpgs.v2.Connector.getContext(Connector.java:58)
I Corona  : 	plugin.gpgs.v2.Connector.isConnected(Connector.java:50)
I Corona  : 	plugin.gpgs.v2.Utils.checkConnection(Utils.java:52)
I Corona  : 	plugin.gpgs.v2.Leaderboards.show(Leaderboards.java:278)
I Corona  : 	plugin.gpgs.v2.Leaderboards$4.invoke(Leaderboards.java:51)
I Corona  : 	com.ansca.corona.JavaToNativeShim.nativeTouchEvent(Native Method)
I Corona  : 	com.ansca.corona.JavaToNativeShim.touchEvent(JavaToNativeShim.java:430)
I Corona  : 	com.ansca.corona.input.RaiseTouchEventTask.executeUsing(RaiseTouchEventTask.java:39)
I Corona  : 	com.ansca.corona.CoronaRuntimeTaskDispatcher$TaskEvent.Send(CoronaRuntimeTaskDispatcher.java:170)
I Corona  : 	com.ansca.corona.events.EventManager.sendEvents(EventManager.java:91)
I Corona  : 	com.ansca.corona.Controller.updateRuntimeState(Controller.java:318)
I Corona  : 	com.ansca.corona.graphics.opengl.CoronaGLSurfaceView$CoronaRenderer.onDrawFrame(CoronaGLSurfaceView.java:425)
I Corona  : 	com.ansca.corona.graphics.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1625)
I Corona  : 	com.ansca.corona.graphics.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1380)
I Corona  : stack traceback:
I Corona  : 	[C]: ?
I Corona  : 	[C]: in function 'show'
I Corona  : 	?: in function 'showLeaderboards'
I Corona  : 	?: in function '_onEvent'
I Corona  : 	/Users/jenkins/slaveroot/workspace/Templates/label/android/subrepos/widget/widgetLibrary/widget_button.lua:120: in function 'manageButtonTouch'
I Corona  : 	/Users/jenkins/slaveroot/workspace/Templates/label/android/subrepos/widget/widgetLibrary/widget_button.lua:658: in function 'method'
I Corona  : 	/Users/jenkins/slaveroot/workspace/Templates/label/android/platform/resources/init.lua:221: in function </Users/jenkins/slaveroot/workspace/Templates/label/android/platform/resources/init.lua:190>

Any idea what could be causing this? It's driving me crazy!



[TOPIC: post.html]
#3

TawaNicolas

[GLOBAL: userInfoPane.html]
TawaNicolas
  • Observer

  • 17 posts
  • Corona SDK

This is blocking my project from finishing.  :(

Any help would be appreciated. 



[TOPIC: post.html]
#4

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,147 posts
  • Corona SDK

I'll see if I can get an engineer to look into this.

 

In the meantime can you share your code?

 

What version of Corona as you using?

 

Are you doing native builds or simulator builds?

 

What device and version of Android are you testing on?

 

Is the test device rooted?

 

Are you building with a release keystore or a debug keystore?

 

Are you sure you have everything set up correctly in your Google Play developer console?

 

 

Rob



[TOPIC: post.html]
#5

TawaNicolas

[GLOBAL: userInfoPane.html]
TawaNicolas
  • Observer

  • 17 posts
  • Corona SDK

Thank you for your response Rob.

 

Here's the code leaderboard handler I created:

local isAndroid = false
local isiOS = false

local targetAppStore = system.getInfo( "targetAppStore" )

local leaderboardIDs = {
	"leaderboardid1", -- those are placeholder IDs for the purpose of this post.
	"leaderboardid2"  -- In my code I have the real values from Play Store Console.
}


if ( "apple" == targetAppStore ) then  -- iOS
	isiOS = true
elseif ( "google" == targetAppStore ) then  -- Android
	isAndroid = true

	local licensing = require( "licensing" )
 
	local function licensingListener( event )
		if not ( event.isVerified ) then
		    native.showAlert( "Event!", "You're a pirate!", { "OK" } )
		else
		    native.showAlert( "Event!", "You're not a pirate!", { "OK" } )
		end
	end

	local licensingInit = licensing.init( "google" )

	if ( licensingInit == true ) then
		licensing.verify( licensingListener )
	else
	end
end	

local gameNetwork = nil
local gpgs = nil

if isiOS then
	gameNetwork = require( "gameNetwork" )
end

if isAndroid then
	gpgs = require( "plugin.gpgs.v2" )
	gpgs.enableDebug()
end

local m = {}

local function initCallback( event )
	if isAndroid then
	    if not event.isError then
	        if ( event.name == "init" ) then
		  	    native.showAlert( "Submit Event!", "Init call back", { "OK" } )
	            gpgs.login( { userInitiated=true, listener=initCallback } )
	 
	        elseif ( event.name == "login" ) then		
		  	    native.showAlert( "Submit Event!", "Login call back", { "OK" } )
	        end
	    else
	  	    native.showAlert( "Submit Event!", "Error in initcallback: "..event.name, { "OK" } )
	    end
	else 
		native.showAlert( "Submit Event!", "Now android: "..event.name, { "OK" } )
	end
end

function m.init()
	if m.didInit then
		return
	end

	m.didInit = true

	if isiOS then
		gameNetwork.init( "gamecenter", initCallback )
	elseif isAndroid then
		gpgs.init(initCallback)
	end
end

function m.setTopScore( score, leaderboardIndex )
	if isiOS then
		local categories = {
			"com.frikado.leaderboard.park",
			"com.frikado.leaderboard.room"
		}
		gameNetwork.request( "setHighScore", { localPlayerScore = { category=categories[leaderboardIndex], value=score }})
	elseif isAndroid then
		local function submitCallback(event) 
		    native.showAlert( "Submit Event!", "Set Top Score", { "OK" } )
		end
		gpgs.leaderboards.submit({
			leaderboardId = leaderboardIDs[leaderboardIndex],
			score = score,
			listener = submitCallback
			})
	end
end

function m.showLeaderboards()
	if isiOS then
		gameNetwork.show( "leaderboards" )
	elseif isAndroid then
		local function showCallback(event) 
		    native.showAlert( "Show Event!", "Show Leaderboard", { "OK" } )
		end

		gpgs.leaderboards.show({listener = showCallback})
	end
end

return m

I tried with Corona versions 3326 and 3441. It's happening with both.

I'm testing on a Galaxy S6 with Android 7.0; I also made sure to update Google Play Store Game Services form the play store before posting this. The device is not rooted.

 

I was initially signing with the app store key. After signing with the debug key I get the error saying:

attempt to call field 'init' (a nil value) // On the line where it says "gpgs.init(initCallback)" in the code above.

 

I went over the Google Play developer console requirements multiple times. Could anything related to that be causing the issue?

 
It's worth mentioning that in the build.settings file I have
       ["plugin.gpgs.v2"] =
        {
            publisherId = "com.coronalabs",
            supportedPlatforms = { android=true }
        },
 
Thank you for your help!


[TOPIC: post.html]
#6

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,147 posts
  • Corona SDK

You should not call .init() with GPGS v2. Please see:

 

https://coronalabs.com/blog/2018/10/31/update-on-the-new-gpgs-v2-plugin/

 

I'd make that change and see if the issue goes away.

 

Rob



[TOPIC: post.html]
#7

TawaNicolas

[GLOBAL: userInfoPane.html]
TawaNicolas
  • Observer

  • 17 posts
  • Corona SDK

Oh right, I removed that, and I get:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.ContextWrapper.getApplicationContext()' on a null object reference

On both lines that call:

gpgs.leaderboards.submit({

and

gpgs.leaderboards.show({listener = showCallback})


[TOPIC: post.html]
#8

Kirill Toporkov

[GLOBAL: userInfoPane.html]
Kirill Toporkov
  • Observer

  • 8 posts
  • Corona Staff

Hi! First of all, before calling any methods from the plugin check the connection state because the result of isConnected() method can be false and you probably will get this error. Second, if you didn't update your app at the https://play.google.com/apps/publish or at the https://console.developers.google.com/, or you didn't set up the project completely, the plugin will not allow you to call the methods.

Probably this would help you with debugging your application

function m.setTopScore( score, leaderboardIndex )
	if isiOS then
		local categories = {
			"com.frikado.leaderboard.park",
			"com.frikado.leaderboard.room"
		}
		gameNetwork.request( "setHighScore", { localPlayerScore = { category=categories[leaderboardIndex], value=score }})
	elseif isAndroid then
		local function submitCallback(event) 
		    native.showAlert( "Submit Event!", "Set Top Score", { "OK" } )
		end
		if gpgs.isConnected() then
			gpgs.leaderboards.submit({
				leaderboardId = leaderboardIDs[leaderboardIndex],
				score = score,
				listener = submitCallback
				})
		else
			native.showAlert('Is connected?', gpgs.isConnected() and 'Yes' or 'No', {'OK'})
		end
	end
end

function m.showLeaderboards()
	if isiOS then
		gameNetwork.show( "leaderboards" )
	elseif isAndroid then
		local function showCallback(event) 
		    native.showAlert( "Show Event!", "Show Leaderboard", { "OK" } )
		end
		if gpgs.isConnected() then
			gpgs.leaderboards.show({listener = showCallback})
		else
			native.showAlert('Is connected?', gpgs.isConnected() and 'Yes' or 'No', {'OK'})
		end
	end
end


[TOPIC: post.html]
#9

TawaNicolas

[GLOBAL: userInfoPane.html]
TawaNicolas
  • Observer

  • 17 posts
  • Corona SDK

Thanks for your reply Kirill, after trying your suggestion, I get the crash now on the line that calls this:

if gpgs.isConnected() then

I will go over the console stuff again.  :rolleyes:



[TOPIC: post.html]
#10

TawaNicolas

[GLOBAL: userInfoPane.html]
TawaNicolas
  • Observer

  • 17 posts
  • Corona SDK

Any updates?  :(



[TOPIC: post.html]
#11

Aarbron

[GLOBAL: userInfoPane.html]
Aarbron
  • Observer

  • 13 posts
  • Corona SDK

Hello guys!

I know you are super busy but there are some issues with gpgs v2.

 

I use gpgs for saving / loading players progress.

Everything is fine with the old plugin.

With the new plugin:

 

1. I don't see the welcome and chose account boxes the first time (or ever) the app starts. Is it normal?

2. If I delete / reinstall the game, I have to start the game twice until I get my progress back.

The first time fails to move to gpgsSnapshotOpenForReadListener function I guess.

Something wrong with my code?

 

I'm sorry, I don't have time right now for logs but maybe someone ( Mr. Rob Miracle :) ) could check my code.

  
-- build.settings
["plugin.gpgs.v2"] =
        {
            publisherId = "com.coronalabs",
            supportedPlatforms = { android=true }
        },

-- main.lua
gpgs = require( "plugin.gpgs.v2" )

-- menu.lua 
local function gpgsSnapshotOpenForReadListener( event ) 
    if not event.isError then 
        local readlevels = gpgs.snapshots.getSnapshot (event.snapshotId) 
        local prevlevels = json.decode( readlevels.contents.read() ) 
        if prevlevels == nil then 
            readlevels.contents.write( json.encode( makeallzero ) ) 
            gpgs.snapshots.save({ snapshotId = event.snapshotId, listener = gpgsSnapshotAfter }) 
        else 
            if prevlevels > nowlevels then 
                saveFile("nowlevels.txt", prevlevels) 
            end
        end
    end 
end 

local function gpgsLoginListener( event ) 
    gpgs.snapshots.open({ filename = "save1", 
    create = true, 
    listener = gpgsSnapshotOpenForReadListener }) 

    gpgs.snapshots.open({ filename = "save2", 
    create = true, 
    listener = gpgsSnapshotOpenForReadListener2 }) 
end 
gpgs.login( { userInitiated = true, listener = gpgsLoginListener } )




[TOPIC: post.html]
#12

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,147 posts
  • Corona SDK

I believe there were multiple ways to deal with snapshots in the V1 plugin, but for V2, those seem to be a bit more limited. Consider this code:

local myTable = { play = 1 }
local snapshotFilename = "snapshot1"
local data = json.encode( myTable )

local function gpgsSnapshotOpenForReadListener( event )
	print( "snapshot open event:", json.prettify(event) )
	if not event.isError then
		local data = event.snapshot.contents.read()
		native.showAlert('Snapshots', 'Reading was ' .. (event.isError and 'unsuccessful' or 'successful') .. ',', { 'OK'})
	end
end

local function gpgsSnapshotAfterSaveListener( event )
	native.showAlert('Snapshots', 'Saving was ' .. (event.isError and 'unsuccessful' or 'successful') .. '.', {'OK'})
end


function myData.openSnapshot()
	print("Opening snapshot")
	gpgs.snapshots.open({
		filename = snapshotFilename,
		listener = gpgsSnapshotOpenForReadListener
	})
end


local function gpgsSnapshotOpenForSaveListener( event )
	print("open for save listener", json.prettify( event ))
	if not event.isError then
		event.snapshot.contents.write(data) -- Write new data as a JSON string into the snapshot
		gpgs.snapshots.save({
			snapshot = event.snapshot,
			description = 'Save slot ' .. snapshotFilename,
			listener = gpgsSnapshotAfterSaveListener
		})
	end
end

function myData.saveSnapshot()
	print("saving snapshhot")
	gpgs.snapshots.open({ -- Open the save slot
		filename = snapshotFilename,
		create = true, -- Create the snapshot if it's not found
		listener = gpgsSnapshotOpenForSaveListener
	})
end

Try this method of reading/writing snapshots.

 

Rob




[topic_controls]
[/topic_controls]