Таблица лидеров Google Play Games не обновляется для новых игроков Android (Flutter + Flame)Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Таблица лидеров Google Play Games не обновляется для новых игроков Android (Flutter + Flame)

Сообщение Anonymous »

У меня возникла проблема со списками лидеров Google Play Games в созданной мною игре Flutter + Flame, и я не могу понять, в чем дело.
Среда
  • Flutter
  • Flame
  • games_services: ^4.1.1
  • Android и iOS собирает
  • Игровые сервисы Google Play (новый API v2)
Настройка Android
В pubspec.yaml:

Код: Выделить всё

dependencies:
games_services: ^4.1.1
В android/app/build.gradle:

Код: Выделить всё

dependencies {
implementation "com.google.android.gms:play-services-games-v2:+"
implementation "com.google.android.gms:play-services-auth:21.3.0"
implementation "com.google.android.play:integrity:1.6.0"
}
Настройка консоли Google Play:
  • Включены игровые сервисы Play
  • Таблица лидеров создана и опубликована
  • Связан проект Google Cloud
  • Учетные данные OAuth настроены
  • Приложение подписано и загружено правильно
  • Внутреннее/производственное тестирование работает
Класс Dart, где Я реализовал связь с игровым сервисом:

Код: Выделить всё

import 'dart:async';
import 'package:games_services/games_services.dart';
import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'game_data.dart'; // Import your GameData class

