├── settings.gradle ├── app ├── libs │ ├── slf4j-android-1.5.8.jar │ └── Java-WebSocket-1.5.2.jar ├── src │ └── main │ │ ├── res │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ ├── values-v21 │ │ │ └── styles.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ ├── layout │ │ │ └── main.xml │ │ └── drawable │ │ │ └── ic_launcher_background.xml │ │ ├── java │ │ └── com │ │ │ └── kdt │ │ │ └── mrpc │ │ │ ├── RPCCallback.java │ │ │ ├── RPCService.java │ │ │ ├── DiscordSocketClient.java │ │ │ └── MainActivity.java │ │ └── AndroidManifest.xml ├── proguard-rules.pro └── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .github └── workflows │ └── main.yml ├── .gitignore ├── README.md ├── gradlew └── LICENSE /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /app/libs/slf4j-android-1.5.8.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khanhduytran0/MRPC/HEAD/app/libs/slf4j-android-1.5.8.jar -------------------------------------------------------------------------------- /app/libs/Java-WebSocket-1.5.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khanhduytran0/MRPC/HEAD/app/libs/Java-WebSocket-1.5.2.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khanhduytran0/MRPC/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khanhduytran0/MRPC/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khanhduytran0/MRPC/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khanhduytran0/MRPC/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khanhduytran0/MRPC/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khanhduytran0/MRPC/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khanhduytran0/MRPC/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khanhduytran0/MRPC/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khanhduytran0/MRPC/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khanhduytran0/MRPC/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khanhduytran0/MRPC/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MRPC 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | -keepattributes SourceFile, LineNumberTable 2 | -renamesourcefileattribute SourceFile 3 | -repackageclasses 4 | -ignorewarnings 5 | -dontwarn 6 | -dontnote -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Sep 12 09:22:55 CEST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/java/com/kdt/mrpc/RPCCallback.java: -------------------------------------------------------------------------------- 1 | package com.kdt.mrpc; 2 | 3 | public interface RPCCallback 4 | { 5 | public static final int STATUS_CONNECTED = 1; 6 | public static final int STATUS_CLOSED = 1000; 7 | 8 | public void appendToLog(String line); 9 | public void onStatusChanged(int code, String reason, boolean remote); 10 | } 11 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Android CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | workflow_dispatch: 9 | 10 | jobs: 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: set up JDK 1.8 18 | uses: actions/setup-java@v1 19 | with: 20 | java-version: 1.8 21 | 22 | - name: Grant execute permission for gradlew 23 | run: chmod +x gradlew 24 | - name: Build with Gradle 25 | run: ./gradlew build 26 | - name: Upload APK 27 | uses: actions/upload-artifact@v2 28 | with: 29 | name: app-debug 30 | path: app/build/outputs/apk/debug/app-debug.apk 31 | 32 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 29 5 | 6 | 7 | defaultConfig { 8 | applicationId "com.kdt.mrpc" 9 | minSdkVersion 19 10 | targetSdkVersion 29 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | // https://mvnrepository.com/artifact/com.google.code.gson/gson 24 | implementation 'com.google.code.gson:gson:2.8.5' 25 | // implementation 'tech.gusavila92:java-android-websocket-client:1.2.2' 26 | implementation fileTree(dir: 'libs', include: ['*.jar']) 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 15 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 30 | 31 | 32 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.aar 4 | *.ap_ 5 | *.aab 6 | 7 | # Files for the ART/Dalvik VM 8 | *.dex 9 | 10 | # Java class files 11 | *.class 12 | 13 | # Generated files 14 | bin/ 15 | gen/ 16 | out/ 17 | # Uncomment the following line in case you need and you don't have the release build type files in your app 18 | # release/ 19 | 20 | # Gradle files 21 | .gradle/ 22 | build/ 23 | 24 | # Local configuration file (sdk path, etc) 25 | local.properties 26 | 27 | # Proguard folder generated by Eclipse 28 | proguard/ 29 | 30 | # Log Files 31 | *.log 32 | 33 | # Android Studio Navigation editor temp files 34 | .navigation/ 35 | 36 | # Android Studio captures folder 37 | captures/ 38 | 39 | # IntelliJ 40 | *.iml 41 | .idea/workspace.xml 42 | .idea/tasks.xml 43 | .idea/gradle.xml 44 | .idea/assetWizardSettings.xml 45 | .idea/dictionaries 46 | .idea/libraries 47 | # Android Studio 3 in .gitignore file. 48 | .idea/caches 49 | .idea/modules.xml 50 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 51 | .idea/navEditor.xml 52 | 53 | # Keystore files 54 | # Uncomment the following lines if you do not want to check your keystore files in. 55 | #*.jks 56 | #*.keystore 57 | 58 | # External native build folder generated in Android Studio 2.2 and later 59 | .externalNativeBuild 60 | .cxx/ 61 | 62 | # Google Services (e.g. APIs or Firebase) 63 | # google-services.json 64 | 65 | # Freeline 66 | freeline.py 67 | freeline/ 68 | freeline_project_description.json 69 | 70 | # fastlane 71 | fastlane/report.xml 72 | fastlane/Preview.html 73 | fastlane/screenshots 74 | fastlane/test_output 75 | fastlane/readme.md 76 | 77 | # Version control 78 | vcs.xml 79 | 80 | # lint 81 | lint/intermediates/ 82 | lint/generated/ 83 | lint/outputs/ 84 | lint/tmp/ 85 | # lint/reports/ 86 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MRPC 2 | Experimental Discord Mobile Rich Presence (Android) 3 | 4 | ## How does it work? 5 | It's pretty simple. 6 | - Connect to the [Discord Gateway](https://discord.com/developers/docs/topics/gateway) as a normal Discord Client. 7 | - Send [Identify](https://discord.com/developers/docs/topics/gateway#identifying) and [Update Presence](https://discord.com/developers/docs/topics/gateway#update-presence). 8 | 9 | ## Custom image support + gif 10 | MRPC now supports setting custom image through 2 links: 11 | - `https://media.discordapp.net` (resolves from `mp:path/to/image`) 12 | - `https://cdn.discordapp.com` (resolves from `../../path/to/image`) 13 | 14 | In late 2021(?), Discord allowed activity to specify media proxy image, which opens a way to set custom image. 15 | However, there is another trick that has not been used before: 16 | 17 | - By default, Discord parses the input as `application_assets` (unless it is set to media proxy with `mp:` prefix) 18 | - Setting the asset object to `test` results in `https://cdn.discordapp.com/app-assets/application-id/test.png` 19 | - It does not verify anything there. This way, we can put `../..` to escape the path, then we can set anything such as an animated emoji right here, finally `#` at the end to exclude `.png`. 20 | - Setting the asset object to `../../emojis/emoji-id.gif#` results in `https://cdn.discordapp.com/app-assets/application-id/../../emojis/emoji-id.gif#.png` which then gets resolved to `https://cdn.discordapp.com/emojis/emoji-id.gif` 21 | 22 | ## Notes 23 | - MRPC parses the image link automatically, so you just need to paste the link and it will work out of the box. You can only use image link from domains listed above. 24 | - Rate limiting is not yet handled. 25 | - This app uses the Discord Gateway instead of OAuth2 API (which I can't even find the documentation for the `activities.write` scope), so this might not be safe. Use this at your own risk. 26 | - Zlib compression is not yet used, due to the current using library doesn't correctly handle it(?). 27 | 28 | ## License 29 | [Apache License 2.0](https://github.com/khanhduytran0/MRPC/blob/main/LICENSE). 30 | 31 | ## Third party libraries and their licenses 32 | - [gson](https://github.com/google/gson): [Apache License 2.0](https://github.com/google/gson/blob/master/LICENSE). 33 | - [Java-WebSocket](https://github.com/TooTallNate/Java-WebSocket): [MIT License](https://github.com/TooTallNate/Java-WebSocket/blob/master/LICENSE). 34 | - [slf4j-android](https://github.com/twwwt/slf4j): [MIT License](https://github.com/twwwt/slf4j/blob/master/LICENSE.txt). 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 |