A Minecraft Fabric mod that connects the game with ATProtocol ⛏️
8
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: wire PlayerProfileService to syncPreferencesStore

Profile records are identity declarations rather than data sync, so
only skip syncing when the player has disabled ALL four categories.
Also updates the class docstring to reference PlayerSyncPreferencesStore
instead of the old PlayerIdentityStore consent fields.

+16 -4
+1
src/main/kotlin/com/jollywhoppers/Atprotoconnect.kt
··· 121 121 recordManager = recordManager, 122 122 sessionManager = sessionManager, 123 123 identityStore = identityStore, 124 + syncPreferencesStore = syncPreferencesStore, 124 125 ) 125 126 logger.info("Player profile service initialized") 126 127
+15 -4
src/main/kotlin/com/jollywhoppers/atproto/server/PlayerProfileService.kt
··· 18 18 * When a player links their identity, this service creates or updates their 19 19 * `com.jollywhoppers.minecraft.player.profile` record with the `literal:self` rkey. 20 20 * 21 - * Note: AT Protocol data is always public. Sync consent (syncStats, syncSessions) 22 - * is stored locally in PlayerIdentityStore and controls whether data is written 23 - * at all — it is NOT included in the profile record since it would give a false 24 - * sense of privacy control. 21 + * Note: AT Protocol data is always public. Sync consent is stored locally 22 + * in PlayerSyncPreferencesStore and controls whether data is written at all — 23 + * it is NOT included in the profile record since it would give a false sense 24 + * of privacy control. 25 25 */ 26 26 class PlayerProfileService( 27 27 private val recordManager: RecordManager, 28 28 private val sessionManager: AtProtoSessionManager, 29 29 private val identityStore: PlayerIdentityStore, 30 + private val syncPreferencesStore: PlayerSyncPreferencesStore, 30 31 ) { 31 32 private val logger = LoggerFactory.getLogger("atproto-connect:profile") 32 33 private val coroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob()) ··· 62 63 63 64 if (!sessionManager.hasSession(playerUuid)) { 64 65 logger.warn("Cannot sync profile: player $playerUuid has no active session") 66 + return@launch 67 + } 68 + 69 + // Profile records are identity declarations, not data sync. 70 + // Only skip if the player has explicitly disabled ALL sync categories. 71 + val prefs = syncPreferencesStore.getOrDefault(playerUuid) 72 + if (!prefs.syncStatsEnabled && !prefs.syncSessionsEnabled 73 + && !prefs.syncAchievementsEnabled && !prefs.syncServerStatusEnabled 74 + ) { 75 + logger.debug("Skipping profile sync for $playerUuid: all sync categories disabled") 65 76 return@launch 66 77 } 67 78