Conversation
…otlin) Replace Discord Social SDK native C++/JNI integration with the Discord-OAuth2-RPC Kotlin library that connects to Discord Gateway WebSocket directly via OAuth2 bearer token. Changes: - Add GatewayClient, RichPresence builder, and supporting utils from Discord-OAuth2-RPC library (com.discord.oauth2rpc package) - Create DiscordOAuth2RPCClient replacing DiscordSocialPresenceClient and DiscordSocialNativeBridge JNI layer - Remove native C++ bridge (discord_social_bridge.cpp, CMakeLists.txt) - Remove DiscordSocialSdkAndroidInitializer (reflection-based SDK init) - Remove discord_partner_sdk.aar dependency and CMake build config - Keep existing DiscordRPC.kt high-level logic, DiscordPresenceModels, DiscordOAuthRepository, and OAuth callback unchanged
…blic/private methods - updatePresence() held mutex then called connect() which tried to re-acquire the same non-reentrant Mutex — caused JobCancellationException - Split into connect() (public, with lock) → connectInternal() (private, no lock) - Removed superfluous scope.launch + CompletableDeferred wrapper; gws.connect() already suspends until READY - Removed unused scope/connectJob members
- Removed -keep rules for com.discord.socialsdk.** and DiscordSocialNativeBridge - Removed -dontwarn for com.discord.socialsdk.** These classes no longer exist after the Social SDK→Gateway RPC migration
…oes not hang forever
…g to connect flow
…with log filtering
…e stops the loop instead of retrying
Code Review SummaryStatus: Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)CRITICAL
WARNING
Other Observations (not in diff)No issues found in unchanged code. Files Reviewed (11 files)
|
| forceClose(4000, "server reconnect") | ||
| } | ||
| GatewayOp.INVALID_SESSION -> { | ||
| val resumable = d?.jsonPrimitive?.boolean ?: false |
There was a problem hiding this comment.
WARNING: INVALID_SESSION payload parsing could fail silently
Discord sends d as a boolean primitive (true/false) for INVALID_SESSION, but the code uses d?.jsonPrimitive?.boolean. If d is not a JsonPrimitive (e.g., null or malformed), this could throw or return incorrect values. Consider adding explicit type checking: d?.jsonPrimitive?.booleanOrNull ?: false
| fun getSession(): SessionState? = sessionState?.copy() | ||
|
|
||
| suspend fun connect(opts: GatewayConnectOptions) { | ||
| if (wsSession != null) throw IllegalStateException("GatewayClient already connected") |
There was a problem hiding this comment.
WARNING: Potential race condition in connect()
While connect() checks wsSession != null at the start, multiple coroutine contexts could pass this check before either sets wsSession, potentially creating duplicate WebSocket sessions. Though the mutex in DiscordOAuth2RPCClient.connectInternal provides some protection, consider adding synchronization within GatewayClient.connect() itself for robustness.
Code Review SummaryStatus: No Issues Found | Recommendation: Merge All previously reported issues have been addressed in this incremental diff:
Files Reviewed (2 files)
Reviewed by laguna-m.1-20260312:free · 147,080 tokens |
… flow — kills scope mid-Gateway-connect when player is briefly not READY
…ing, discarded replace results
Summary
Eliminates the dependency on Discord's proprietary Social SDK (C++ native library + JNI bridge) by replacing it with a pure Kotlin implementation that connects directly to the Discord Gateway WebSocket using an OAuth2 bearer token. The Discord-OAuth2-RPC library handles the WebSocket lifecycle, heartbeats, and presence updates without any native code.
Motivation
discord_partner_sdk.aar, which is partner-only and requires manual approval from DiscordChanges
Added
com.discord.oauth2rpclibrary package (Gateway WebSocket client, RichPresence builder, bitfield utilities)DiscordOAuth2RPCClient— singleton gateway client mappingDiscordPresenceActivity→ GatewayPRESENCE_UPDATE(opcode 3)Modified
DiscordRPC.kt— delegates toDiscordOAuth2RPCClientinstead ofDiscordSocialPresenceClientDiscordPresenceManager.kt— removedcallbacksJobloop (no longer needed; Gateway handles heartbeats internally)MainActivity.kt— removedDiscordSocialSdkAndroidInitializer.setEngineActivity()callsapp/build.gradle.kts— removed CMake/native build config, removeddiscord_partner_sdk.aardependencyRemoved
DiscordSocialNativeBridge.kt— JNIexternal fundeclarations and native library loaderDiscordSocialPresenceClient.kt— mutex-guarded presence client wrapping the native bridgeDiscordSocialSdkAndroidInitializer.kt— reflection-basedsetEngineActivity()for Social SDKdiscord_social_bridge.cpp— 461-line C++ JNI implementationapp/src/main/cpp/CMakeLists.txt— CMake build definitionUnchanged
DiscordPresenceModels.kt,DiscordOAuthRepository.kt,DiscordOAuthCallbackActivity.kt— same data models and OAuth flowDiscordImageResolver.kt,DiscordSettings.kt,DiscordExperimental.kt— UI and image caching unchangedArchitecture Comparison
runCallbacks()loop