UNPKG

cordova-plugin-gpgs

Version:

Modern Cordova plugin for Google Play Games Services v2 API with comprehensive gaming features

443 lines (369 loc) 10.8 kB
# Google Play Games Services Plugin for Cordova A modern Cordova plugin for Google Play Games Services v2 API with comprehensive gaming features. ## Features - **Authentication** - Manual silent sign-in via initialize() - Background sign-out detection - Manual sign-in support - Sign-in state events - Modern v2 authentication flow - **Leaderboards** - Submit scores - Show leaderboards - Get player scores - Get player rankings - **Achievements** - Unlock achievements - Increment achievements - Show achievements UI - Reveal hidden achievements - Set achievement steps - Load all achievements - **Cloud Saves** - Save game data - Load game data - Show saved games UI - Conflict resolution - Snapshot management - Delete a snapshot - Load all snapshots - **Friends** - Get friends list - Show player profiles - Player search - Compare profiles - **Player Stats** - Get player info - Get player stats - Get player level info - **Events** - Increment events - Get event data - Get all events - Event tracking ## Requirements - Cordova >= 12.0.0 - Cordova Android >= 14.0.0 - Android SDK >= 24 - Google Play Services >= 21.2.0 ## Installation ```bash cordova plugin add cordova-plugin-gpgs --variable APP_ID="your-app-id" --variable PLAY_SERVICES_VERSION="23.2.0" ``` ### Configuration Variables - `APP_ID` (required): Your Google Play Games App ID - `PLAY_SERVICES_VERSION` (optional): Version of Google Play Services to use (default: 23.2.0) ## Configuration Add the following to your `config.xml`: ```xml <preference name="GPGS_DEBUG" value="true" /> ``` ## Usage ### Initialization Call `initialize()` once after `deviceready`. It performs a silent sign-in and fires the usual events (`gpgs.signin`, `gpgs.signout`, `gpgs.availability`). All Play Games API calls that require authentication should be made after the `gpgs.signin` event has fired. ```javascript document.addEventListener('deviceready', () => { GPGS.initialize() .then(() => { console.log('GPGS initialization request sent'); }) .catch(console.error); }); ``` The plugin NO LONGER attempts silent sign-in automatically; you are in full control of when the operation happens. ### Authentication ```javascript // Check if Google Play Services are available GPGS.isGooglePlayServicesAvailable().then(result => { if (result === true) { console.log('Google Play Services are available'); } else if (typeof result === 'object') { console.log('Google Play Services are not available:', result.errorString); if (result.isUserResolvable) { // Show UI to help user resolve the issue } } }); // Returns: Promise<boolean|Object> - If services are not available, returns an object with: // { // available: false, // errorCode: number, // errorString: string, // isUserResolvable: boolean // } // Check if user is signed in GPGS.isSignedIn().then(result => { if (typeof result === 'object') { console.log('Sign-in status:', result.isSignedIn); } else { console.log('Sign-in status:', result); } }); // Returns: Promise<boolean|Object> - Returns either a boolean or an object with: // { // isSignedIn: boolean // } // Manual sign-in GPGS.login().then(() => { console.log('Sign-in successful'); }).catch(error => { console.error('Sign-in failed:', error); }); // Returns: Promise<void> ``` ### Leaderboards ```javascript // Submit a score GPGS.submitScore('leaderboard_id', 1000).then(() => { console.log('Score submitted'); }); // Returns: Promise<void> // Show a leaderboard GPGS.showLeaderboard('leaderboard_id').then(() => { console.log('Leaderboard shown'); }); // Returns: Promise<void> // Show all leaderboards GPGS.showAllLeaderboards().then(() => { console.log('All leaderboards shown'); }); // Returns: Promise<void> // Get player's score GPGS.getPlayerScore('leaderboard_id').then(score => { console.log('Player score:', score); }); // Returns: Promise<{ // player_score: number, // player_rank: number // }> // --- Parameter enums ------------------------------------------------------ // timeSpan → 0 = daily, 1 = weekly, 2 = all-time // collection → 0 = public, 1 = friends // For richer code samples see: examples/scores.md // Load top scores for a leaderboard GPGS.loadTopScores('leaderboard_id', 2 /*all-time*/, 0 /*public*/, 25).then(result => { console.log('Leaderboard:', result.leaderboard); console.log('Scores:', result.scores); }); // Returns: Promise<Object> // ------------------------------------------------------------------------- // See examples/scores.md for showing a leaderboard slice around the player // Load scores centered around the signed-in player GPGS.loadPlayerCenteredScores('leaderboard_id', 2 /*all-time*/, 0 /*public*/, 25).then(result => { console.log('Leaderboard:', result.leaderboard); console.log('Scores:', result.scores); }); // Returns: Promise<Object> // Load metadata for a single leaderboard GPGS.loadLeaderboardMetadata('leaderboard_id').then(metadata => { console.log('Leaderboard Metadata:', metadata); }); // Returns: Promise<Object> // Load metadata for all leaderboards GPGS.loadLeaderboardMetadata().then(metadata => { console.log('All Leaderboards Metadata:', metadata); }); // Returns: Promise<Array<Object>> ``` ### Achievements ```javascript // Unlock an achievement GPGS.unlockAchievement('achievement_id').then(() => { console.log('Achievement unlocked'); }); // Returns: Promise<void> // Increment an achievement GPGS.incrementAchievement('achievement_id', 1).then(() => { console.log('Achievement incremented'); }); // Returns: Promise<void> // Show achievements UI GPGS.showAchievements().then(() => { console.log('Achievements UI shown'); }); // Returns: Promise<void> // Reveal a hidden achievement GPGS.revealAchievement('achievement_id').then(() => { console.log('Achievement revealed'); }); // Returns: Promise<void> // Set achievement steps GPGS.setStepsInAchievement('achievement_id', 5).then(() => { console.log('Achievement steps set'); }); // Returns: Promise<void> // Load all achievements GPGS.loadAchievements(false).then(achievements => { console.log('Achievements:', achievements); }); // Returns: Promise<Array<Object>> // Get friends list GPGS.getFriendsList().then(friends => { console.log('Friends:', friends); }); // Returns: Promise<Array<{ // id: string, // displayName: string // }>> // Show player profile GPGS.showPlayerProfile('player_id').then(() => { console.log('Player profile shown'); }); // Returns: Promise<void> // Show player search GPGS.showPlayerSearch().then(() => { console.log('Player search shown'); }); // Returns: Promise<void> ``` ### Cloud Saves ```javascript // Save game data GPGS.saveGame('save_name', 'description', { level: 1, score: 1000 }).then(() => { console.log('Game saved'); }); // Returns: Promise<void> // Load game data GPGS.loadGame('save_name').then(data => { console.log('Game loaded:', data); }); // Returns: Promise<Object> - The saved game data // Show saved games UI GPGS.showSavedGames({ title: 'Saved Games', allowAddButton: true, allowDelete: true, maxSnapshots: 5 }).then(() => { console.log('Saved games UI shown'); }); // Returns: Promise<void> // Delete a snapshot GPGS.deleteSnapshot('save_name').then(snapshotId => { console.log('Snapshot deleted:', snapshotId); }); // Returns: Promise<string> // Load all snapshots GPGS.loadAllSnapshots(false).then(snapshots => { console.log('All snapshots:', snapshots); }); // Returns: Promise<Array<Object>> ``` ### Player Stats ```javascript // Get player info GPGS.getPlayerInfo('player_id', true).then(info => { console.log('Player info:', info); }); // Returns: Promise<{ // id: string, // displayName: string, // title: string, // levelInfo?: { // currentLevel: number, // maxXp: number, // minXp: number // } // }> // Get player stats GPGS.getPlayerStats().then(stats => { console.log('Player stats:', stats); }); // Returns: Promise<{ // averageSessionLength: number, // daysSinceLastPlayed: number, // numberOfPurchases: number, // numberOfSessions: number, // sessionPercentile: number, // spendPercentile: number, // spendProbability: number // }> ``` ### Events ```javascript // Increment an event GPGS.incrementEvent('event_id', 1).then(() => { console.log('Event incremented'); }); // Returns: Promise<void> // Get all events GPGS.getAllEvents().then(events => { console.log('All events:', events); }); // Returns: Promise<Array<{ // id: string, // name: string, // description: string, // value: number // }>> // Get specific event GPGS.getEvent('event_id').then(event => { console.log('Event:', event); }); // Returns: Promise<{ // id: string, // name: string, // description: string, // value: number // }> ``` ## Events The plugin emits the following events: ### `gpgs.signin` Emitted when sign-in state changes. ```javascript { isSignedIn: boolean, error?: string // Present if sign-in failed } ``` ### `gpgs.signout` Emitted when user signs out (including background sign-out). ```javascript { isSignedIn: false, reason: string // e.g., "background_signout" } ``` ### `gpgs.availability` Emitted when Google Play Services availability changes. ```javascript { available: boolean, errorCode?: number, errorString?: string, isUserResolvable?: boolean } ``` ## Error Handling The plugin uses promises for all operations. Errors are passed to the catch handler: ```javascript GPGS.login().catch(error => { console.error('Error:', error.message, 'Status Code:', error.statusCode); }); ``` The error object contains: - `message`: A descriptive error message - `statusCode`: The status code from the underlying Google Play Games SDK (if available) Common error codes from the SDK can be found in the official documentation. ## Debug Mode Enable debug mode in `config.xml` to see detailed logs: ```xml <preference name="GPGS_DEBUG" value="true" /> ``` ## License This project is licensed under the GPL-3.0-or-later License - see the [LICENSE](LICENSE) file for details. ## Author Exelerus AB - [https://exelerus.com](https://exelerus.com) ## Contributing 1. Fork the repository 2. Create your feature branch (`git checkout -b feature/amazing-feature`) 3. Commit your changes (`git commit -m 'Add some amazing feature'`) 4. Push to the branch (`git push origin feature/amazing-feature`) 5. Open a Pull Request ## Examples - [Listening to sign-in events](examples/events.md) - [Working with leaderboards & scores](examples/scores.md)