Files
rr3-ota/INTEGRATION-GUIDE.md
ssfdre38 0daa89e935 Fix critical version code formula bug
Changed formula from (major*100000 + minor*1000 + patch) to the correct
(major*10000 + minor*100 + patch) to match UpdateManager.smali implementation.

Updated all examples:
- 14.5.0 = 140500 (0x224D4) not 145000
- Corrected hex values throughout documentation

This bug would have prevented OTA updates from working correctly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-24 22:32:41 -08:00

11 KiB

🔧 RR3 OTA Integration Guide

Step-by-step guide to integrate the OTA update system into any RR3 APK


📋 Prerequisites

Tools Needed

  • apktool - For decompiling/recompiling APKs
  • Java JDK 8+ - For compiling Java to class files
  • dx tool (Android SDK) - For converting class to dex
  • baksmali/smali - For dex to smali conversion
  • zipalign - For optimizing APK
  • apksigner - For signing APK
  • Text editor - For editing files

Install Tools

# apktool
wget https://github.com/iBotPeaches/Apktool/releases/latest/download/apktool.jar

# Android SDK (includes dx, zipalign, apksigner)
# Download from: https://developer.android.com/studio

# baksmali/smali
wget https://github.com/JesusFreke/smali/releases/latest/download/baksmali.jar
wget https://github.com/JesusFreke/smali/releases/latest/download/smali.jar

🎯 Integration Steps

Step 1: Decompile Your APK

# Decompile RR3 APK
apktool d your-rr3.apk -o rr3-decompiled

cd rr3-decompiled

Output structure:

rr3-decompiled/
├── AndroidManifest.xml
├── smali/
├── assets/
├── res/
└── ...

Step 2: Add UpdateManager

Option A: Use Precompiled Smali (Easier)

# Create directory
mkdir -p smali/com/community

# Copy UpdateManager.smali
cp /path/to/rr3-ota/UpdateManager.smali smali/com/community/

Option B: Compile from Java (More Control)

# Compile Java to class
javac -source 1.8 -target 1.8 \
    -cp android.jar:org.json.jar \
    UpdateManager.java

# Convert class to dex
dx --dex --output=UpdateManager.dex UpdateManager.class

# Convert dex to smali
baksmali d UpdateManager.dex -o smali-output

# Copy to APK
mkdir -p smali/com/community
cp smali-output/com/community/UpdateManager.smali smali/com/community/

Important: Update Version Constants

Edit smali/com/community/UpdateManager.smali:

Find these lines:

.field private static final CURRENT_VERSION:Ljava/lang/String; = "15.0.0-community-alpha"

.field private static final CURRENT_VERSION_CODE:I = 0x249f0

Change to your version:

.field private static final CURRENT_VERSION:Ljava/lang/String; = "14.5.0"  # Your version

.field private static final CURRENT_VERSION_CODE:I = 0x224D4  # 140500 in hex

Calculate version code:

versionCode = (major * 10000) + (minor * 100) + patch

Examples:
14.5.0 → 140500 → 0x224D4 (hex)
15.0.0 → 150000 → 0x249F0 (hex)

# Convert to hex: printf '%x\n' 140500

Update Manifest URL

Find this line:

.field private static final UPDATE_API_URL:Ljava/lang/String; = "https://raw.githubusercontent.com/project-real-resurrection-3/rr3-releases/main/versions.json"

Change to your manifest URL:

.field private static final UPDATE_API_URL:Ljava/lang/String; = "https://raw.githubusercontent.com/YOUR-ORG/YOUR-REPO/main/versions.json"

Step 3: Add HTML UI

# Copy update checker HTML
cp /path/to/rr3-ota/community_update_checker.html assets/

Verify placement:

assets/
└── community_update_checker.html

Step 4: Add Permissions

Edit AndroidManifest.xml:

<manifest>
    <!-- Add these permissions -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" 
        android:maxSdkVersion="32" />
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
    
    <!-- Rest of manifest -->
</manifest>

Step 5: Integrate into Your UI

You need to add a button/menu item that triggers the update checker.

Example: Add to Main Menu WebView

Find your main menu HTML file (usually in assets/):

# Search for HTML files
find assets/ -name "*.html" | grep -i menu

Add update button:

<!-- Add to your menu -->
<button onclick="checkForUpdates()" class="menu-button">
    🔄 Check for Updates
</button>

<script>
function checkForUpdates() {
    window.location.href = 'file:///android_asset/community_update_checker.html';
}
</script>

Add WebView Bridge

Find the Activity that creates your WebView (in smali/):

Common locations:

  • smali/com/ea/games/*/MainActivity.smali
  • smali/com/ea/games/*/WebViewActivity.smali

Find where WebView is created:

# Look for this pattern
new-instance v0, Landroid/webkit/WebView;
invoke-direct {v0, p0}, Landroid/webkit/WebView;-><init>(Landroid/content/Context;)V

Add JavaScript interface after WebView creation:

# Create UpdateManager instance
new-instance v1, Lcom/community/UpdateManager;
move-object v2, p0  # context
invoke-direct {v1, v2}, Lcom/community/UpdateManager;-><init>(Landroid/content/Context;)V

# Add as JavaScript interface
const-string v2, "UpdateManager"
invoke-virtual {v0, v1, v2}, Landroid/webkit/WebView;->addJavascriptInterface(Ljava/lang/Object;Ljava/lang/String;)V

Step 6: Recompile APK

# Build APK
apktool b rr3-decompiled -o rr3-modified-unsigned.apk

# Zipalign
zipalign -p -f -v 4 rr3-modified-unsigned.apk rr3-modified-aligned.apk

