├── .gitignore
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── io
│ │ └── bambosan
│ │ └── iseng
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ ├── launcher.dex
│ │ ├── launcher_draco.dex
│ │ └── launcher_mbl2.dex
│ ├── java
│ │ └── io
│ │ │ └── bambosan
│ │ │ └── mbloader
│ │ │ ├── CrashActivity.java
│ │ │ ├── Fallback.java
│ │ │ ├── HomeFragment.java
│ │ │ ├── IntentHandler.java
│ │ │ ├── MBLoaderApp.java
│ │ │ ├── MainActivity.java
│ │ │ ├── SettingsFragment.java
│ │ │ └── SplashActivity.java
│ ├── jni
│ │ ├── Android.mk
│ │ ├── Application.mk
│ │ └── mc-init.cpp
│ ├── jniLibs
│ │ ├── arm64-v8a
│ │ │ ├── libdraco.so
│ │ │ └── libmtbinloader2.so
│ │ └── armeabi-v7a
│ │ │ ├── libdraco.so
│ │ │ └── libmtbinloader2.so
│ └── res
│ │ ├── anim
│ │ ├── fade_in.xml
│ │ ├── fade_out.xml
│ │ ├── logo_pulse.xml
│ │ ├── logo_rotate.xml
│ │ ├── logo_zoom_in.xml
│ │ ├── slide_in_left.xml
│ │ ├── slide_in_right.xml
│ │ ├── slide_out_left.xml
│ │ ├── slide_out_right.xml
│ │ ├── slide_up_fade_in.xml
│ │ └── text_slide_up.xml
│ │ ├── animator
│ │ └── nav_item_animation.xml
│ │ ├── color
│ │ └── nav_item_color.xml
│ │ ├── drawable
│ │ ├── beta_label_background.xml
│ │ ├── button_container_background.xml
│ │ ├── ic_baseline_home_24.xml
│ │ ├── ic_baseline_settings_24.xml
│ │ ├── ic_launcher_foreground.xml
│ │ ├── ic_launcher_monochrome.xml
│ │ ├── nav_background.xml
│ │ ├── rounded_background.xml
│ │ ├── rounded_corner_background.xml
│ │ └── splash_highlight.xml
│ │ ├── layout
│ │ ├── activity_crash.xml
│ │ ├── activity_fallback.xml
│ │ ├── activity_main.xml
│ │ ├── activity_splash.xml
│ │ ├── fragment_home.xml
│ │ └── fragment_settings.xml
│ │ ├── menu
│ │ └── bottom_nav_menu.xml
│ │ ├── mipmap-anydpi-v26
│ │ └── ic_launcher.xml
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── themes.xml
│ │ └── xml
│ │ ├── file_provider_paths.xml
│ │ └── network_security_config.xml
│ └── test
│ └── java
│ └── io
│ └── bambosan
│ └── mbloader
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
├── libs.versions.toml
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── minecraft
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── com
│ └── mojang
│ └── minecraftpe
│ ├── FilePickerManagerHandler.java
│ ├── Launcher.java
│ ├── MainActivity.java
│ ├── NotificationListenerService.java
│ └── store
│ ├── ExtraLicenseResponseData.java
│ ├── Product.java
│ ├── Purchase.java
│ ├── Store.java
│ ├── StoreListener.java
│ ├── amazonappstore
│ └── AmazonAppStore.java
│ └── googleplay
│ └── GooglePlayStore.java
├── my-release-key.jks
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .idea
3 | .gradle
4 | /local.properties
5 | /.idea/caches
6 | /.idea/libraries
7 | /.idea/modules.xml
8 | /.idea/workspace.xml
9 | /.idea/navEditor.xml
10 | /.idea/assetWizardSettings.xml
11 | .DS_Store
12 | /build
13 | /captures
14 | .externalNativeBuild
15 | .cxx
16 | local.properties
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MB Loader (Unofficial)
2 |
3 | **Not distributed by us**, modified by The NoxPE Team.
4 |
5 | ORIGINAL APP: https://github.com/bambosan/MaterialBinLoader-Apk
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.android.application)
3 | alias(libs.plugins.kotlin.android)
4 | }
5 |
6 | android {
7 | namespace 'io.bambosan.mbloader'
8 | compileSdk 35
9 | buildToolsVersion = "35.0.0"
10 | defaultConfig {
11 | applicationId "io.bambosan.mbloader"
12 | minSdk 26
13 | targetSdk 35
14 | versionCode 17
15 | versionName "1.6"
16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
17 | ndk {
18 | abiFilters 'arm64-v8a', 'armeabi-v7a'
19 | }
20 | }
21 |
22 | signingConfigs {
23 | release {
24 | storeFile file("../my-release-key.jks")
25 | storePassword "lyssadev"
26 | keyAlias "my-alias"
27 | keyPassword "lyssadev"
28 | }
29 | }
30 |
31 | buildTypes {
32 | release {
33 | minifyEnabled false
34 | shrinkResources false
35 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
36 | signingConfig signingConfigs.release
37 | }
38 | }
39 | compileOptions {
40 | sourceCompatibility JavaVersion.VERSION_1_8
41 | targetCompatibility JavaVersion.VERSION_1_8
42 | }
43 | externalNativeBuild {
44 | ndkBuild {
45 | path "src/main/jni/Android.mk"
46 | }
47 | }
48 | ndkVersion "27.1.12297006"
49 | }
50 |
51 | dependencies {
52 | implementation libs.appcompat
53 | implementation libs.constraintlayout
54 | implementation 'com.google.android.material:material:1.12.0'
55 | implementation 'com.google.android.material:material:1.9.0'
56 | implementation 'androidx.fragment:fragment:1.6.0'
57 | implementation 'com.github.skydoves:colorpickerview:2.3.0'
58 | testImplementation libs.junit
59 | androidTestImplementation libs.ext.junit
60 | androidTestImplementation libs.espresso.core
61 | }
62 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/androidTest/java/io/bambosan/iseng/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package io.bambosan.mbloader;
2 |
3 | import android.content.Context;
4 | import androidx.test.platform.app.InstrumentationRegistry;
5 | import androidx.test.ext.junit.runners.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
23 | assertEquals("io.bambosan.iseng", appContext.getPackageName());
24 | }
25 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
40 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
54 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
103 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
141 |
143 |
145 |
146 |
147 |
158 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
196 |
198 |
200 |
201 |
202 |
208 |
209 |
211 |
214 |
216 |
218 |
219 |
220 |
226 |
232 |
237 |
240 |
241 |
242 |
243 |
244 |
248 |
249 |
250 |
--------------------------------------------------------------------------------
/app/src/main/assets/launcher.dex:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lyssadev/mb-loader-unofficial/fe6a30125e6baefa396c8853cd4a6bdfab4942eb/app/src/main/assets/launcher.dex
--------------------------------------------------------------------------------
/app/src/main/assets/launcher_draco.dex:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lyssadev/mb-loader-unofficial/fe6a30125e6baefa396c8853cd4a6bdfab4942eb/app/src/main/assets/launcher_draco.dex
--------------------------------------------------------------------------------
/app/src/main/assets/launcher_mbl2.dex:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lyssadev/mb-loader-unofficial/fe6a30125e6baefa396c8853cd4a6bdfab4942eb/app/src/main/assets/launcher_mbl2.dex
--------------------------------------------------------------------------------
/app/src/main/java/io/bambosan/mbloader/CrashActivity.java:
--------------------------------------------------------------------------------
1 | package io.bambosan.mbloader;
2 |
3 | import android.content.ClipData;
4 | import android.content.ClipboardManager;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.os.Bundle;
8 | import android.widget.Button;
9 | import android.widget.TextView;
10 | import android.widget.Toast;
11 |
12 | import androidx.appcompat.app.AppCompatActivity;
13 |
14 | public class CrashActivity extends AppCompatActivity {
15 |
16 | public static final String EXTRA_STACK_TRACE = "stack_trace";
17 |
18 | @Override
19 | protected void onCreate(Bundle savedInstanceState) {
20 | super.onCreate(savedInstanceState);
21 | setContentView(R.layout.activity_crash);
22 |
23 | // Get the stack trace from the intent
24 | String stackTraceStr = getIntent().getStringExtra(EXTRA_STACK_TRACE);
25 | if (stackTraceStr == null) {
26 | stackTraceStr = "No stack trace available";
27 | }
28 |
29 | final String stackTrace = stackTraceStr;
30 |
31 | // Display the stack trace
32 | TextView stackTraceTextView = findViewById(R.id.crash_stack_trace);
33 | stackTraceTextView.setText(stackTrace);
34 |
35 | // Copy button functionality
36 | Button copyButton = findViewById(R.id.btn_copy);
37 | copyButton.setOnClickListener(v -> {
38 | ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
39 | ClipData clip = ClipData.newPlainText("Stack Trace", stackTrace);
40 | clipboard.setPrimaryClip(clip);
41 | Toast.makeText(this, "Stack trace copied to clipboard", Toast.LENGTH_SHORT).show();
42 | });
43 |
44 | // Restart button functionality
45 | Button restartButton = findViewById(R.id.btn_restart);
46 | restartButton.setOnClickListener(v -> {
47 | Intent intent = new Intent(this, SplashActivity.class);
48 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
49 | startActivity(intent);
50 | finish();
51 | });
52 | }
53 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/bambosan/mbloader/Fallback.java:
--------------------------------------------------------------------------------
1 | package io.bambosan.mbloader;
2 |
3 | import android.os.Bundle;
4 |
5 | import android.widget.TextView;
6 | import androidx.appcompat.app.AppCompatActivity;
7 |
8 | public class Fallback extends AppCompatActivity {
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 | setContentView(R.layout.activity_fallback);
14 | TextView logOut = findViewById(R.id.logOut);
15 | String log = getIntent().getStringExtra("LOG_STR");
16 | logOut.setText(log);
17 | }
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/bambosan/mbloader/HomeFragment.java:
--------------------------------------------------------------------------------
1 | package io.bambosan.mbloader;
2 |
3 | import android.os.Bundle;
4 | import android.os.Handler;
5 | import android.os.Looper;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.Button;
10 | import android.widget.ScrollView;
11 | import android.widget.TextView;
12 |
13 | import androidx.fragment.app.Fragment;
14 |
15 | public class HomeFragment extends Fragment {
16 |
17 | private TextView listener;
18 | private ScrollView logScrollView;
19 | private Handler handler;
20 |
21 | @Override
22 | public void onCreate(Bundle savedInstanceState) {
23 | super.onCreate(savedInstanceState);
24 | }
25 |
26 | @Override
27 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
28 | View view = inflater.inflate(R.layout.fragment_home, container, false);
29 |
30 | listener = view.findViewById(R.id.listener);
31 | Button mbl2_button = view.findViewById(R.id.mbl2_load);
32 | Button draco_button = view.findViewById(R.id.draco_load);
33 | logScrollView = view.findViewById(R.id.log_scroll_view);
34 | handler = new Handler(Looper.getMainLooper());
35 |
36 | mbl2_button.setOnClickListener(v -> {
37 | ((MainActivity) requireActivity()).startLauncher(handler, listener, logScrollView, "launcher_mbl2.dex", MainActivity.MC_PACKAGE_NAME);
38 | });
39 |
40 | draco_button.setOnClickListener(v -> {
41 | ((MainActivity) requireActivity()).startLauncher(handler, listener, logScrollView, "launcher_draco.dex", MainActivity.MC_PACKAGE_NAME);
42 | });
43 |
44 | return view;
45 | }
46 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/bambosan/mbloader/IntentHandler.java:
--------------------------------------------------------------------------------
1 | package io.bambosan.mbloader;
2 |
3 |
4 | import android.content.Intent;
5 | import android.app.Activity;
6 | import android.os.Bundle;
7 |
8 | public class IntentHandler extends Activity
9 | {
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState)
12 | {
13 | super.onCreate(savedInstanceState);
14 | patiencepls(getIntent());
15 | //setContentView(R.layout.main);
16 |
17 | }
18 | void patiencepls(Intent intention) {
19 | if (isMcLoaded()) {
20 | intention.setClassName(getApplicationContext(), "com.mojang.minecraftpe.Launcher");
21 | } else {
22 | intention.setClassName(getApplicationContext(), "io.bambosan.mbloader.MainActivity");
23 | }
24 | startActivity(intention);
25 | }
26 | Boolean isMcLoaded() {
27 | try {
28 | Class.forName("com.mojang.minecraftpe.Launcher", false, getClassLoader());
29 | return true;
30 | } catch (Exception e) {
31 | return false;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/io/bambosan/mbloader/MBLoaderApp.java:
--------------------------------------------------------------------------------
1 | package io.bambosan.mbloader;
2 |
3 | import android.app.Application;
4 | import android.content.Intent;
5 | import android.os.Process;
6 |
7 | import java.io.PrintWriter;
8 | import java.io.StringWriter;
9 |
10 | public class MBLoaderApp extends Application {
11 |
12 | @Override
13 | public void onCreate() {
14 | super.onCreate();
15 |
16 | // Set up the default uncaught exception handler
17 | Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
18 | StringWriter sw = new StringWriter();
19 | PrintWriter pw = new PrintWriter(sw);
20 | throwable.printStackTrace(pw);
21 | String stackTraceString = sw.toString();
22 |
23 | // Start the crash activity with the stack trace
24 | Intent intent = new Intent(MBLoaderApp.this, CrashActivity.class);
25 | intent.putExtra(CrashActivity.EXTRA_STACK_TRACE, stackTraceString);
26 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
27 | startActivity(intent);
28 |
29 | // Force close the app
30 | Process.killProcess(Process.myPid());
31 | System.exit(1);
32 | });
33 | }
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/bambosan/mbloader/MainActivity.java:
--------------------------------------------------------------------------------
1 | package io.bambosan.mbloader;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.app.ActivityManager;
5 | import android.app.AlertDialog;
6 | import android.content.DialogInterface;
7 | import android.content.Intent;
8 | import android.content.pm.ApplicationInfo;
9 | import android.content.pm.PackageManager;
10 | import android.net.Uri;
11 | import android.os.Build;
12 | import android.os.Bundle;
13 | import android.os.Handler;
14 | import android.os.Looper;
15 | import android.os.SystemClock;
16 | import android.util.Log;
17 | import android.view.Gravity;
18 | import android.view.View;
19 | import android.widget.ScrollView;
20 | import android.widget.TextView;
21 | import androidx.fragment.app.Fragment;
22 | import androidx.appcompat.app.AppCompatActivity;
23 |
24 | import com.google.android.material.bottomnavigation.BottomNavigationView;
25 |
26 | import org.jetbrains.annotations.NotNull;
27 |
28 | import java.io.BufferedInputStream;
29 | import java.io.BufferedOutputStream;
30 | import java.io.File;
31 | import java.io.FileInputStream;
32 | import java.io.FileOutputStream;
33 | import java.io.IOException;
34 | import java.io.InputStream;
35 | import java.io.OutputStream;
36 | import java.lang.reflect.Field;
37 | import java.lang.reflect.Method;
38 | import java.nio.file.Files;
39 | import java.util.ArrayList;
40 | import java.util.Collection;
41 | import java.util.Collections;
42 | import java.util.HashMap;
43 | import java.util.List;
44 | import java.util.Objects;
45 | import java.util.concurrent.Executors;
46 | import java.util.zip.ZipEntry;
47 | import java.util.zip.ZipFile;
48 | import java.util.zip.ZipInputStream;
49 |
50 | public class MainActivity extends AppCompatActivity {
51 |
52 | public static final String MC_PACKAGE_NAME = "com.mojang.minecraftpe";
53 |
54 | @Override
55 | protected void onCreate(Bundle savedInstanceState) {
56 | super.onCreate(savedInstanceState);
57 |
58 | // Support for shared element transition from splash screen
59 | postponeEnterTransition();
60 |
61 | // Add entry animation
62 | View rootView = findViewById(android.R.id.content);
63 | rootView.startAnimation(android.view.animation.AnimationUtils.loadAnimation(this, R.anim.slide_up_fade_in));
64 |
65 | // Complete the postponed shared element transition
66 | startPostponedEnterTransition();
67 |
68 | if (savedInstanceState == null) {
69 | // --- Apply custom window flags ---
70 | getWindow().setStatusBarColor(getColor(R.color.background));
71 | getWindow().setNavigationBarColor(getColor(R.color.background));
72 |
73 | // --- Set content view and attach navigation ---
74 | setContentView(R.layout.activity_main);
75 | setupNavigation();
76 |
77 | // --- Set default fragment ---
78 | getSupportFragmentManager().beginTransaction()
79 | .replace(R.id.fragment_container, new HomeFragment())
80 | .commit();
81 | }
82 | }
83 |
84 | public void startLauncher(Handler handler, TextView listener, ScrollView logScrollView, String launcherDexName, String mcPackageName) {
85 | Executors.newSingleThreadExecutor().execute(() -> {
86 | try {
87 | File cacheDexDir = new File(getCodeCacheDir(), "dex");
88 | handleCacheCleaning(cacheDexDir, handler, listener, logScrollView);
89 | ApplicationInfo mcInfo = null;
90 | try {
91 | mcInfo = getPackageManager().getApplicationInfo(mcPackageName, PackageManager.GET_META_DATA);
92 | } catch(Exception e) {
93 | handler.post(() -> alertAndExit("Minecraft not found", "Perhaps you don't have it installed?"));
94 | return;
95 | }
96 | Object pathList = getPathList(getClassLoader());
97 | processDexFiles(mcInfo, cacheDexDir, pathList, handler, listener, logScrollView, launcherDexName);
98 | if (!processNativeLibraries(mcInfo, pathList, handler, listener, logScrollView)) {
99 | return;
100 | }
101 | launchMinecraft(mcInfo);
102 | } catch (Exception e) {
103 | String logMessage = e.getCause() != null ? e.getCause().toString() : e.toString();
104 | handler.post(() -> {
105 | listener.setText("Launching failed: " + logMessage);
106 | logScrollView.post(() -> logScrollView.fullScroll(View.FOCUS_DOWN));
107 | });
108 | }
109 | });
110 | }
111 | @SuppressLint("SetTextI18n")
112 | private void handleCacheCleaning(@NotNull File cacheDexDir, Handler handler, TextView listener, ScrollView logScrollView) {
113 | if (cacheDexDir.exists() && cacheDexDir.isDirectory()) {
114 | handler.post(() -> {
115 | listener.setText("-> " + cacheDexDir.getAbsolutePath() + " not empty, do cleaning");
116 | logScrollView.post(() -> logScrollView.fullScroll(View.FOCUS_DOWN));
117 | });
118 | for (File file : Objects.requireNonNull(cacheDexDir.listFiles())) {
119 | if (file.delete()) {
120 | handler.post(() -> {
121 | listener.append("\n-> " + file.getName() + " deleted");
122 | logScrollView.post(() -> logScrollView.fullScroll(View.FOCUS_DOWN));
123 | });
124 | }
125 | }
126 | } else {
127 | handler.post(() -> {
128 | listener.setText("-> " + cacheDexDir.getAbsolutePath() + " is empty, skip cleaning");
129 | logScrollView.post(() -> logScrollView.fullScroll(View.FOCUS_DOWN));
130 | });
131 | }
132 | }
133 |
134 | private Object getPathList(@NotNull ClassLoader classLoader) throws Exception {
135 | Field pathListField = Objects.requireNonNull(classLoader.getClass().getSuperclass()).getDeclaredField("pathList");
136 | pathListField.setAccessible(true);
137 | return pathListField.get(classLoader);
138 | }
139 |
140 | private void processDexFiles(ApplicationInfo mcInfo, File cacheDexDir, @NotNull Object pathList, @NotNull Handler handler, TextView listener, ScrollView logScrollView, String launcherDexName) throws Exception {
141 | Method addDexPath = pathList.getClass().getDeclaredMethod("addDexPath", String.class, File.class);
142 | File launcherDex = new File(cacheDexDir, launcherDexName);
143 |
144 | copyFile(getAssets().open(launcherDexName), launcherDex);
145 | handler.post(() -> {
146 | listener.append("\n-> " + launcherDexName + " copied to " + launcherDex.getAbsolutePath());
147 | logScrollView.post(() -> logScrollView.fullScroll(View.FOCUS_DOWN));
148 | });
149 |
150 | if (launcherDex.setReadOnly()) {
151 | addDexPath.invoke(pathList, launcherDex.getAbsolutePath(), null);
152 | handler.post(() -> {
153 | listener.append("\n-> " + launcherDexName + " added to dex path list");
154 | logScrollView.post(() -> logScrollView.fullScroll(View.FOCUS_DOWN));
155 | });
156 | }
157 |
158 | try (ZipFile zipFile = new ZipFile(mcInfo.sourceDir)) {
159 | for (int i = 10; i >= 0; i--) {
160 | String dexName = "classes" + (i == 0 ? "" : i) + ".dex";
161 | ZipEntry dexFile = zipFile.getEntry(dexName);
162 | if (dexFile != null) {
163 | File mcDex = new File(cacheDexDir, dexName);
164 | copyFile(zipFile.getInputStream(dexFile), mcDex);
165 | handler.post(() -> {
166 | listener.append("\n-> " + mcInfo.sourceDir + "/" + dexName + " copied to " + mcDex.getAbsolutePath());
167 | logScrollView.post(() -> logScrollView.fullScroll(View.FOCUS_DOWN));
168 | });
169 | if (mcDex.setReadOnly()) {
170 | addDexPath.invoke(pathList, mcDex.getAbsolutePath(), null);
171 | handler.post(() -> {
172 | listener.append("\n-> " + dexName + " added to dex path list");
173 | logScrollView.post(() -> logScrollView.fullScroll(View.FOCUS_DOWN));
174 | });
175 | }
176 | }
177 | }
178 | } catch (Throwable th) {}
179 | handler.post(() -> {
180 | listener.append("\n-> Processed dex files.");
181 | logScrollView.post(() -> logScrollView.fullScroll(View.FOCUS_DOWN));
182 | });
183 | }
184 |
185 | @SuppressLint("SoonBlockedPrivateApi")
186 | private boolean processNativeLibraries(ApplicationInfo mcInfo, @NotNull Object pathList, @NotNull Handler handler, TextView listener, ScrollView logScrollView) throws Exception {
187 | FileInputStream inStream = new FileInputStream(getApkWithLibs(mcInfo));
188 | BufferedInputStream bufInStream = new BufferedInputStream(inStream);
189 | ZipInputStream inZipStream = new ZipInputStream(bufInStream);
190 | if (!checkLibCompatibility(inZipStream)) {
191 | handler.post(() -> alertAndExit("Wrong Minecraft architecture", "The Minecraft you have installed does not support the same main architecture (" + Build.SUPPORTED_ABIS[0] + ") your device uses, MBLoader can't work with it"));
192 | return false;
193 | }
194 | Method addNativePath = pathList.getClass().getDeclaredMethod("addNativePath", Collection.class);
195 | ArrayList libDirList = new ArrayList<>();
196 | File libdir = new File(mcInfo.nativeLibraryDir);
197 | if (libdir.list() == null || libdir.list().length == 0
198 | || (mcInfo.flags & ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) != ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) {
199 | loadUnextractedLibs(mcInfo);
200 | libDirList.add(getCodeCacheDir().getAbsolutePath() + "/");
201 | } else {
202 | libDirList.add(mcInfo.nativeLibraryDir);
203 | }
204 | addNativePath.invoke(pathList, libDirList);
205 | handler.post(() -> {
206 | listener.append("\n-> " + mcInfo.nativeLibraryDir + " added to native library directory path");
207 | logScrollView.post(() -> logScrollView.fullScroll(View.FOCUS_DOWN));
208 | });
209 | return true;
210 | }
211 |
212 | private static Boolean checkLibCompatibility(ZipInputStream zip) throws Exception{
213 | ZipEntry ze = null;
214 | String requiredLibDir = "lib/" + Build.SUPPORTED_ABIS[0] + "/";
215 | while ((ze = zip.getNextEntry()) != null) {
216 | if (ze.getName().startsWith(requiredLibDir)) {
217 | return true;
218 | }
219 | }
220 | zip.close();
221 | return false;
222 | }
223 |
224 | private void alertAndExit(String issue, String description) {
225 | AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
226 | alertDialog.setTitle(issue);
227 | alertDialog.setMessage(description);
228 | alertDialog.setCancelable(false);
229 | alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "Exit",
230 | new DialogInterface.OnClickListener() {
231 | public void onClick(DialogInterface dialog, int which) {
232 | finish();
233 | }
234 | });
235 | alertDialog.show();
236 | }
237 |
238 | private void loadUnextractedLibs(ApplicationInfo appInfo) throws Exception {
239 | FileInputStream inStream = new FileInputStream(getApkWithLibs(appInfo));
240 | BufferedInputStream bufInStream = new BufferedInputStream(inStream);
241 | ZipInputStream inZipStream = new ZipInputStream(bufInStream);
242 | String zipPath = "lib/" + Build.SUPPORTED_ABIS[0] + "/";
243 | String outPath = getCodeCacheDir().getAbsolutePath() + "/";
244 | File dir = new File(outPath);
245 | dir.mkdir();
246 | extractDir(appInfo, inZipStream, zipPath, outPath);
247 | }
248 |
249 | public String getApkWithLibs(ApplicationInfo pkg) throws PackageManager.NameNotFoundException {
250 | // get installed split's Names
251 | String[] sn=pkg.splitSourceDirs;
252 |
253 | // check whether if it's really split or not
254 | if (sn != null && sn.length > 0) {
255 | String cur_abi = Build.SUPPORTED_ABIS[0].replace('-','_');
256 | // search installed splits
257 | for(String n:sn){
258 | //check whether is the one required
259 | if(n.contains(cur_abi)){
260 | // yes, it's installed!
261 | return n;
262 | }
263 | }
264 | }
265 | // couldn't find!
266 | return pkg.sourceDir;
267 | }
268 |
269 | private static void extractDir(ApplicationInfo mcInfo, ZipInputStream zip, String zip_folder, String out_folder) throws Exception {
270 | ZipEntry ze = null;
271 | while ((ze = zip.getNextEntry()) != null) {
272 | if (ze.getName().startsWith(zip_folder) && !ze.getName().contains("c++_shared")) {
273 | String strippedName = ze.getName().substring(zip_folder.length());
274 | String path = out_folder + "/" + strippedName;
275 | OutputStream out = new FileOutputStream(path);
276 | BufferedOutputStream outBuf = new BufferedOutputStream(out);
277 | byte[] buffer = new byte[9000];
278 | int len;
279 | while ((len = zip.read(buffer)) != -1) {
280 | outBuf.write(buffer, 0, len);
281 | }
282 | outBuf.close();
283 | }
284 | }
285 | zip.close();
286 | }
287 |
288 | private void launchMinecraft(@NotNull ApplicationInfo mcInfo) throws ClassNotFoundException {
289 | Class> launcherClass = getClassLoader().loadClass("com.mojang.minecraftpe.Launcher");
290 | // We do this to preserve data that apps like file managers pass
291 | Intent mcActivity = getIntent().setClass(this, launcherClass);
292 | mcActivity.putExtra("MC_SRC", mcInfo.sourceDir);
293 |
294 | if (mcInfo.splitSourceDirs != null) {
295 | ArrayList listSrcSplit = new ArrayList<>();
296 | Collections.addAll(listSrcSplit, mcInfo.splitSourceDirs);
297 | mcActivity.putExtra("MC_SPLIT_SRC", listSrcSplit);
298 | }
299 |
300 | startActivity(mcActivity);
301 | finish();
302 | }
303 |
304 | private void handleException(@NotNull Exception e, @NotNull Intent fallbackActivity) {
305 | String logMessage = e.getCause() != null ? e.getCause().toString() : e.toString();
306 | fallbackActivity.putExtra("LOG_STR", logMessage);
307 | startActivity(fallbackActivity);
308 | finish();
309 | }
310 |
311 | private static void copyFile(InputStream from, @NotNull File to) throws IOException {
312 | File parentDir = to.getParentFile();
313 | if (parentDir != null && !parentDir.exists() && !parentDir.mkdirs()) {
314 | throw new IOException("Failed to create directories");
315 | }
316 | if (!to.exists() && !to.createNewFile()) {
317 | throw new IOException("Failed to create new file");
318 | }
319 | try (BufferedInputStream input = new BufferedInputStream(from);
320 | BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(to.toPath()))) {
321 | byte[] buffer = new byte[8192];
322 | int bytesRead;
323 | while ((bytesRead = input.read(buffer)) != -1) {
324 | output.write(buffer, 0, bytesRead);
325 | }
326 | }
327 | }
328 |
329 | private void setupNavigation() {
330 | // Setup bottom navigation
331 | BottomNavigationView bottomNav = findViewById(R.id.bottom_navigation);
332 |
333 | // Set initial fragment
334 | if (getSupportFragmentManager().findFragmentById(R.id.fragment_container) == null) {
335 | getSupportFragmentManager().beginTransaction()
336 | .replace(R.id.fragment_container, new HomeFragment())
337 | .commit();
338 |
339 | // Select home item initially
340 | bottomNav.setSelectedItemId(R.id.navigation_home);
341 | }
342 |
343 | // Animate nav items using state list animator
344 | bottomNav.setItemIconTintList(getColorStateList(R.color.nav_item_color));
345 | bottomNav.setItemTextColor(getColorStateList(R.color.nav_item_color));
346 | bottomNav.setStateListAnimator(android.animation.AnimatorInflater.loadStateListAnimator(
347 | this, R.animator.nav_item_animation));
348 |
349 | // Track the current selected item to determine animation direction
350 | final int[] currentItem = {R.id.navigation_home};
351 |
352 | // Handle navigation item selection
353 | bottomNav.setOnItemSelectedListener(item -> {
354 | Fragment selectedFragment = null;
355 | int enterAnim = R.anim.slide_in_right;
356 | int exitAnim = R.anim.slide_out_left;
357 |
358 | // Determine animation direction based on item position
359 | if (getNavigationItemIndex(item.getItemId()) < getNavigationItemIndex(currentItem[0])) {
360 | enterAnim = R.anim.slide_in_left;
361 | exitAnim = R.anim.slide_out_right;
362 | }
363 |
364 | // Create appropriate fragment
365 | if (item.getItemId() == R.id.navigation_home) {
366 | selectedFragment = new HomeFragment();
367 | } else if (item.getItemId() == R.id.navigation_settings) {
368 | selectedFragment = new SettingsFragment();
369 | }
370 |
371 | if (selectedFragment != null) {
372 | // Update current item
373 | currentItem[0] = item.getItemId();
374 |
375 | // Perform fragment transition with animations
376 | getSupportFragmentManager().beginTransaction()
377 | .setCustomAnimations(
378 | enterAnim,
379 | exitAnim
380 | )
381 | .replace(R.id.fragment_container, selectedFragment)
382 | .commit();
383 | return true;
384 | }
385 | return false;
386 | });
387 | }
388 |
389 | // Helper method to get the index of navigation items
390 | private int getNavigationItemIndex(int itemId) {
391 | if (itemId == R.id.navigation_home) return 0;
392 | if (itemId == R.id.navigation_settings) return 1;
393 | return 0;
394 | }
395 | }
396 |
--------------------------------------------------------------------------------
/app/src/main/java/io/bambosan/mbloader/SettingsFragment.java:
--------------------------------------------------------------------------------
1 | package io.bambosan.mbloader;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.os.Bundle;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.EditText;
10 | import androidx.fragment.app.Fragment;
11 | import com.google.android.material.button.MaterialButton;
12 | import com.google.android.material.textfield.TextInputEditText;
13 |
14 | public class SettingsFragment extends Fragment {
15 | private SharedPreferences prefs;
16 | private View rootView;
17 |
18 | @Override
19 | public void onCreate(Bundle savedInstanceState) {
20 | super.onCreate(savedInstanceState);
21 | prefs = requireActivity().getSharedPreferences("app_settings", Context.MODE_PRIVATE);
22 | }
23 |
24 | @Override
25 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
26 | rootView = inflater.inflate(R.layout.fragment_settings, container, false);
27 |
28 | TextInputEditText mcPackageName = rootView.findViewById(R.id.mc_pkgname);
29 | mcPackageName.setText(MainActivity.MC_PACKAGE_NAME);
30 |
31 | // Set up crash test button
32 | MaterialButton testCrashButton = rootView.findViewById(R.id.test_crash_button);
33 | testCrashButton.setOnClickListener(v -> {
34 | throw new RuntimeException("Test crash to verify crash handler");
35 | });
36 |
37 | return rootView;
38 | }
39 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/bambosan/mbloader/SplashActivity.java:
--------------------------------------------------------------------------------
1 | package io.bambosan.mbloader;
2 |
3 | import android.animation.Animator;
4 | import android.animation.AnimatorListenerAdapter;
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 | import android.os.Handler;
8 | import android.view.View;
9 | import android.view.animation.Animation;
10 | import android.view.animation.AnimationUtils;
11 | import android.widget.ImageView;
12 | import android.widget.TextView;
13 | import androidx.appcompat.app.AppCompatActivity;
14 | import androidx.core.app.ActivityOptionsCompat;
15 |
16 | public class SplashActivity extends AppCompatActivity {
17 |
18 | private static final int SPLASH_DURATION = 3000; // 3 seconds
19 |
20 | private ImageView logoView;
21 | private TextView titleView;
22 | private TextView subtitleView;
23 | private View highlightView;
24 |
25 | @Override
26 | protected void onCreate(Bundle savedInstanceState) {
27 | super.onCreate(savedInstanceState);
28 | setContentView(R.layout.activity_splash);
29 |
30 | // Find views
31 | logoView = findViewById(R.id.splash_logo);
32 | titleView = findViewById(R.id.splash_title);
33 | subtitleView = findViewById(R.id.splash_subtitle);
34 | highlightView = findViewById(R.id.splash_highlight);
35 |
36 | // Start animations
37 | startAnimations();
38 |
39 | // Delay transition to MainActivity
40 | new Handler().postDelayed(this::startMainActivity, SPLASH_DURATION);
41 | }
42 |
43 | private void startAnimations() {
44 | // Logo animation
45 | Animation zoomIn = AnimationUtils.loadAnimation(this, R.anim.logo_zoom_in);
46 | Animation rotate = AnimationUtils.loadAnimation(this, R.anim.logo_rotate);
47 |
48 | logoView.startAnimation(zoomIn);
49 |
50 | zoomIn.setAnimationListener(new Animation.AnimationListener() {
51 | @Override
52 | public void onAnimationStart(Animation animation) {}
53 |
54 | @Override
55 | public void onAnimationEnd(Animation animation) {
56 | logoView.startAnimation(rotate);
57 | }
58 |
59 | @Override
60 | public void onAnimationRepeat(Animation animation) {}
61 | });
62 |
63 | // Text animations
64 | Animation textAnim = AnimationUtils.loadAnimation(this, R.anim.text_slide_up);
65 | titleView.startAnimation(textAnim);
66 |
67 | Animation subtitleAnim = AnimationUtils.loadAnimation(this, R.anim.text_slide_up);
68 | subtitleAnim.setStartOffset(1300); // Slight delay for subtitle
69 | subtitleView.startAnimation(subtitleAnim);
70 |
71 | // Highlight animation
72 | Animation pulseAnim = AnimationUtils.loadAnimation(this, R.anim.logo_pulse);
73 | highlightView.startAnimation(pulseAnim);
74 | }
75 |
76 | private void startMainActivity() {
77 | Intent intent = new Intent(this, MainActivity.class);
78 |
79 | // Create a shared element transition
80 | ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
81 | this, logoView, "app_logo");
82 |
83 | startActivity(intent, options.toBundle());
84 |
85 | // Delayed finish to allow smooth transition
86 | new Handler().postDelayed(this::finish, 500);
87 | }
88 | }
--------------------------------------------------------------------------------
/app/src/main/jni/Android.mk:
--------------------------------------------------------------------------------
1 | LOCAL_PATH := $(call my-dir)
2 |
3 | include $(CLEAR_VARS)
4 | LOCAL_MODULE := mc
5 | LOCAL_SRC_FILES := mc-init.cpp
6 | include $(BUILD_SHARED_LIBRARY)
7 |
--------------------------------------------------------------------------------
/app/src/main/jni/Application.mk:
--------------------------------------------------------------------------------
1 | APP_ABI := arm64-v8a
2 | APP_STL := c++_shared
3 |
--------------------------------------------------------------------------------
/app/src/main/jni/mc-init.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include
6 |
7 | static void (*android_main_minecraft)(struct android_app *app);
8 | static void (*ANativeActivity_onCreate_minecraft)(ANativeActivity *activity, void *savedState, size_t savedStateSize);
9 |
10 | extern "C" void android_main(struct android_app *app) {
11 | android_main_minecraft(app);
12 | }
13 |
14 | extern "C" void ANativeActivity_onCreate(ANativeActivity *activity, void *savedState, size_t savedStateSize) {
15 | ANativeActivity_onCreate_minecraft(activity, savedState, savedStateSize);
16 | }
17 |
18 | JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
19 | void *handle = dlopen("libminecraftpe.so", RTLD_LAZY);
20 | android_main_minecraft = (void (*)(struct android_app *)) (dlsym(handle, "android_main"));
21 | ANativeActivity_onCreate_minecraft = (void (*)(ANativeActivity *, void *, size_t)) (dlsym(handle, "ANativeActivity_onCreate"));
22 | return JNI_VERSION_1_6;
23 | }
--------------------------------------------------------------------------------
/app/src/main/jniLibs/arm64-v8a/libdraco.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lyssadev/mb-loader-unofficial/fe6a30125e6baefa396c8853cd4a6bdfab4942eb/app/src/main/jniLibs/arm64-v8a/libdraco.so
--------------------------------------------------------------------------------
/app/src/main/jniLibs/arm64-v8a/libmtbinloader2.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lyssadev/mb-loader-unofficial/fe6a30125e6baefa396c8853cd4a6bdfab4942eb/app/src/main/jniLibs/arm64-v8a/libmtbinloader2.so
--------------------------------------------------------------------------------
/app/src/main/jniLibs/armeabi-v7a/libdraco.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lyssadev/mb-loader-unofficial/fe6a30125e6baefa396c8853cd4a6bdfab4942eb/app/src/main/jniLibs/armeabi-v7a/libdraco.so
--------------------------------------------------------------------------------
/app/src/main/jniLibs/armeabi-v7a/libmtbinloader2.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lyssadev/mb-loader-unofficial/fe6a30125e6baefa396c8853cd4a6bdfab4942eb/app/src/main/jniLibs/armeabi-v7a/libmtbinloader2.so
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/logo_pulse.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/logo_rotate.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/logo_zoom_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
14 |
15 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_in_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
10 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_in_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
10 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_out_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
10 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_out_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
10 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_up_fade_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/text_slide_up.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/animator/nav_item_animation.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
9 |
10 | -
11 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/color/nav_item_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/beta_label_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_container_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_home_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_settings_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
8 |
13 |
18 |
23 |
28 |
33 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_monochrome.xml:
--------------------------------------------------------------------------------
1 |
8 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/nav_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rounded_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rounded_corner_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
8 |
9 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/splash_highlight.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_crash.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
21 |
22 |
26 |
27 |
33 |
34 |
35 |
41 |
42 |
48 |
49 |
54 |
55 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_fallback.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
35 |
36 |
37 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
20 |
21 |
35 |
36 |
49 |
50 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
19 |
20 |
31 |
32 |
39 |
40 |
49 |
50 |
55 |
56 |
64 |
65 |
72 |
73 |
83 |
84 |
85 |
86 |
95 |
96 |
101 |
102 |
110 |
111 |
118 |
119 |
132 |
133 |
134 |
135 |
144 |
145 |
150 |
151 |
159 |
160 |
165 |
166 |
172 |
173 |
181 |
182 |
183 |
184 |
185 |
186 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
19 |
20 |
29 |
30 |
31 |
40 |
41 |
46 |
47 |
55 |
56 |
63 |
64 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
85 |
86 |
91 |
92 |
100 |
101 |
108 |
109 |
117 |
118 |
119 |
120 |
121 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/bottom_nav_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 | #000000
5 | #2196F3
6 | #1C1C1C
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | MB Loader
3 | ms-xal-0000000048183522
4 | Hello World!
5 | Startup with full support for shader resourcepacks from worlds,realms and servers (might break with mc updates)
6 | Startup with support for shader resourcepacks from global resourcepacks tab only (more compatible)
7 | Please choose what to launch mc with
8 | mc packageid:
9 | Permission to launch Minecraft with MB Loader
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
19 |
20 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/file_provider_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
9 |
12 |
15 |
18 |
21 |
24 |
27 |
30 |
33 |
36 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/network_security_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/test/java/io/bambosan/mbloader/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package io.bambosan.mbloader;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | plugins {
3 | alias(libs.plugins.android.application) apply false
4 | alias(libs.plugins.android.library) apply false
5 | alias(libs.plugins.kotlin.android) apply false
6 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. For more details, visit
12 | # https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Enables namespacing of each library's R class so that its R class includes only the
19 | # resources declared in the library itself and none from the library's dependencies,
20 | # thereby reducing the size of the R class for that library
21 | android.nonTransitiveRClass=true
--------------------------------------------------------------------------------
/gradle/libs.versions.toml:
--------------------------------------------------------------------------------
1 | [versions]
2 | agp = "8.9.1"
3 | junit = "4.13.2"
4 | junitVersion = "1.2.1"
5 | espressoCore = "3.6.1"
6 | appcompat = "1.7.0"
7 | constraintlayout = "2.1.4"
8 | kotlin = "1.9.0"
9 |
10 | [libraries]
11 | junit = { group = "junit", name = "junit", version.ref = "junit" }
12 | ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
13 | espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
14 | appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
15 | constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
16 |
17 | [plugins]
18 | android-application = { id = "com.android.application", version.ref = "agp" }
19 | android-library = { id = "com.android.library", version.ref = "agp" }
20 | kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
21 |
22 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lyssadev/mb-loader-unofficial/fe6a30125e6baefa396c8853cd4a6bdfab4942eb/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Aug 16 19:13:26 WIB 2024
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/minecraft/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/minecraft/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.android.library)
3 | }
4 |
5 | android {
6 | namespace 'com.mojang.minecraftpe'
7 | compileSdk 34
8 | defaultConfig {
9 | minSdk 26
10 | consumerProguardFiles "consumer-rules.pro"
11 | }
12 | buildTypes {
13 | release {
14 | minifyEnabled false
15 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
16 | }
17 | }
18 | compileOptions {
19 | sourceCompatibility JavaVersion.VERSION_1_8
20 | targetCompatibility JavaVersion.VERSION_1_8
21 | }
22 | }
23 |
24 | dependencies {}
--------------------------------------------------------------------------------
/minecraft/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lyssadev/mb-loader-unofficial/fe6a30125e6baefa396c8853cd4a6bdfab4942eb/minecraft/consumer-rules.pro
--------------------------------------------------------------------------------
/minecraft/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/minecraft/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/minecraft/src/main/java/com/mojang/minecraftpe/FilePickerManagerHandler.java:
--------------------------------------------------------------------------------
1 | package com.mojang.minecraftpe;
2 |
3 | import android.content.Intent;
4 |
5 | interface FilePickerManagerHandler {
6 | void startPickerActivity(Intent intent, int i);
7 | }
8 |
--------------------------------------------------------------------------------
/minecraft/src/main/java/com/mojang/minecraftpe/Launcher.java:
--------------------------------------------------------------------------------
1 | package com.mojang.minecraftpe;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.os.Bundle;
5 | import java.lang.reflect.Method;
6 | import java.util.ArrayList;
7 |
8 | public class Launcher extends com.mojang.minecraftpe.MainActivity {
9 | @Override
10 | public void onCreate(Bundle bundle) {
11 | try {
12 | @SuppressLint("DiscouragedPrivateApi") Method addAssetPath = getAssets().getClass().getDeclaredMethod("addAssetPath", String.class);
13 | String mcSource = getIntent().getStringExtra("MC_SRC");
14 | addAssetPath.invoke(getAssets(), mcSource);
15 |
16 | ArrayList mcSplitSrc = getIntent().getStringArrayListExtra("MC_SPLIT_SRC");
17 | if (mcSplitSrc != null){
18 | for (String splitSource : mcSplitSrc) {
19 | addAssetPath.invoke(getAssets(), splitSource);
20 | }
21 | }
22 | super.onCreate(bundle);
23 | } catch (Exception e) {
24 | throw new RuntimeException(e);
25 | }
26 | }
27 |
28 | static {
29 | System.loadLibrary("c++_shared");
30 | System.loadLibrary("fmod");
31 | System.loadLibrary("minecraftpe");
32 | System.loadLibrary("mc");
33 | System.loadLibrary("materialbinloader");
34 | }
35 | }
--------------------------------------------------------------------------------
/minecraft/src/main/java/com/mojang/minecraftpe/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.mojang.minecraftpe;
2 |
3 | import android.app.NativeActivity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.KeyEvent;
7 | import android.view.View;
8 |
9 | public abstract class MainActivity extends NativeActivity implements View.OnKeyListener, FilePickerManagerHandler {
10 | @Override
11 | public void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 | throw new RuntimeException("Stub!");
14 | }
15 | @Override
16 | public boolean onKey(View v, int keyCode, KeyEvent event) {
17 | throw new RuntimeException("Stub!");
18 | }
19 | @Override
20 | public void startPickerActivity(Intent intent, int i) {
21 | throw new RuntimeException("Stub!");
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/minecraft/src/main/java/com/mojang/minecraftpe/NotificationListenerService.java:
--------------------------------------------------------------------------------
1 | package com.mojang.minecraftpe;
2 |
3 | public class NotificationListenerService {
4 | public static String getDeviceRegistrationToken() {
5 | return "";
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/minecraft/src/main/java/com/mojang/minecraftpe/store/ExtraLicenseResponseData.java:
--------------------------------------------------------------------------------
1 | package com.mojang.minecraftpe.store;
2 |
3 | public class ExtraLicenseResponseData {
4 | private long mRetryAttempts = 0;
5 | private long mRetryUntilTime = 0;
6 | private long mValidationTime = 0;
7 |
8 | public ExtraLicenseResponseData(long validationTime, long retryUntilTime, long retryAttempts) {
9 | mValidationTime = validationTime;
10 | mRetryUntilTime = retryUntilTime;
11 | mRetryAttempts = retryAttempts;
12 | }
13 |
14 | public long getValidationTime() {
15 | return mValidationTime;
16 | }
17 |
18 | public long getRetryUntilTime() {
19 | return mRetryUntilTime;
20 | }
21 |
22 | public long getRetryAttempts() {
23 | return mRetryAttempts;
24 | }
25 | }
--------------------------------------------------------------------------------
/minecraft/src/main/java/com/mojang/minecraftpe/store/Product.java:
--------------------------------------------------------------------------------
1 | package com.mojang.minecraftpe.store;
2 |
3 | public class Product {
4 | public String mCurrencyCode;
5 | public String mId;
6 | public String mPrice;
7 | public String mUnformattedPrice;
8 |
9 | public Product(String id, String price, String currencyCode, String unformattedPrice) {
10 | mId = id;
11 | mPrice = price;
12 | mCurrencyCode = currencyCode;
13 | mUnformattedPrice = unformattedPrice;
14 | }
15 | }
--------------------------------------------------------------------------------
/minecraft/src/main/java/com/mojang/minecraftpe/store/Purchase.java:
--------------------------------------------------------------------------------
1 | package com.mojang.minecraftpe.store;
2 |
3 | public class Purchase {
4 | public String mProductId;
5 | public boolean mPurchaseActive;
6 | public String mReceipt;
7 |
8 | public Purchase(String productId, String receipt, boolean purchaseActive) {
9 | mProductId = productId;
10 | mReceipt = receipt;
11 | mPurchaseActive = purchaseActive;
12 | }
13 | }
--------------------------------------------------------------------------------
/minecraft/src/main/java/com/mojang/minecraftpe/store/Store.java:
--------------------------------------------------------------------------------
1 | package com.mojang.minecraftpe.store;
2 |
3 | public interface Store {
4 | void acknowledgePurchase(String str, String str2);
5 |
6 | void destructor();
7 |
8 | ExtraLicenseResponseData getExtraLicenseData();
9 |
10 | String getProductSkuPrefix();
11 |
12 | String getRealmsSkuPrefix();
13 |
14 | String getStoreId();
15 |
16 | boolean hasVerifiedLicense();
17 |
18 | void purchase(String str, boolean z, String str2);
19 |
20 | void purchaseGame();
21 |
22 | void queryProducts(String[] strArr);
23 |
24 | void queryPurchases();
25 |
26 | boolean receivedLicenseResponse();
27 | }
--------------------------------------------------------------------------------
/minecraft/src/main/java/com/mojang/minecraftpe/store/StoreListener.java:
--------------------------------------------------------------------------------
1 | package com.mojang.minecraftpe.store;
2 |
3 | public interface StoreListener {
4 | void onPurchaseCanceled(String str);
5 |
6 | void onPurchaseFailed(String str);
7 |
8 | void onPurchaseSuccessful(String str, String str2);
9 |
10 | void onQueryProductsFail();
11 |
12 | void onQueryProductsSuccess(Product[] productArr);
13 |
14 | void onQueryPurchasesFail();
15 |
16 | void onQueryPurchasesSuccess(Purchase[] purchaseArr);
17 |
18 | void onStoreInitialized(boolean z);
19 | }
--------------------------------------------------------------------------------
/minecraft/src/main/java/com/mojang/minecraftpe/store/amazonappstore/AmazonAppStore.java:
--------------------------------------------------------------------------------
1 | package com.mojang.minecraftpe.store.amazonappstore;
2 |
3 | import android.content.Context;
4 |
5 | import com.mojang.minecraftpe.store.ExtraLicenseResponseData;
6 | import com.mojang.minecraftpe.store.Store;
7 | import com.mojang.minecraftpe.store.StoreListener;
8 |
9 | public class AmazonAppStore implements Store {
10 | StoreListener mListener;
11 | private boolean mForFireTV;
12 |
13 | public AmazonAppStore(Context context, StoreListener listener) {
14 | mListener = listener;
15 | }
16 |
17 | public AmazonAppStore(Context context, StoreListener listener, boolean forFireTV) {
18 | mListener = listener;
19 | mForFireTV = forFireTV;
20 | }
21 |
22 | public String getStoreId() {
23 | return "android.amazonappstore";
24 | }
25 |
26 | public boolean hasVerifiedLicense() {
27 | return true;
28 | }
29 |
30 | public boolean receivedLicenseResponse() {
31 | return true;
32 | }
33 |
34 | public void queryProducts(String[] productIds) {
35 | }
36 |
37 | public void acknowledgePurchase(String receipt, String productType) {
38 | }
39 |
40 | public void queryPurchases() {
41 | }
42 |
43 | public String getProductSkuPrefix() {
44 | return mForFireTV ? "firetv." : "";
45 | }
46 |
47 | public String getRealmsSkuPrefix() {
48 | return mForFireTV ? "firetv." : "";
49 | }
50 |
51 | public void destructor() {
52 | }
53 |
54 | @Override
55 | public ExtraLicenseResponseData getExtraLicenseData() {
56 | return new ExtraLicenseResponseData(0L, 0L, 0L);
57 | }
58 |
59 | public void purchase(String productId, boolean isSubscription, String payload) {
60 | }
61 |
62 | public void purchaseGame() {
63 | }
64 | }
--------------------------------------------------------------------------------
/minecraft/src/main/java/com/mojang/minecraftpe/store/googleplay/GooglePlayStore.java:
--------------------------------------------------------------------------------
1 | package com.mojang.minecraftpe.store.googleplay;
2 |
3 | import com.mojang.minecraftpe.MainActivity;
4 | import com.mojang.minecraftpe.store.ExtraLicenseResponseData;
5 | import com.mojang.minecraftpe.store.Store;
6 | import com.mojang.minecraftpe.store.StoreListener;
7 |
8 | public class GooglePlayStore implements Store {
9 | MainActivity mActivity;
10 | StoreListener mListener;
11 |
12 | public GooglePlayStore(MainActivity activity, String licenseKey, StoreListener listener) {
13 | mActivity = activity;
14 | mListener = listener;
15 | mListener.onStoreInitialized(true);
16 | }
17 |
18 | public String getStoreId() {
19 | return "android.googleplay";
20 | }
21 |
22 | public boolean hasVerifiedLicense() {
23 | return true;
24 | }
25 |
26 | public void queryProducts(String[] productIds) {
27 | }
28 |
29 | public void acknowledgePurchase(String receipt, String productType) {
30 | }
31 |
32 | public void queryPurchases() {
33 | }
34 |
35 | public String getProductSkuPrefix() {
36 | return "";
37 | }
38 |
39 | public String getRealmsSkuPrefix() {
40 | return "";
41 | }
42 |
43 | public boolean receivedLicenseResponse() {
44 | return true;
45 | }
46 |
47 | public void destructor() {
48 | }
49 |
50 | @Override
51 | public ExtraLicenseResponseData getExtraLicenseData() {
52 | return new ExtraLicenseResponseData(0L, 0L, 0L);
53 | }
54 |
55 | public void purchase(String productId, boolean isSubscription, String payload) {
56 | }
57 |
58 | public void purchaseGame() {
59 | }
60 | }
--------------------------------------------------------------------------------
/my-release-key.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lyssadev/mb-loader-unofficial/fe6a30125e6baefa396c8853cd4a6bdfab4942eb/my-release-key.jks
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | google {
4 | content {
5 | includeGroupByRegex("com\\.android.*")
6 | includeGroupByRegex("com\\.google.*")
7 | includeGroupByRegex("androidx.*")
8 | }
9 | }
10 | mavenCentral()
11 | gradlePluginPortal()
12 | }
13 | }
14 | dependencyResolutionManagement {
15 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
16 | repositories {
17 | google()
18 | mavenCentral()
19 | maven { url 'https://jitpack.io' }
20 | }
21 | }
22 |
23 | rootProject.name = "mbloader"
24 | include ':app'
25 | include ':minecraft'
26 |
--------------------------------------------------------------------------------