class GamesServicesController {
// Your leaderboard IDs
static const String iosLeaderboardId = [iosLeaderboardId];
static const String androidLeaderboardId = [androidLeaderboardId];

// Migration tracking key
static const String _migrationCompleteKey = 'score_migration_complete';

static final GamesServicesController _instance = GamesServicesController._internal();
factory GamesServicesController() => _instance;
GamesServicesController._internal();

bool _signedIn = false;
bool _isInitialized = false;

// Public getters
bool get signedIn => _signedIn;
bool get isInitialized => _isInitialized;

/// Initialize games services - call this once at app startup
Future initialize() async {
if (_isInitialized) return;

try {
debugPrint('Initializing Games Services...');
await GamesServices.signIn();
_signedIn = await GamesServices.isSignedIn;
debugPrint('Games Services signed in: $_signedIn');

// If signed in successfully, sync cloud score and migrate if needed
if (_signedIn) {
await syncCloudScoreToLocal();
await _migrateOfflineScoreIfNeeded();
}
} on Exception catch (e) {
debugPrint('Games Services initialization failed: $e');
_signedIn = false;
}

_isInitialized = true;
}

/// Sync cloud score down to local storage
Future syncCloudScoreToLocal() async {
if (!_signedIn) {
debugPrint('Cannot sync cloud score - not signed in');
return;
}

try {
// Get the player's score from the cloud
int? cloudScore = await GamesServices.getPlayerScore(
iOSLeaderboardID: iosLeaderboardId,
androidLeaderboardID: androidLeaderboardId,
);

if (cloudScore != null && cloudScore > 0) {
// Get local score
final localScore = await GameData.getBestScore();

// If cloud score is higher, update local score
if (cloudScore > localScore) {
debugPrint('Syncing cloud score ($cloudScore) to local storage (was $localScore)');
await GameData.saveBestScore(cloudScore);
}
}
} on Exception catch (e) {
debugPrint('Failed to sync cloud score to local: $e');
}
}

/// Migrate offline score to online leaderboard (one-time operation)
Future _migrateOfflineScoreIfNeeded() async {
try {
final prefs = await SharedPreferences.getInstance();
final migrationComplete = prefs.getBool(_migrationCompleteKey) ?? false;

if (migrationComplete) {
debugPrint('Score migration already completed');
return;
}

final offlineBestScore = await GameData.getBestScore();

if (offlineBestScore >  0) {
debugPrint('Migrating offline score: $offlineBestScore');

// Submit the offline score to the leaderboard
await GamesServices.submitScore(
score: Score(
iOSLeaderboardID: iosLeaderboardId,
androidLeaderboardID: androidLeaderboardId,
value: offlineBestScore,
),
);

debugPrint('Offline score migrated successfully');
}

// Mark migration as complete
await prefs.setBool(_migrationCompleteKey, true);

} on Exception catch (e) {
debugPrint('Failed to migrate offline score: $e');
// Don't mark as complete if migration failed
}
}

/// Submit score to leaderboard (enhanced version)
Future submitScore(int score) async {
// Only submit if signed in
if (_signedIn) {
try {
int? onlinePlayerScore = await GamesServices.getPlayerScore(
iOSLeaderboardID: iosLeaderboardId,
androidLeaderboardID: androidLeaderboardId,
);

if (onlinePlayerScore == null || score > onlinePlayerScore) {
await GamesServices.submitScore(
score: Score(
iOSLeaderboardID: iosLeaderboardId,
androidLeaderboardID: androidLeaderboardId,
value: score,
),
);
}
} on Exception catch (e) {
debugPrint('Failed to submit score online: $e');
}
}
}

/// Show the platform's leaderboard UI
Future showLeaderboard() async {
if (!_signedIn) {
debugPrint('Cannot show leaderboard - not signed in to Games Services');
return;
}

try {
// Sync with a timeout to avoid long delays
await forceSyncOfflineScore().timeout(
const Duration(seconds: 2),
onTimeout: () {
debugPrint('Score sync timed out, showing leaderboard anyway');
},
);

await GamesServices.showLeaderboards(
iOSLeaderboardID: iosLeaderboardId,
androidLeaderboardID: androidLeaderboardId,
);
} on Exception catch (e) {
debugPrint('Failed to show leaderboard: $e');
}
}

/// Sign in manually (if auto sign-in failed)
Future signIn() async {
try {
await GamesServices.signIn();
_signedIn = await GamesServices.isSignedIn;

// If sign-in successful, sync cloud score and try migration
if (_signedIn) {
await syncCloudScoreToLocal();
await _migrateOfflineScoreIfNeeded();
}

return _signedIn;
} on Exception catch (e) {
debugPrint('Manual sign-in failed: $e');
return false;
}
}

/// Force sync offline scores (useful for debugging or manual sync)
Future forceSyncOfflineScore() async {
if (!_signedIn) {
debugPrint('Cannot sync - not signed in');
return;
}

final offlineBestScore = await GameData.getBestScore();
if (offlineBestScore > 0) {
await submitScore(offlineBestScore);
}
}

/// Reset migration flag (for testing purposes)
Future  resetMigrationFlag() async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove(_migrationCompleteKey);
debugPrint('Migration flag reset');
}
}
На Android существующие игроки, уже присутствующие в таблице лидеров, могут:
  • Отправлять результаты
  • Правильно обновлять свой лучший результат
На iOS все работает как положено:
  • В таблице лидеров появляются как новые, так и существующие игроки
  • Результаты загружаются правильно
Проблема
Только на Android:
Новые игроки (которые никогда раньше не были в таблице лидеров):
  • Могут играть в игру
  • Могут набирать высокие баллы (даже выше, чем существующие игроки)
Но их результаты никогда не появляются в таблице лидеров!
Существующие игроки Android продолжают нормально обновлять свои результаты.
Я действительно запутался, потому что, если бы это была проблема с кодом, существующие проигрыватели Android также должны были выйти из строя, или iOS должна показать ту же проблему.
Если интеграция Google Cloud / Play Games была нарушена, результаты не должны загружаться ни для кого.
Но вместо этого это касается только новых пользователей Android.
Что может привести к тому, что таблицы лидеров Google Play Games на Android будут приняты оценивать материалы существующих игроков и молча игнорировать или не отображать результаты новых игроков?
Будем очень признательны за любые идеи или советы по отладке.

Подробнее здесь: https://stackoverflow.com/questions/798 ... flutter-fl
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»