# Sign APK (create keystore if needed)
# Create keystore (first time only):
keytool -genkey -v -keystore rr3.keystore -alias rr3-key -keyalg RSA -keysize 2048 -validity 10000

# Sign
apksigner sign --ks rr3.keystore --ks-key-alias rr3-key \
    --out rr3-modified-signed.apk \
    rr3-modified-aligned.apk

# Verify signature
apksigner verify rr3-modified-signed.apk

Final APK: rr3-modified-signed.apk


Step 7: Test Installation

# Install on device
adb install rr3-modified-signed.apk

# Or manually:
# 1. Transfer APK to device
# 2. Enable "Install from Unknown Sources"
# 3. Tap APK to install

🧪 Testing the Integration

Test 1: WebView Bridge

Open your app and run in Android Studio logcat:

adb logcat | grep UpdateManager

Expected: Should see UpdateManager logs when app starts.

Test 2: UI Button

  1. Open your modified menu
  2. Click "Check for Updates" button
  3. Should navigate to update checker page

If it doesn't work:

  • Check assets/community_update_checker.html exists
  • Verify path: file:///android_asset/community_update_checker.html

Test 3: Update Check

  1. Click "Check for Updates" in the UI
  2. Watch logcat: adb logcat | grep UpdateManager

Expected logs:

I/UpdateManager: Checking for updates from manifest...
I/UpdateManager: No update available

Or if update exists:

I/UpdateManager: Update available: 15.1.0

Test 4: Download

  1. Create a test release on GitHub
  2. Update your versions.json manifest
  3. Check for updates in app
  4. Click "Download Update"
  5. Verify download starts

🐛 Troubleshooting

Issue: "Class not found: UpdateManager"

Cause: UpdateManager.smali not in correct location

Fix:

# Verify file exists
ls -la smali/com/community/UpdateManager.smali

# Should be:
# smali/com/community/UpdateManager.smali
# NOT: smali/UpdateManager.smali

Issue: "JavaScript interface not found"

Cause: WebView bridge not added or incorrect

Fix:

  • Verify you added the JavaScript interface code
  • Check the interface name matches: "UpdateManager"
  • Make sure it's added BEFORE WebView loads content

Issue: "Update check returns error"

Cause: Manifest URL incorrect or not accessible

Fix:

# Test manifest URL manually
curl https://raw.githubusercontent.com/YOUR-ORG/YOUR-REPO/main/versions.json

# Should return JSON, not 404

Issue: "Version code mismatch"

Cause: Incorrect version code calculation

Fix:

# Calculate version code
echo "scale=0; (14*10000) + (5*100) + 0" | bc
# Result: 140500

# Convert to hex
printf '%x\n' 140500
# Result: 224d4

# Update in smali:
.field private static final CURRENT_VERSION_CODE:I = 0x23ab8

Issue: "APK won't install"

Cause: Signature mismatch or corrupted APK

Fix:

# Verify APK
apksigner verify rr3-modified-signed.apk

# If invalid, rebuild and re-sign
apktool b rr3-decompiled -o new.apk
zipalign -p 4 new.apk aligned.apk
apksigner sign --ks rr3.keystore aligned.apk

📱 Platform-Specific Notes

Android 11+ (API 30+)

File access changes: Need to use scoped storage

In UpdateManager.smali, update download destination:

// Old (doesn't work on Android 11+):
Environment.DIRECTORY_DOWNLOADS

// New (works on all versions):
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)

Android 8+ (API 26+)

Install unknown apps permission required

Add to AndroidManifest.xml:

<application>
    <activity android:name=".MainActivity">
        <!-- Add this -->
        <meta-data
            android:name="android.app.install_package"
            android:value="true" />
    </activity>
</application>

🔐 Security Checklist

Before releasing:

  • Version constants updated
  • Manifest URL points to your repository
  • APK signed with your keystore (not debug key!)
  • Permissions added to AndroidManifest.xml
  • SHA-256 checksums in manifest (optional but recommended)
  • HTTPS used for all URLs
  • Tested on multiple Android versions

📊 Version Manifest Setup

After integration, you need a manifest:

1. Create GitHub Repository

# Create releases repository
gh repo create YOUR-ORG/rr3-releases --public

2. Create versions.json

{
  "schema_version": 1,
  "last_updated": "2026-02-24T00:00:00Z",
  "channels": {
    "stable": {
      "description": "Stable releases",
      "latest": "14.5.0"
    }
  },
  "versions": [
    {
      "version": "14.5.0",
      "version_code": 140500,
      "channel": "stable",
      "release_date": "2026-02-24",
      "min_android": 21,
      "target_android": 33,
      "download_url": "https://github.com/YOUR-ORG/rr3-releases/releases/download/v14.5.0/RR3-v14.5.0.apk",
      "file_size": 230000000,
      "sha256": "your-sha256-here",
      "changelog": "## What's New\n- Your changelog here",
      "upgrade_from": []
    }
  ]
}

3. Upload to GitHub

git add versions.json
git commit -m "Add version manifest"
git push

4. Verify Accessibility

curl https://raw.githubusercontent.com/YOUR-ORG/rr3-releases/main/versions.json

🎉 You're Done!

Your RR3 APK now has a fully functional OTA update system!

Next steps:

  1. Release your first version on GitHub
  2. Update versions.json when new versions are ready
  3. Users will automatically see updates

📞 Need Help?

  • 📖 Full documentation: README.md
  • 🐛 Report issues: GitHub Issues
  • 💬 Community: Discord (link TBA)
  • 📧 Contact: @ssfdre38

Happy integrating! 🔄🏁