diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 000000000..c3ba3d16b
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,59 @@
+language: android
+sudo: required
+jdk: oraclejdk8
+
+env:
+ global:
+ - ANDROID_API_LEVEL=26
+ - ANDROID_BUILD_TOOLS_VERSION=26.0.0
+ - ANDROID_ABI=armeabi-v7a
+ - ANDROID_ABI=X86
+ - ANDROID_ABI=ARMEABI_V7A
+
+android:
+ components:
+ - tools
+ - build-tools-$ANDROID_BUILD_TOOLS_VERSION
+ - android-$ANDROID_API_LEVEL
+ - extra-android-m2repository
+ licenses:
+ - yes | sudo sdkmanager --licenses
+ - 'android-sdk-preview-license-52d11cd2'
+ - 'android-sdk-license-.+'
+ - 'google-gdk-license-.+'
+
+before_install:
+ - yes | sdkmanager "platforms;android-26"
+ - yes | sdkmanager "build-tools;26.0.0"
+ - yes | sdkmanager "platforms;android-28"
+ - yes | sdkmanager "build-tools;28.0.3"
+
+before_cache:
+ - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
+ - rm -fr $HOME/.gradle/caches/*/plugin-resolution/
+
+cache:
+ directories:
+ - $HOME/.gradle/caches/
+ - $HOME/.gradle/wrapper/
+ - $HOME/.android/build-cache
+
+before_script:
+ - chmod +x gradlew
+
+script:
+ - ./gradlew clean build
+ - ./gradlew test
+
+deploy:
+ provider: releases
+ api-key: $GITHUB_API_KEY
+ file: $TRAVIS_BUILD_DIR/app/build/outputs/apk/debug/app-debug.apk
+ skip_cleanup: true
+ name: autobuild-$TRAVIS_COMMIT
+ body: Automatic build of PojavLauncher from the latest source commit ($TRAVIS_COMMIT) built by Travis CI on $(date +'%F %T %Z').
+ prerelease: true
+ overwrite: true
+ target_commitish: $TRAVIS_COMMIT
+ on:
+ branch: gl4es
diff --git a/README.md b/README.md
index fffe0b0fc..2ae8b0fef 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,156 @@
+
# PojavLauncher
An open source Minecraft: Java Edition launcher for Android based from Boardwalk. Support up-to Minecraft 1.11
(Codes has not been sorted yet, it contains ton of classes without packing to module).
+Discord server: https://discord.gg/6RpEJda
+
+## iOS version?
+- Impossible for directly run. There's RoboVM but is AOT Compiler. You could also try UTM with Android-x86.
+- OpenJDK 9 and GL4ES has iOS port so maybe run in a jailbreaked device. I don't have a Mac OS X device to build one.
+
## About this branch
- This branch attempt to launch Minecraft using command line like `dalvikvm` and `app_process`.
- Status: working partial, EGL Context not yet shared, process get crashed if attempt to execute OpenGL command.
+
## Anything if this successful?
- Able to custom min/max RAM heap.
- Solve some incompatible issues.
+## Installing Forge?
+Not implemented yet.
+
+## Known issues
+- Some Huawei devices can't run Minecraft or OptiFine.
+- Can't run multiple versions at same time.
+
+## FAQ
+### • Unable to drag item in inventory?
+Disable touchscreen mode. Open Minecraft Settings -> Controls -> Touchscreen Mode: Toggle to OFF.
+
+### • Unable to install Minecraft 1.9 or above, can't convert library `net.java.dev.jna`?
+Increase max DX references. Launcher Options -> Settings -> Increase max DX references to 8k.
+
+### • Other bugs or still not working?
+#### Report an issue with:
+- Full error log: press **Show more** and copy.
+#### If it isn't a Minecraft crash:
+- Device name
+- Android version
+
+## Minecraft versions worked in PojavLauncher 2.4.2
+
+
+
+
+## OptiFine worked in PojavLauncher 2.4.2
+|Android version | 9.0 |???|???|Manually Android 10|9.0|
+|-----------------|------|---|---|-----|-----|
+|Minecraft version|1.7.10|1.8|1.9| 1.10| 1.11|
+|OptiFine |OptiFine_1.7.10_HD_U_E7|???|???|OptiFine_1.10_HD_U_H5|OptiFine_1.11_HD_U_F5|
+|Status |[Worked](https://youtu.be/In_EPebQG7Q)|???|???|[Worked (manually)](https://youtu.be/TJeJcPFgzcI)|[Worked (with 1 hack)](https://youtu.be/eIawM9UmQ88)
+
+## A note about 1.12.x
+- Minecraft 1.12.x can be run on Android 8.0 and above by use d8 for desugar and dexing in the latest v2, but will crash in singleplayer.
+
## Solution found!
- [twaik/libcw](https://github.com/twaik/libcw) or [shodruky-rhyammer/gl-streaming](https://github.com/shodruky-rhyammer/gl-streaming) but I'm busy at v3.
+
+## License
+- PojavLauncher is licensed under [GNU GPLv3](https://github.com/khanhduytran0/PojavLauncher/blob/master/LICENSE).
+
+## Using libraries & Third party licenses
+- (v2) Boardwalk: [Apache License 2.0](https://github.com/zhuowei/Boardwalk/blob/master/LICENSE).
+- (v2) LegacyLauncher: (unknown license).
+- (all) Android Support Libraries & DX Dexer: [Apache License 2.0](https://android.googlesource.com/platform/prebuilts/maven_repo/android/+/master/NOTICE.txt).
+- (all) gl4es: [MIT License](https://github.com/ptitSeb/gl4es/blob/master/LICENSE).
+- (v3) BusyBox: [GNU GPLv2 License](https://busybox.net/license.html).
+- (v3) OpenJDK: [GNU GPLv2 License](https://openjdk.java.net/legal/gplv2+ce.html).
+- (v3) PRoot: [GNU GPLv2 License](https://github.com/termux/proot/blob/master/COPYING).
+- (v3) XVnc: [GNU GPLv3 License](https://github.com/theqvd/qvd-client-android/blob/master/LICENSE.txt).
+- (all) LWJGL 2: [Legacy LWJGL License](http://legacy.lwjgl.org/license.php.html).
+
diff --git a/app/build.gradle b/app/build.gradle
index 31ae762c3..54e98665c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,14 +2,19 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 26
- buildToolsVersion '26.0.0'
-
+ dexOptions {
+ javaMaxHeapSize "4g"
+ }
+ lintOptions {
+ abortOnError false
+ }
defaultConfig {
applicationId "net.kdt.pojavlaunch"
minSdkVersion 21
targetSdkVersion 26
versionCode 156235
- versionName "2.5.1_6398b_20200719"
+ versionName "2.5.3_6400b_20200802"
+ multiDexEnabled true //important
}
buildTypes {
@@ -17,7 +22,8 @@ android {
// Don't set to true or java.awt will be a.a or something similar.
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- multiDexEnabled = true
+ // defaultConfig already set
+ // multiDexEnabled = true
debuggable = true
}
}
diff --git a/app/libs/boardwalk_lwjgl.jar b/app/libs/boardwalk_lwjgl.jar
index e56f72079..57866d5f4 100644
Binary files a/app/libs/boardwalk_lwjgl.jar and b/app/libs/boardwalk_lwjgl.jar differ
diff --git a/app/libs/boardwalk_lwjgl_buffer.jar b/app/libs/boardwalk_lwjgl_buffer.jar
new file mode 100644
index 000000000..91750f1f3
Binary files /dev/null and b/app/libs/boardwalk_lwjgl_buffer.jar differ
diff --git a/app/libs/boardwalk_lwjgl_separate.jar b/app/libs/boardwalk_lwjgl_separate.jar
new file mode 100644
index 000000000..cd908238d
Binary files /dev/null and b/app/libs/boardwalk_lwjgl_separate.jar differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index cec705d19..721029be5 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -15,6 +15,9 @@
android:icon="@drawable/ic_launcher"
android:roundIcon="@drawable/ic_launcher"
android:resizeableActivity="true">
+
+
+
@@ -55,6 +63,7 @@
android:screenOrientation="sensorLandscape"
android:name=".prefs.PojavPreferenceActivity"
android:configChanges="keyboardHidden|orientation|screenSize"/>
+
diff --git a/app/src/main/assets/font/minecraft-ten.ttf b/app/src/main/assets/font/minecraft-ten.ttf
new file mode 100644
index 000000000..a81102232
Binary files /dev/null and b/app/src/main/assets/font/minecraft-ten.ttf differ
diff --git a/app/src/main/assets/libraries/org/lwjgl/lwjglboardwalk/2.9.1/lwjglboardwalk-2.9.1.jar b/app/src/main/assets/libraries/org/lwjgl/lwjglboardwalk/2.9.1/lwjglboardwalk-2.9.1.jar
new file mode 100644
index 000000000..1083154e2
Binary files /dev/null and b/app/src/main/assets/libraries/org/lwjgl/lwjglboardwalk/2.9.1/lwjglboardwalk-2.9.1.jar differ
diff --git a/app/src/main/java/com/android/internal/awt/AndroidGraphicsDevice.java b/app/src/main/java/com/android/internal/awt/AndroidGraphicsDevice.java
new file mode 100644
index 000000000..b29a1e617
--- /dev/null
+++ b/app/src/main/java/com/android/internal/awt/AndroidGraphicsDevice.java
@@ -0,0 +1,29 @@
+package com.android.internal.awt;
+
+import java.awt.*;
+
+public class AndroidGraphicsDevice extends GraphicsDevice
+{
+ public GraphicsConfiguration[] mConfigurations = new GraphicsConfiguration[]{new AndroidGraphicsConfiguration()};
+
+ @Override
+ public GraphicsConfiguration[] getConfigurations() {
+ return mConfigurations;
+ }
+
+ @Override
+ public GraphicsConfiguration getDefaultConfiguration() {
+ return mConfigurations[0];
+ }
+
+ @Override
+ public String getIDstring() {
+ return "Android";
+ }
+
+ @Override
+ public int getType() {
+ return TYPE_IMAGE_BUFFER;
+ }
+}
+
diff --git a/app/src/main/java/com/android/internal/awt/AndroidGraphicsEnvironment.java b/app/src/main/java/com/android/internal/awt/AndroidGraphicsEnvironment.java
new file mode 100644
index 000000000..0696f2f3c
--- /dev/null
+++ b/app/src/main/java/com/android/internal/awt/AndroidGraphicsEnvironment.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko, Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package com.android.internal.awt;
+
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import java.util.Locale;
+
+import org.apache.harmony.awt.gl.CommonGraphicsEnvironment;
+import java.awt.*;
+
+/**
+ * AndroidGraphicsEnvironment implementation
+ *
+ */
+public class AndroidGraphicsEnvironment extends CommonGraphicsEnvironment
+{
+ public GraphicsDevice[] mGraphicsDevices = new GraphicsDevice[]{new AndroidGraphicsDevice()};
+
+ @Override
+ public GraphicsDevice getDefaultScreenDevice() throws HeadlessException {
+ return mGraphicsDevices[0];
+ }
+
+ @Override
+ public GraphicsDevice[] getScreenDevices() throws HeadlessException {
+ return mGraphicsDevices;
+ }
+}
diff --git a/app/src/main/java/com/android/internal/awt/AndroidGraphicsFactory.java b/app/src/main/java/com/android/internal/awt/AndroidGraphicsFactory.java
index ca255b559..92a137643 100644
--- a/app/src/main/java/com/android/internal/awt/AndroidGraphicsFactory.java
+++ b/app/src/main/java/com/android/internal/awt/AndroidGraphicsFactory.java
@@ -34,12 +34,12 @@ import org.apache.harmony.awt.gl.CommonGraphics2DFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.content.Context;
+import org.apache.harmony.awt.gl.*;
public class AndroidGraphicsFactory extends CommonGraphics2DFactory {
public GraphicsEnvironment createGraphicsEnvironment(WindowFactory wf) {
- // TODO Auto-generated method stub
- return null;
+ return new AndroidGraphicsEnvironment();
}
public Font embedFont(String fontFilePath) {
diff --git a/app/src/main/java/com/kdt/handleview/ActionPopupWindow.java b/app/src/main/java/com/kdt/handleview/ActionPopupWindow.java
index c5b4c224b..0ee9d9ef7 100644
--- a/app/src/main/java/com/kdt/handleview/ActionPopupWindow.java
+++ b/app/src/main/java/com/kdt/handleview/ActionPopupWindow.java
@@ -47,7 +47,7 @@ public class ActionPopupWindow extends PinnedPopupWindow implements OnClickListe
try {
Field f = perType.getDeclaredField(name);
f.setAccessible(true);
- return f.get(null);
+ return (int) f.get(null);
} catch (Throwable th) {
th.printStackTrace();
}
@@ -63,7 +63,7 @@ public class ActionPopupWindow extends PinnedPopupWindow implements OnClickListe
try {
Field f = perType.getDeclaredField(name);
f.setAccessible(true);
- return f.get(null);
+ return (int) f.get(null);
} catch (Throwable th) {
th.printStackTrace();
}
diff --git a/app/src/main/java/com/kdt/handleview/HandleView.java b/app/src/main/java/com/kdt/handleview/HandleView.java
index 76036de66..34970828c 100644
--- a/app/src/main/java/com/kdt/handleview/HandleView.java
+++ b/app/src/main/java/com/kdt/handleview/HandleView.java
@@ -80,7 +80,7 @@ public abstract class HandleView extends View implements ViewPositionListener, V
try {
Field f = perType.getDeclaredField(name);
f.setAccessible(true);
- return f.get(null);
+ return (int) f.get(null);
} catch (Throwable th) {
th.printStackTrace();
}
diff --git a/app/src/main/java/com/kdt/mcgui/MineButton.java b/app/src/main/java/com/kdt/mcgui/MineButton.java
index 1e4da5b2a..9070f3254 100644
--- a/app/src/main/java/com/kdt/mcgui/MineButton.java
+++ b/app/src/main/java/com/kdt/mcgui/MineButton.java
@@ -7,6 +7,7 @@ import android.util.*;
import android.view.*;
import android.widget.*;
import android.view.View.*;
+import net.kdt.pojavlaunch.*;
public class MineButton extends Button
{
@@ -42,20 +43,16 @@ public class MineButton extends Button
private LayerDrawable layerdrawable, layerdrawablefocus;
- public MineButton(Context ctx)
- {
- super(ctx);
- init();
+ public MineButton(Context ctx) {
+ this(ctx, null);
}
- public MineButton(Context ctx, AttributeSet attrs)
- {
+ public MineButton(Context ctx, AttributeSet attrs) {
super(ctx, attrs);
init();
}
- public void init()
- {
+ public void init() {
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
diff --git a/app/src/main/java/com/kdt/mcgui/MineEditText.java b/app/src/main/java/com/kdt/mcgui/MineEditText.java
index 807547a12..ea842b5d4 100644
--- a/app/src/main/java/com/kdt/mcgui/MineEditText.java
+++ b/app/src/main/java/com/kdt/mcgui/MineEditText.java
@@ -4,6 +4,7 @@ import android.content.*;
import android.util.*;
import android.widget.*;
import net.kdt.pojavlaunch.*;
+import android.graphics.*;
public class MineEditText extends EditText
{
@@ -21,7 +22,8 @@ public class MineEditText extends EditText
public void init()
{
- setBackgroundResource(R.drawable.border_edittext);
+ // setBackgroundResource(R.drawable.border_edittext);
+ setBackgroundColor(Color.parseColor("#131313"));
setPadding(5, 5, 5, 5);
}
}
diff --git a/app/src/main/java/com/kdt/mcgui/app/MineActivity.java b/app/src/main/java/com/kdt/mcgui/app/MineActivity.java
index 39f627d4c..7778b64dc 100644
--- a/app/src/main/java/com/kdt/mcgui/app/MineActivity.java
+++ b/app/src/main/java/com/kdt/mcgui/app/MineActivity.java
@@ -6,39 +6,26 @@ import android.support.v7.app.*;
import android.view.*;
import android.widget.*;
import net.kdt.pojavlaunch.*;
+import java.util.*;
+import android.content.*;
+import com.kdt.mcgui.*;
public class MineActivity extends AppCompatActivity implements View.OnClickListener
{
private int topId = 150001;
private boolean showBeforeView = true;
- private FontChanger fontChanger;
-
private ImageButton menu;
private LinearLayout content, undertop;
private LayoutInflater li;
- public ViewGroup replaceFonts(ViewGroup viewTree)
- {
- if (fontChanger == null) fontChanger = new FontChanger(getAssets(), "font/NotoSans-Bold.ttf");
- return fontChanger.replaceFonts(viewTree);
- }
-
- public View replaceFont(TextView view)
- {
- if (fontChanger == null) fontChanger = new FontChanger(getAssets(), "font/NotoSans-Bold.ttf");
- return fontChanger.replaceFont(view);
- }
-
@Override
- protected void onCreate(Bundle savedInstanceState)
- {
+ protected void onCreate(Bundle savedInstanceState) {
this.onCreate(savedInstanceState, true);
}
- protected void onCreate(Bundle savedInstanceState, boolean showBeforeView)
- {
+ protected void onCreate(Bundle savedInstanceState, boolean showBeforeView) {
super.onCreate(savedInstanceState);
this.showBeforeView = showBeforeView;
@@ -59,10 +46,12 @@ public class MineActivity extends AppCompatActivity implements View.OnClickListe
li.inflate(R.layout.top_bar, top, true);
li.inflate(R.layout.bottom_bar, btm, true);
- replaceFonts(btm);
-
- replaceFont((TextView) top.findViewById(R.id.topbar_language_text));
+ FontChanger.changeFonts(btm);
+ // replaceFont((TextView) top.findViewById(R.id.topbar_navmenu_changelang));
+ Spinner changeLangSpinner = ((Spinner) top.findViewById(R.id.topbar_navmenu_changelang));
+ // Locale l = getResources().getConfiguration().locale;
+
RelativeLayout.LayoutParams conLay = new RelativeLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
conLay.addRule(root.BELOW, topId);
conLay.bottomMargin = 66;
@@ -99,7 +88,7 @@ public class MineActivity extends AppCompatActivity implements View.OnClickListe
}
li.inflate(resource, content, true);
- replaceFonts(content);
+ FontChanger.changeFonts(content);
}
@Override
@@ -111,7 +100,7 @@ public class MineActivity extends AppCompatActivity implements View.OnClickListe
content.addView(view);
if (view instanceof ViewGroup) {
- replaceFonts((ViewGroup) view);
+ FontChanger.changeFonts((ViewGroup) view);
}
}
diff --git a/app/src/main/java/java/awt/GraphicsDevice.java b/app/src/main/java/java/awt/GraphicsDevice.java
index 9eda4e0ed..81dca868e 100644
--- a/app/src/main/java/java/awt/GraphicsDevice.java
+++ b/app/src/main/java/java/awt/GraphicsDevice.java
@@ -21,7 +21,8 @@
package java.awt;
-import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.internal.nls.*;
+import org.lwjgl.opengl.*;
/**
* The GraphicsDevice class describes the graphics devices (such as screens or
@@ -62,7 +63,7 @@ public abstract class GraphicsDevice {
* Constructor is not to be used directly as this class is abstract.
*/
protected GraphicsDevice() {
- displayMode = new DisplayMode(0, 0, DisplayMode.BIT_DEPTH_MULTI,
+ displayMode = new DisplayMode(AndroidDisplay.windowWidth, AndroidDisplay.windowHeight, DisplayMode.BIT_DEPTH_MULTI,
DisplayMode.REFRESH_RATE_UNKNOWN);
}
diff --git a/app/src/main/java/java/awt/GraphicsEnvironment.java b/app/src/main/java/java/awt/GraphicsEnvironment.java
index d527417f7..fd68c607d 100644
--- a/app/src/main/java/java/awt/GraphicsEnvironment.java
+++ b/app/src/main/java/java/awt/GraphicsEnvironment.java
@@ -87,7 +87,10 @@ public abstract class GraphicsEnvironment {
* keyboard, or mouse, false otherwise.
*/
public static boolean isHeadless() {
- return "true".equals(System.getProperty("java.awt.headless"));
+ return false;
+
+ // Disable headless...
+ // "true".equals(System.getProperty("java.awt.headless"));
}
/**
diff --git a/app/src/main/java/java/awt/HeadlessToolkit.java b/app/src/main/java/java/awt/HeadlessToolkit.java
index f652ce3bd..4a1193574 100644
--- a/app/src/main/java/java/awt/HeadlessToolkit.java
+++ b/app/src/main/java/java/awt/HeadlessToolkit.java
@@ -169,14 +169,17 @@ public final class HeadlessToolkit extends ToolkitImpl {
try {
ComponentInternals.setComponentInternals(new ComponentInternalsImpl());
// ???AWT: new EventQueue(this); // create the system EventQueue
- // ???AWT: dispatcher = new Dispatcher(this);
+ // ???AWT:
+ dispatcher = new Dispatcher(this);
desktopProperties = new HashMap();
// ???AWT: desktopPropsSupport = new PropertyChangeSupport(this);
- // ???AWT: awtEventsManager = new AWTEventsManager();
+ // ???AWT:
+ awtEventsManager = new AWTEventsManager();
// ???AWT: dispatchThread = new HeadlessEventDispatchThread(this,
// dispatcher);
// ???AWT: dtk = DTK.getDTK();
- dispatchThread.start();
+
+ // dispatchThread.start();
} finally {
unlockAWT();
}
diff --git a/app/src/main/java/net/kdt/pojavlaunch/DroidToJavaKey.java b/app/src/main/java/net/kdt/pojavlaunch/DroidToJavaKey.java
index 898f8809c..b6b8ade05 100644
--- a/app/src/main/java/net/kdt/pojavlaunch/DroidToJavaKey.java
+++ b/app/src/main/java/net/kdt/pojavlaunch/DroidToJavaKey.java
@@ -44,6 +44,16 @@ public class DroidToJavaKey {
}
*/
+ // Fix press 'e' key close inventory (while search item)
+ // Should it be or other ways?
+ /*
+ if (!AndroidDisplay.grab && keyEvent.getDisplayLabel() != 'e') {
+ mainActivity.sendKeyPress(keyEvent.getDisplayLabel(), status);
+ } else {
+ mainActivity.sendKeyPress(keyEvent.getDisplayLabel());
+ }
+ */
+
mainActivity.sendKeyPress(keyEvent.getDisplayLabel(), status);
}
}
diff --git a/app/src/main/java/net/kdt/pojavlaunch/FatalErrorActivity.java b/app/src/main/java/net/kdt/pojavlaunch/FatalErrorActivity.java
new file mode 100644
index 000000000..236221d11
--- /dev/null
+++ b/app/src/main/java/net/kdt/pojavlaunch/FatalErrorActivity.java
@@ -0,0 +1,73 @@
+package net.kdt.pojavlaunch;
+
+import android.app.*;
+import android.content.*;
+import android.os.*;
+import android.support.v7.app.*;
+import android.util.*;
+import java.awt.*;
+import java.awt.datatransfer.*;
+
+import android.support.v7.app.AlertDialog;
+
+public class FatalErrorActivity extends AppCompatActivity
+{
+ public static void showError(Context ctx, String savePath, boolean storageAllow, /* boolean isFatalErr, */ Throwable th) {
+ Intent ferrorIntent = new Intent(ctx, FatalErrorActivity.class);
+ ferrorIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ ferrorIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ ferrorIntent.putExtra("throwable", th);
+ ferrorIntent.putExtra("savePath", savePath);
+ ferrorIntent.putExtra("storageAllow", storageAllow);
+ // ferrorIntent.putExtra("isFatal", isFatalErr);
+ ctx.startActivity(ferrorIntent);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Bundle extras = getIntent().getExtras();
+ boolean storageAllow = extras.getBoolean("storageAllow");
+ final String strStackTrace = Log.getStackTraceString((Throwable) extras.getSerializable("throwable"));
+ String strSavePath = extras.getString("savePath");
+ String errHeader = storageAllow ?
+ "Crash stack trace saved to " + strSavePath + "." :
+ "Storage permission is required to save crash stack trace!";
+
+ // boolean isFatalError = extras.getBoolean("isFatal", false);
+
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.error_fatal)
+ .setMessage(errHeader + "\n\n" + strStackTrace)
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
+
+ @Override
+ public void onClick(DialogInterface p1, int p2) {
+ finish();
+ }
+ })
+ .setNegativeButton(R.string.global_restart, new DialogInterface.OnClickListener(){
+
+ @Override
+ public void onClick(DialogInterface p1, int p2) {
+ startActivity(new Intent(FatalErrorActivity.this, PojavLoginActivity.class));
+ }
+ })
+ .setNeutralButton(android.R.string.copy, new DialogInterface.OnClickListener(){
+
+ @Override
+ public void onClick(DialogInterface p1, int p2) {
+ StringSelection errData = new StringSelection(strStackTrace);
+ Toolkit.getDefaultToolkit().getSystemClipboard().setContents(errData, null);
+
+ finish();
+ }
+ })
+ //.setNegativeButton("Report (not available)", null)
+ .setCancelable(false)
+ .show();
+
+ // Tools.showError(this, isFatalError ? R.string.error_fatal : R.string.global_error, th, true);
+ }
+}
diff --git a/app/src/main/java/net/kdt/pojavlaunch/FontChanger.java b/app/src/main/java/net/kdt/pojavlaunch/FontChanger.java
index dd24642d0..8b3f6815f 100644
--- a/app/src/main/java/net/kdt/pojavlaunch/FontChanger.java
+++ b/app/src/main/java/net/kdt/pojavlaunch/FontChanger.java
@@ -4,37 +4,31 @@ import android.content.res.*;
import android.graphics.*;
import android.view.*;
import android.widget.*;
+import android.content.*;
+import com.kdt.mcgui.*;
public class FontChanger
{
- private Typeface typeface;
-
- public FontChanger(Typeface typeface)
- {
- this.typeface = typeface;
- }
-
- public FontChanger(AssetManager assets, String assetsFontFileName)
- {
- typeface = Typeface.createFromAsset(assets, assetsFontFileName);
- }
-
- public ViewGroup replaceFonts(ViewGroup viewTree)
- {
- View child;
+ private static Typeface fNotoSans, fMinecraftTen;
+
+ public static void initFonts(Context ctx) {
+ fNotoSans = Typeface.createFromAsset(ctx.getAssets(), "font/NotoSans-Bold.ttf");
+ fMinecraftTen = Typeface.createFromAsset(ctx.getAssets(), "font/minecraft-ten.ttf");
+ }
+
+ public static void changeFonts(ViewGroup viewTree) {
+ View child;
for(int i = 0; i < viewTree.getChildCount(); ++i) {
child = viewTree.getChildAt(i);
if (child instanceof ViewGroup) {
- replaceFonts((ViewGroup)child);
+ changeFonts((ViewGroup) child);
} else if (child instanceof TextView) {
- replaceFont((TextView) child);
+ changeFont((TextView) child);
}
}
- return viewTree;
- }
+ }
- public View replaceFont(TextView view) {
- view.setTypeface(typeface);
- return view;
+ public static void changeFont(TextView view) {
+ view.setTypeface(view instanceof MineButton ? fMinecraftTen : fNotoSans);
}
}
diff --git a/app/src/main/java/net/kdt/pojavlaunch/JMinecraftVersionList.java b/app/src/main/java/net/kdt/pojavlaunch/JMinecraftVersionList.java
index d528ccb02..d651eedd7 100644
--- a/app/src/main/java/net/kdt/pojavlaunch/JMinecraftVersionList.java
+++ b/app/src/main/java/net/kdt/pojavlaunch/JMinecraftVersionList.java
@@ -13,7 +13,7 @@ public class JMinecraftVersionList {
public Version[] versions;
public static class Version {
- // Since 1.13
+ // Since 1.13, so it's one of ways to check
public Arguments arguments;
public String assets;
diff --git a/app/src/main/java/net/kdt/pojavlaunch/MCLauncherActivity.java b/app/src/main/java/net/kdt/pojavlaunch/MCLauncherActivity.java
index 23085aa02..486dd5acc 100644
--- a/app/src/main/java/net/kdt/pojavlaunch/MCLauncherActivity.java
+++ b/app/src/main/java/net/kdt/pojavlaunch/MCLauncherActivity.java
@@ -67,13 +67,29 @@ public class MCLauncherActivity extends AppCompatActivity
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
-
gson = new Gson();
DisplayMetrics dm = Tools.getDisplayMetrics(this);
AndroidDisplay.windowWidth = dm.widthPixels;
AndroidDisplay.windowHeight = dm.heightPixels;
viewInit();
+
+ final View decorView = getWindow().getDecorView();
+ decorView.setOnSystemUiVisibilityChangeListener (new View.OnSystemUiVisibilityChangeListener() {
+ @Override
+ public void onSystemUiVisibilityChange(int visibility) {
+ if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
+ decorView.setSystemUiVisibility(
+ View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
+ }
+ }
+ });
+
+
}
// DEBUG
//new android.support.design.widget.NavigationView(this);
@@ -116,7 +132,7 @@ public class MCLauncherActivity extends AppCompatActivity
} catch(Exception e) {
//Tools.throwError(this, e);
e.printStackTrace();
- toast(getStr(R.string.toast_login_error) + " " + e.getMessage());
+ toast(getStr(R.string.toast_login_error, e.getMessage()));
finish();
}
@@ -400,9 +416,11 @@ public class MCLauncherActivity extends AppCompatActivity
}
@Override
- protected void onResume()
- {
+ protected void onResume(){
super.onResume();
+ final int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+ final View decorView = getWindow().getDecorView();
+ decorView.setSystemUiVisibility(uiOptions);
}
private boolean canBack = false;
@@ -533,6 +551,7 @@ public class MCLauncherActivity extends AppCompatActivity
libItem.name.startsWith("com.mojang:realms") ||
libItem.name.startsWith("net.java.jinput") ||
libItem.name.startsWith("net.minecraft.launchwrapper") ||
+ libItem.name.startsWith("optifine:launchwrapper-of") ||
// libItem.name.startsWith("org.lwjgl.lwjgl:lwjgl") ||
libItem.name.startsWith("org.lwjgl") ||
libItem.name.startsWith("tv.twitch")
@@ -610,7 +629,7 @@ public class MCLauncherActivity extends AppCompatActivity
}
}
- publishProgress("5", getStr(R.string.mcl_launch_download_client) + p1[0]);
+ publishProgress("5", getStr(R.string.mcl_launch_download_client, p1[0]));
outUnpatchedConvert = new File(unpatchedPath);
boolean patchedExist = new File(patchedFile).exists();
if (!patchedExist) {
diff --git a/app/src/main/java/net/kdt/pojavlaunch/MainActivity.java b/app/src/main/java/net/kdt/pojavlaunch/MainActivity.java
index ef7364814..189d54a74 100644
--- a/app/src/main/java/net/kdt/pojavlaunch/MainActivity.java
+++ b/app/src/main/java/net/kdt/pojavlaunch/MainActivity.java
@@ -3,7 +3,6 @@ package net.kdt.pojavlaunch;
import android.app.*;
import android.content.*;
import android.graphics.*;
-import android.graphics.drawable.*;
import android.os.*;
import android.support.design.widget.*;
import android.support.v4.widget.*;
@@ -22,17 +21,16 @@ import java.io.*;
import java.lang.reflect.*;
import java.security.*;
import java.util.*;
-import javax.crypto.*;
import javax.microedition.khronos.egl.*;
import javax.microedition.khronos.opengles.*;
import net.kdt.pojavlaunch.exit.*;
import net.kdt.pojavlaunch.prefs.*;
+import net.kdt.pojavlaunch.value.customcontrols.*;
import optifine.*;
import org.apache.harmony.security.fortress.*;
import org.lwjgl.input.*;
import org.lwjgl.opengl.*;
-import org.lwjgl.util.applet.*;
-import org.lwjgl.util.glu.tessellation.*;
+import sun.security.jca.*;
import android.app.AlertDialog;
import android.graphics.drawable.Drawable;
@@ -40,6 +38,7 @@ import net.kdt.pojavlaunch.value.customcontrols.*;
import com.google.android.gles_jni.*;
import com.kdt.minecraftegl.*;
+
public class MainActivity extends AppCompatActivity implements OnTouchListener, OnClickListener
{
public static final String initText = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ";
@@ -127,6 +126,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
private boolean lastGrab = false;
private boolean isExited = false;
private boolean isLogAllow = false;
+ private int navBarHeight = 40;
// private static Collection extends Provider.Service> rsaPkcs1List;
@@ -141,11 +141,100 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
setContentView(R.layout.main);
try {
+ final View decorView = getWindow().getDecorView();
+ decorView.setOnSystemUiVisibilityChangeListener (new View.OnSystemUiVisibilityChangeListener() {
+ @Override
+ public void onSystemUiVisibilityChange(int visibility) {
+ if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
+ decorView.setSystemUiVisibility(
+ View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
+ }
+ }
+ });
+
+ /*
+ ExitManager.setExitTrappedListener(new ExitManager.ExitTrappedListener(){
+ @Override
+ public void onExitTrapped()
+ {
+ runOnUiThread(new Runnable(){
+
+ @Override
+ public void run() {
+ isExited = true;
+
+ try {
+ SecondaryDexLoader.resetFieldArray(getClassLoader());
+ } catch (Throwable th) {
+ th.printStackTrace();
+ }
+
+ AlertDialog.Builder d = new AlertDialog.Builder(MainActivity.this);
+ d.setTitle(R.string.mcn_exit_title);
+
+ try {
+ File crashLog = Tools.lastFileModified(Tools.crashPath);
+ if(crashLog != null && Tools.read(crashLog.getAbsolutePath()).startsWith("---- Minecraft Crash Report ----")){
+ d.setMessage(R.string.mcn_exit_crash);
+ } else {
+ fullyExit();
+ return;
+ }
+ } catch (Throwable th) {
+ d.setMessage(getStr(R.string.mcn_exit_errcrash) + "\n" + Log.getStackTraceString(th));
+ }
+ d.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
+
+ @Override
+ public void onClick(DialogInterface p1, int p2)
+ {
+ fullyExit();
+ }
+ });
+ d.setCancelable(false);
+ d.show();
+ }
+ });
+ }
+ });
+
+ try {
+ ExitManager.disableSystemExit();
+ } catch (Throwable th) {
+ Log.w(Tools.APP_NAME, "Could not disable System.exit() method!", th);
+ }
+
+ */
+ File optDir = getDir("dalvik-cache", 0);
+ optDir.mkdirs();
+ launchOptimizedDirectory = optDir.getAbsolutePath();
+
+
+
mProfile = PojavProfile.getCurrentProfileContent(this);
mVersionInfo = Tools.getVersionInfo(mProfile.getVersion());
setTitle("Minecraft " + mProfile.getVersion());
//System.loadLibrary("gl4es");
+ /*
+ if (mVersionInfo.arguments != null) {
+ System.loadLibrary("lwjgl32");
+ System.loadLibrary("lwjgl_opengl32");
+ System.loadLibrary("lwjgl_stb32");
+ }
+ */
+
+ if (mVersionInfo.arguments == null) {
+ // Minecraft 1.12 and below
+
+ // TODO uncomment after fix
+ // SecondaryDexLoader.install(getClassLoader(), Arrays.asList(new File[]{new File(Tools.libraries + "/" + Tools.artifactToPath("org.lwjgl", "lwjglboardwalk", "2.9.1"))}), optDir);
+ }
+
this.displayMetrics = Tools.getDisplayMetrics(this);
AndroidDisplay.windowWidth = displayMetrics.widthPixels / scaleFactor;
@@ -598,6 +687,10 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
AndroidContextImplementation.draw = egl10.eglGetCurrentSurface(EGL10.EGL_DRAW);
egl10.eglMakeCurrent(AndroidContextImplementation.display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
System.out.println(new StringBuffer().append("Gave up context: ").append(AndroidContextImplementation.context).toString());
+
+
+ AndroidDisplay.windowWidth += navBarHeight;
+
*/
EGLContextImpl eglContextImpl = (EGLContextImpl) egl10.eglGetCurrentContext();
@@ -608,6 +701,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
} catch (Throwable th) {
Tools.showError(MainActivity.this, th, true);
}
+
new Thread(new Runnable(){
@@ -636,7 +730,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
});
glSurfaceView.setPreserveEGLContextOnPause(true);
glSurfaceView.setRenderMode(MinecraftGLView.RENDERMODE_CONTINUOUSLY);
- glSurfaceView.requestRender();
+ // glSurfaceView.requestRender();
} catch (Throwable e) {
e.printStackTrace();
Tools.showError(this, e, true);
@@ -693,7 +787,10 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
public void onResume() {
super.onResume();
mIsResuming = true;
- glSurfaceView.requestRender();
+ if (glSurfaceView != null) glSurfaceView.requestRender();
+ final int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+ final View decorView = getWindow().getDecorView();
+ decorView.setSystemUiVisibility(uiOptions);
}
@Override
@@ -927,7 +1024,20 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
public static String launchOptimizedDirectory;
public static String launchLibrarySearchPath;
private void runCraft(long eglContext) throws Throwable
+
{
+ LoggerJava.OnStringPrintListener printLog = new LoggerJava.OnStringPrintListener(){
+ @Override
+ public void onCharPrint(char c) {
+ appendToLog(Character.toString(c));
+ }
+ };
+
+ PrintStream theStreamErr = new PrintStream(new LoggerJava.LoggerOutputStream(System.err, printLog));
+ PrintStream theStreamOut = new PrintStream(new LoggerJava.LoggerOutputStream(System.out, printLog));
+ System.setErr(theStreamErr);
+ System.setOut(theStreamOut);
+
String[] launchArgs = getMCArgs();
// Setup OptiFine
@@ -938,17 +1048,24 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
AndroidOptiFineUtilities.originalOptifineJar = PojavPreferenceActivity.PREF_FORGETOF ? "/null/file.jar" : optifineJar;
}
- File optDir = getDir("dalvik-cache", 0);
- optDir.mkdirs();
-
- launchClassPath = Tools.generate(mProfile.getVersion());
- launchOptimizedDirectory = optDir.getAbsolutePath();
+ launchClassPath = Tools.generateLaunchClassPath(mProfile.getVersion());
launchLibrarySearchPath = getApplicationInfo().nativeLibraryDir;
/* gl4es
if (mVersionInfo.mainClass.equals("net.minecraft.launchwrapper.Launch")) {
net.minecraft.launchwrapper.Launch.main(launchArgs);
} else {
+/*
+ PrintStream theStreamErr = new PrintStream(new LoggerJava.LoggerOutputStream(System.err, printLog));
+ System.setErr(theStreamErr);
+*/
+ fixRSAPadding(this);
+
+ appendlnToLog("Running Minecraft with classpath: \n" + launchClassPath + "\n", false);
+
+ // Load classpath
+ DexClassLoader launchBaseLoader = new DexClassLoader(launchClassPath, launchOptimizedDirectory, launchLibrarySearchPath, getClassLoader());
+
LoggerJava.OnStringPrintListener printLog = new LoggerJava.OnStringPrintListener(){
@Override
public void onCharPrint(char c) {
@@ -963,6 +1080,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
ShellProcessOperation shell = new ShellProcessOperation(new ShellProcessOperation.OnPrintListener(){
+
@Override
public void onPrintLine(String text) {
appendToLog(text);
@@ -1012,59 +1130,107 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
});
}
+ public static void fixRSAPadding(final Activity act) {
+/*
private void createEGLHackStuff() {
}
- public void fixRSAPadding() throws Exception {
+*/
// welcome to the territory of YOLO; I'll be your tour guide for today.
+ final boolean isLegacyPatch = Build.VERSION.SDK_INT < 24;
+
try {
- List rsaList, rsaPkcs1List;
- if (android.os.Build.VERSION.SDK_INT > 23) { // Nougat
- /*
- * Since Android 7, it use OpenJDK sun.security.jca.GetInstance
- * But it's not part of Android SDK.
- */
- rsaList = getCipherServices("RSA");
- rsaPkcs1List = getCipherServices("RSA/ECB/PKCS1PADDING");
- } else {
- rsaList = Services.getServices("Cipher.RSA");
- rsaPkcs1List = Services.getServices("Cipher.RSA/ECB/PKCS1PADDING");
- }
+ if (!isLegacyPatch) {
+ /*
+ System.out.println("RSAPadding BEFORE");
+ debug_printServiceInfo(System.out, "Cipher.RSA");
+ */
- /*
- * Not .clear() directly since the entry removal is protected,
- * so some reflections to reset it
- */
- Modifiable.resetServiceList(rsaList);
- rsaList.addAll(rsaPkcs1List);
+ Map rsaMap, rsaPkcs1Map;
+ rsaMap = getCipherServicesMap("Cipher", "RSA");
+ rsaPkcs1Map = getCipherServicesMap("Cipher", "RSA/ECB/PKCS1PADDING");
+
+ for (Map.Entry set : rsaMap.entrySet()) {
+ System.out.println(set.getKey().getName() + ": ");
+ for (Map.Entry en : set.getKey().entrySet()) {
+ if (en.getKey().toString().contains("Cipher.RSA"))
+ System.out.println(en.getKey().toString() + " = " + en.getValue().toString());
+ }
+
+ set.getKey().remove("Cipher.RSA SupportedKeyFormats");
+
+ int spend = 0;
+ for (Map.Entry s : rsaPkcs1Map.entrySet()) {
+ if (spend == 0) {
+ set.getKey().put("Cipher.RSA", s.getValue().getClassName());
+ set.getKey().put("Cipher.RSA SupportedKeyClasses", s.getKey().get("Cipher.RSA/ECB/PKCS1Padding SupportedKeyClasses"));
+
+ List rsaAliasList = Modifiable.getServiceAliases(set.getValue());
+ rsaAliasList.clear();
+ rsaAliasList.addAll(Modifiable.getServiceAliases(s.getValue()));
+
+ spend++;
+ }
+ }
+
+ // printList(set.getKey().getServices());
+
+ /*
+ System.out.println("RSAPadding AFTER");
+ debug_printServiceInfo(System.out, "Cipher.RSA");
+ */
+ }
+ } else {
+ Collection rsaList, rsaPkcs1List;
+ rsaList = getCipherServices("Cipher", "RSA");
+ rsaPkcs1List = getCipherServices("Cipher", "RSA/ECB/PKCS1PADDING");
+
+ rsaList.clear();
+ rsaList.addAll(rsaPkcs1List);
+ }
} catch (Throwable th) {
th.printStackTrace();
final File rsaFixFile = new File(Tools.MAIN_PATH, "rsapadding_error.txt");
- // Debug information
- PrintStream rsaFixStream = new PrintStream(rsaFixFile);
- rsaFixStream.println("--- RSA PADDING ERROR ---");
- rsaFixStream.println("• Error stack trace");
- th.printStackTrace(rsaFixStream);
- rsaFixStream.println();
- rsaFixStream.println("• RSAPadding info");
- rsaFixStream.println(" - Patch method: " + (Build.VERSION.SDK_INT < 24 ? "Direct (no" : "Reflection Bypass (with") + " security check)");
- rsaFixStream.println(" - getDeclaredMethods() return");
- debug_printMethodInfo(rsaFixStream, Provider.class.getDeclaredMethods());
- rsaFixStream.println(" - getMethods() return");
- debug_printMethodInfo(rsaFixStream, Provider.class.getMethods());
- rsaFixStream.println("• System info");
- rsaFixStream.println(" - Android version " + Build.VERSION.RELEASE + " (API " + Integer.toString(Build.VERSION.SDK_INT) + ")");
- rsaFixStream.close();
+ try {
+ // Debug information
+ PrintStream rsaFixStream = new PrintStream(rsaFixFile);
+ rsaFixStream.println("--- RSA PADDING ERROR ---");
+ rsaFixStream.println("• Error stack trace");
+ th.printStackTrace(rsaFixStream);
+ rsaFixStream.println();
+ rsaFixStream.println("• RSAPadding info");
+ rsaFixStream.println(" - Patch method: " + (isLegacyPatch ? "Apache Harmony" : "OpenJDK sun.security.jca"));
+ if (!isLegacyPatch) {
+ rsaFixStream.println(" - sun.security.jca.ProviderList:");
+ debug_printMethodInfo(rsaFixStream, ProviderList.class.getDeclaredMethods());
+ }
+ rsaFixStream.println("• System info");
+ rsaFixStream.println(" - Android version " + Build.VERSION.RELEASE + " (API " + Integer.toString(Build.VERSION.SDK_INT) + ")");
+ rsaFixStream.close();
+
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
- runOnUiThread(new Runnable(){
+
+ final String errMsg = "Unable to fix RSAPadding. Premium features is limited!" +
+ (Build.VERSION.SDK_INT == 23 ?
+ "Android 6 currently don't have solution" :
+ "Send the file at " + rsaFixFile.getAbsolutePath() + " to the developer");
+
+ if (act != null) {
+ act.runOnUiThread(new Runnable(){
@Override
public void run() {
- Toast.makeText(MainActivity.this, "Unable to fix RSAPadding. Premium features is limited! Send the file at " + rsaFixFile.getAbsolutePath() + " to the developer", Toast.LENGTH_LONG).show();
+ Toast.makeText(act, errMsg, Toast.LENGTH_LONG).show();
}
});
+ } else {
+ System.err.println("RSAPadding error: " + errMsg);
+ }
}
/*
@@ -1077,13 +1243,19 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
*/
}
- private List getCipherServices(String algorithm) throws InvocationTargetException, SecurityException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, ClassNotFoundException {
- return (List) Class.forName("sun.security.jca.GetInstance")
- .getDeclaredMethod("getServices", String.class, String.class)
- .invoke(null, new Object[]{"Cipher", algorithm});
+ private static void debug_printServiceInfo(PrintStream stream, String key) {
+ String[] keyArr = key.split(".");
+ for (Provider p : getCipherServicesMap(keyArr[0], keyArr[1]).keySet()) {
+ stream.println("- " + p.getName() + ": " + p.getInfo());
+ for (Provider.Service s : p.getServices()) {
+ if (s.getAlgorithm().contains(key)) {
+ stream.println(s.toString());
+ }
+ }
+ }
}
- private void debug_printMethodInfo(PrintStream stream, Method[] methods) {
+ private static void debug_printMethodInfo(PrintStream stream, Method[] methods) {
StringBuilder methodInfo = new StringBuilder();
for (Method method : methods) {
methodInfo.setLength(0);
@@ -1126,6 +1298,45 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
stream.println(methodInfo);
}
}
+
+ // From org.apache.harmony.security.fortress.Services:getServices(String type, String algorithm)
+ private static synchronized Collection getCipherServices(String type, String algorithm) {
+ if (Build.VERSION.SDK_INT < 23) {
+ // 5.1 (Lollipop) and below
+ return Services.getServices(type + "." + algorithm);
+ } else if (Build.VERSION.SDK_INT == 23) {
+ // 6.0 (Marshmallow) only
+ return Services.getServices(type, algorithm);
+ } else {
+ return getCipherServicesMap(type, algorithm).values();
+ }
+ }
+
+ private static synchronized Map getCipherServicesMap(String type, String algorithm) {
+ // 7.0 (Nougat) and above
+ ProviderList providerList = Providers.getProviderList();
+ Map services = null;
+
+ // Android 10
+ if (Build.VERSION.SDK_INT >= 29) {
+ services = new ArrayMap<>();
+ Provider.Service service = providerList.getService(type, algorithm);
+ services.put(service.getProvider(), service);
+ } else {
+ List providers = providerList.providers();
+ for (Provider p : providers) {
+ Provider.Service s = p.getService(type, algorithm);
+ if (s != null) {
+ if (services == null) {
+ services = new ArrayMap<>(providers.size());
+ }
+ services.put(p, s);
+ }
+ }
+ }
+ return services;
+ }
+
public void printStream(InputStream stream) {
try {
@@ -1182,12 +1393,24 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
WindowAnimation.fadeOut(contentCanvas, 500);
}
*/
+ private void appendToLog(String text) {
+ appendToLog(text, true);
+ }
+
private void appendlnToLog(String text) {
- appendToLog(text + "\n");
+ appendlnToLog(text, true);
+ }
+
+ private void appendlnToLog(String text, boolean checkAllow) {
+ appendToLog(text + "\n", checkAllow);
}
+ private void appendToLog(final String text, boolean checkAllow) {
+ if (checkAllow && !isLogAllow) return;
+/*
private void appendToLog(final String text) {
- // if (!isLogAllow) return;
+ */
+ // if (!isLogAllow) r
textLog.post(new Runnable(){
@Override
public void run()
diff --git a/app/src/main/java/net/kdt/pojavlaunch/Modifiable.java b/app/src/main/java/net/kdt/pojavlaunch/Modifiable.java
index 0f87fb44d..f33c18601 100644
--- a/app/src/main/java/net/kdt/pojavlaunch/Modifiable.java
+++ b/app/src/main/java/net/kdt/pojavlaunch/Modifiable.java
@@ -38,19 +38,12 @@ public class Modifiable
return (Set) modifyCollection(set);
}
- // Get modifiable list from ServiceList
- public static void resetServiceList(List list) throws Throwable {
- Class> listClass = Class.forName("sun.security.jca.ProviderList$ServiceList");
- Field servicesField = listClass.getDeclaredField("services");
- Field firstServiceField = listClass.getDeclaredField("firstService");
-
- servicesField.setAccessible(true);
- firstServiceField.setAccessible(true);
-
- List services = (List) servicesField.get(list);
- firstServiceField.set(list, null);
- if (services == null) {
- System.err.println("ServiceList is null, how to erase?");
- } else services.clear();
+ // Get alias list from Provider.Service
+ public static List getServiceAliases(Provider.Service service) throws Throwable {
+ Method getAliasesMethod = service.getClass().getDeclaredMethod("getAliases");
+ getAliasesMethod.setAccessible(true);
+ return (List) getAliasesMethod.invoke(service);
}
+
+
}
diff --git a/app/src/main/java/net/kdt/pojavlaunch/PojavApplication.java b/app/src/main/java/net/kdt/pojavlaunch/PojavApplication.java
index fa4bda491..384ed1e22 100644
--- a/app/src/main/java/net/kdt/pojavlaunch/PojavApplication.java
+++ b/app/src/main/java/net/kdt/pojavlaunch/PojavApplication.java
@@ -8,13 +8,50 @@ import net.kdt.pojavlaunch.prefs.*;
import net.kdt.pojavlaunch.value.customcontrols.*;
import android.support.v7.preference.*;
import java.io.*;
+import android.content.*;
+import android.support.v4.app.*;
+import android.util.*;
+import net.kdt.pojavlaunch.exit.*;
+import java.time.*;
+import java.text.*;
+import java.util.*;
public class PojavApplication extends Application
{
+ public static String CRASH_REPORT_TAG = "PojavCrashReport";
+
@Override
public void onCreate() {
- super.onCreate();
+ Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){
+ @Override
+ public void uncaughtException(Thread thread, Throwable th) {
+ boolean storagePermAllowed = Build.VERSION.SDK_INT < 23 || ActivityCompat.checkSelfPermission(PojavApplication.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
+ File crashFile = new File(storagePermAllowed ? Tools.MAIN_PATH : Tools.datapath, "latestcrash.txt");
+ try {
+ // Write to file, since some devices may not able to show error
+ crashFile.createNewFile();
+ PrintStream crashStream = new PrintStream(crashFile);
+ crashStream.append("PojavLauncher crash report\n");
+ crashStream.append(" - Time: " + DateFormat.getDateTimeInstance().format(new Date()));
+ crashStream.append(" - Device: " + Build.PRODUCT + " " + Build.MODEL);
+ crashStream.append(" - Android version: " + Build.VERSION.RELEASE);
+ crashStream.append(" - Crash stack trace:");
+ crashStream.append(Log.getStackTraceString(th));
+ crashStream.close();
+ } catch (Throwable th2) {
+ Log.e(CRASH_REPORT_TAG, " - Exception attempt saving crash stack trace:", th2);
+ Log.e(CRASH_REPORT_TAG, " - The crash stack trace was:", th);
+ }
+
+ FatalErrorActivity.showError(PojavApplication.this, crashFile.getAbsolutePath(), storagePermAllowed, th);
+ // android.os.Process.killProcess(android.os.Process.myPid());
+
+ MainActivity.fullyExit();
+ }
+ });
+
try {
+ super.onCreate();
Tools.APP_NAME = getResources().getString(R.string.app_short_name);
PackageInfo thisApp = getPackageManager().getPackageInfo(getPackageName(), 0);
@@ -37,11 +74,11 @@ public class PojavApplication extends Application
specialButtons[3].name = getString(R.string.control_secondary);
specialButtons[4].name = getString(R.string.control_mouse);
- new File(Tools.CTRLMAP_PATH).mkdirs();
- new CustomControls(this).save(Tools.CTRLDEF_FILE);
-
- } catch (Exception e) {
- e.printStackTrace();
+ FontChanger.initFonts(this);
+ } catch (Throwable th) {
+ Intent ferrorIntent = new Intent(this, FatalErrorActivity.class);
+ ferrorIntent.putExtra("throwable", th);
+ startActivity(ferrorIntent);
}
}
}
diff --git a/app/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java b/app/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java
index 79de49305..79f75e344 100644
--- a/app/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java
+++ b/app/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java
@@ -22,26 +22,31 @@ import android.system.*;
import android.net.*;
import static android.view.ViewGroup.LayoutParams.*;
import net.kdt.pojavlaunch.update.*;
+import net.kdt.pojavlaunch.value.customcontrols.*;
+import android.support.v7.app.AppCompatActivity;
-public class PojavLoginActivity extends MineActivity
+public class PojavLoginActivity extends AppCompatActivity
+// MineActivity
{
private EditText edit2, edit3;
private int REQUEST_STORAGE_REQUEST_CODE = 1;
private ProgressBar prb;
- private Switch sRemember, sOffline;
+ private CheckBox sRemember, sOffline;
+ private LinearLayout loginLayout;
+ private ImageView imageLogo;
private boolean isPromptingGrant = false;
// private boolean isPermGranted = false;
private SharedPreferences firstLaunchPrefs;
// private String PREF_IS_DONOTSHOWAGAIN_WARN = "isWarnDoNotShowAgain";
- private String PREF_IS_INSTALLED_LIBRARIES = "isLibrariesExtracted";
+ private String PREF_IS_INSTALLED_LIBRARIES = "isLibrariesExtracted2";
private boolean isInitCalled = false;
@Override
protected void onCreate(Bundle savedInstanceState)
{
- super.onCreate(savedInstanceState, false);
+ super.onCreate(savedInstanceState); // false);
if (!isInitCalled) {
init();
isInitCalled = true;
@@ -130,7 +135,7 @@ public class PojavLoginActivity extends MineActivity
LinearLayout startScr = new LinearLayout(PojavLoginActivity.this);
LayoutInflater.from(PojavLoginActivity.this).inflate(R.layout.start_screen, startScr);
- replaceFonts(startScr);
+ FontChanger.changeFonts(startScr);
progress = (ProgressBar) startScr.findViewById(R.id.startscreenProgress);
//startScr.addView(progress);
@@ -229,14 +234,23 @@ public class PojavLoginActivity extends MineActivity
}
private void uiInit() {
- setContentView(R.layout.launcher_login);
+ setContentView(R.layout.launcher_login_v2);
- edit2 = (EditText) findViewById(R.id.launcherAccEmail);
- edit3 = (EditText) findViewById(R.id.launcherAccPassword);
+ loginLayout = findViewById(R.id.login_layout_linear);
+ imageLogo = findViewById(R.id.login_image_logo);
+ loginLayout.postDelayed(new Runnable(){
+ @Override
+ public void run(){
+ imageLogo.setTranslationY(loginLayout.getY() - (imageLogo.getHeight() / 2f));
+ }
+ }, 100);
+
+ edit2 = (EditText) findViewById(R.id.login_edit_email);
+ edit3 = (EditText) findViewById(R.id.login_edit_password);
if(prb == null) prb = (ProgressBar) findViewById(R.id.launcherAccProgress);
- sRemember = (Switch) findViewById(R.id.launcherAccRememberSwitch);
- sOffline = (Switch) findViewById(R.id.launcherAccOffSwitch);
+ sRemember = findViewById(R.id.login_switch_remember);
+ sOffline = findViewById(R.id.login_switch_offline);
sOffline.setOnCheckedChangeListener(new OnCheckedChangeListener(){
@Override
@@ -248,29 +262,14 @@ public class PojavLoginActivity extends MineActivity
});
}
- private boolean isAndroid7()
- {
- return Build.VERSION.SDK_INT >= 24;
- }
-
- /*
-
- long lastTime = System.currentTimeMillis();
- long lastDel = 0;
-
-
- private void deAnr(String msg) {
- long currt = System.currentTimeMillis();
- lastDel = currt - lastTime;
- lastTime = currt;
- System.out.println("Time:" + lastDel + "ms||" + (lastDel / 1000) + "s: " + msg);
- }
- */
-
@Override
public void onResume() {
super.onResume();
+ if (loginLayout != null && imageLogo != null) {
+ imageLogo.setTranslationY(loginLayout.getY() - (imageLogo.getHeight() / 2f));
+ }
+
// Clear current profile
PojavProfile.setCurrentProfile(this, null);
}
@@ -304,10 +303,13 @@ public class PojavLoginActivity extends MineActivity
try {
file3.createNewFile();
} catch (IOException e){}
-
+
try {
mkdirs(Tools.MAIN_PATH);
+ mkdirs(Tools.CTRLMAP_PATH);
+ new CustomControls(this).save(Tools.CTRLDEF_FILE);
+
Tools.copyAssetFile(this, "options.txt", Tools.MAIN_PATH, false);
// Extract launcher_profiles.json
@@ -334,10 +336,10 @@ public class PojavLoginActivity extends MineActivity
private boolean mkdirs(String path)
{
- File mFileeee = new File(path);
- if(mFileeee.getParentFile().exists())
- return mFileeee.mkdir();
- else return mFileeee.mkdirs();
+ File file = new File(path);
+ if(file.getParentFile().exists())
+ return file.mkdir();
+ else return file.mkdirs();
}
/*
@@ -362,7 +364,6 @@ public class PojavLoginActivity extends MineActivity
public void loginSavedAcc(View view)
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.login_select_account);
if (Tools.enableDevFeatures) {
/*
@@ -380,7 +381,7 @@ public class PojavLoginActivity extends MineActivity
}
builder.setPositiveButton(android.R.string.cancel, null);
-
+ builder.setTitle(this.getString(R.string.login_select_account));
final AlertDialog dialog = builder.create();
/*
@@ -391,6 +392,8 @@ public class PojavLoginActivity extends MineActivity
lpHint.weight = 1;
lpFlv.weight = 1;
*/
+ dialog.setTitle(this.getString(R.string.login_select_account));
+ System.out.println("Setting title...");
LinearLayout dialay = new LinearLayout(this);
dialay.setOrientation(LinearLayout.VERTICAL);
TextView fhint = new TextView(this);
@@ -459,6 +462,7 @@ public class PojavLoginActivity extends MineActivity
dialay.addView(flv);
dialog.setView(dialay);
+ dialog.setTitle(this.getString(R.string.login_select_account));
dialog.show();
}
@@ -493,50 +497,8 @@ public class PojavLoginActivity extends MineActivity
end skip*/
if (sOffline.isChecked()) {
- AlertDialog.Builder alert = new AlertDialog.Builder(this);
- alert.setTitle(R.string.warning_title);
- alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
-
- @Override
- public void onClick(DialogInterface p1, int p2)
- {
- sRemember.setChecked(true);
- mProfile = loginOffline();
- playProfile();
- }
- });
-
- alert.setNegativeButton(R.string.login_offline_alert_skip, new DialogInterface.OnClickListener(){
-
- @Override
- public void onClick(DialogInterface p1, int p2)
- {
- mProfile = loginOffline();
- playProfile();
- }
- });
-
- alert.setNeutralButton(android.R.string.cancel, new DialogInterface.OnClickListener(){
-
- @Override
- public void onClick(DialogInterface p1, int p2)
- {
- mProfile = null;
- }
- });
-
- if (!sRemember.isChecked()) {
- alert.setMessage(R.string.login_offline_warning_1);
- warning = alert.show();
- } else {
- mProfile = loginOffline();
- playProfile();
- }
-
- /*
- while (warning != null && warning.isShowing()) {
- }
- */
+ mProfile = loginOffline();
+ playProfile();
} else {
new LoginTask().setLoginListener(new LoginListener(){
diff --git a/app/src/main/java/net/kdt/pojavlaunch/SecondaryDexLoader.java b/app/src/main/java/net/kdt/pojavlaunch/SecondaryDexLoader.java
new file mode 100644
index 000000000..8d12f402e
--- /dev/null
+++ b/app/src/main/java/net/kdt/pojavlaunch/SecondaryDexLoader.java
@@ -0,0 +1,146 @@
+package net.kdt.pojavlaunch;
+
+import android.util.*;
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+/*
+ * All methods there are from
+ * https://android.googlesource.com/platform/frameworks/multidex/+/refs/heads/master/library/src/androidx/multidex/MultiDex.java
+ */
+public class SecondaryDexLoader
+{
+ public static String TAG = "SecondaryDexLoader";
+
+ private static int ADDITIONAL_CLASSES = 0;
+
+ public static void install(ClassLoader loader, List additionalClassPathEntries, File optimizedDirectory) throws Throwable {
+ ADDITIONAL_CLASSES = additionalClassPathEntries.size();
+
+ /* The patched class loader is expected to be a descendant of
+ * dalvik.system.BaseDexClassLoader. We modify its
+ * dalvik.system.DexPathList pathList field to append additional DEX
+ * file entries.
+ */
+
+ Object dexPathList = getDexPathList(loader);
+ ArrayList suppressedExceptions = new ArrayList();
+ expandFieldArray(dexPathList, "dexElements", makeDexElements(dexPathList,
+ new ArrayList(additionalClassPathEntries), optimizedDirectory,
+ suppressedExceptions));
+ if (suppressedExceptions.size() > 0) {
+ for (IOException e : suppressedExceptions) {
+ Log.w(TAG, "Exception in makeDexElement", e);
+ }
+ Field suppressedExceptionsField =
+ findField(loader, "dexElementsSuppressedExceptions");
+ IOException[] dexElementsSuppressedExceptions =
+ (IOException[]) suppressedExceptionsField.get(loader);
+ if (dexElementsSuppressedExceptions == null) {
+ dexElementsSuppressedExceptions =
+ suppressedExceptions.toArray(
+ new IOException[suppressedExceptions.size()]);
+ } else {
+ IOException[] combined =
+ new IOException[suppressedExceptions.size() +
+ dexElementsSuppressedExceptions.length];
+ suppressedExceptions.toArray(combined);
+ System.arraycopy(dexElementsSuppressedExceptions, 0, combined,
+ suppressedExceptions.size(), dexElementsSuppressedExceptions.length);
+ dexElementsSuppressedExceptions = combined;
+ }
+ suppressedExceptionsField.set(loader, dexElementsSuppressedExceptions);
+ }
+ }
+
+ private static /* DexPathList */ Object getDexPathList(ClassLoader loader) throws Throwable {
+ Field pathListField = findField(loader, "pathList");
+ return pathListField.get(loader);
+ }
+
+ /**
+ * A wrapper around
+ * {@code private static final dalvik.system.DexPathList#makeDexElements}.
+ */
+ private static Object[] makeDexElements(Object dexPathList, ArrayList files, File optimizedDirectory, ArrayList suppressedExceptions) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+ Method makeDexElements = findMethod(dexPathList, "makeDexElements", ArrayList.class, File.class, ArrayList.class);
+ return (Object[]) makeDexElements.invoke(dexPathList, files, optimizedDirectory, suppressedExceptions);
+ }
+
+
+ /**
+ * Locates a given field anywhere in the class inheritance hierarchy.
+ *
+ * @param instance an object to search the field into.
+ * @param name field name
+ * @return a field object
+ * @throws NoSuchFieldException if the field cannot be located
+ */
+ private static Field findField(Object instance, String name) throws NoSuchFieldException {
+ for (Class> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
+ try {
+ Field field = clazz.getDeclaredField(name);
+ if (!field.isAccessible()) {
+ field.setAccessible(true);
+ }
+ return field;
+ } catch (NoSuchFieldException e) {
+ // ignore and search next
+ }
+ }
+ throw new NoSuchFieldException("Field " + name + " not found in " + instance.getClass());
+ }
+ /**
+ * Locates a given method anywhere in the class inheritance hierarchy.
+ *
+ * @param instance an object to search the method into.
+ * @param name method name
+ * @param parameterTypes method parameter types
+ * @return a method object
+ * @throws NoSuchMethodException if the method cannot be located
+ */
+ private static Method findMethod(Object instance, String name, Class>... parameterTypes) throws NoSuchMethodException {
+ for (Class> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
+ try {
+ Method method = clazz.getDeclaredMethod(name, parameterTypes);
+ if (!method.isAccessible()) {
+ method.setAccessible(true);
+ }
+ return method;
+ } catch (NoSuchMethodException e) {
+ // ignore and search next
+ }
+ }
+ throw new NoSuchMethodException("Method " + name + " with parameters " +
+ Arrays.asList(parameterTypes) + " not found in " + instance.getClass());
+ }
+ /**
+ * Replace the value of a field containing a non null array, by a new array containing the
+ * elements of the original array plus the elements of extraElements.
+ * @param instance the instance whose field is to be modified.
+ * @param fieldName the field to modify.
+ * @param extraElements elements to append at the end of the array.
+ */
+ private static Object[] originalDex;
+ private static void expandFieldArray(Object instance, String fieldName, Object[] extraElements) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
+ Field jlrField = findField(instance, fieldName);
+ originalDex = (Object[]) jlrField.get(instance);
+ Object[] combined = (Object[]) Array.newInstance(
+ originalDex.getClass().getComponentType(), originalDex.length + extraElements.length);
+ System.arraycopy(originalDex, 0, combined, 0, originalDex.length);
+ System.arraycopy(extraElements, 0, combined, originalDex.length, extraElements.length);
+ jlrField.set(instance, combined);
+ }
+
+ public static void resetFieldArray(ClassLoader loader) throws Throwable {
+ if (originalDex == null) return;
+
+ Object instance = getDexPathList(loader);
+
+ Field jlrField = findField(instance, "dexElements");
+ jlrField.set(instance, originalDex);
+
+ originalDex = null;
+ }
+}
diff --git a/app/src/main/java/net/kdt/pojavlaunch/Tools.java b/app/src/main/java/net/kdt/pojavlaunch/Tools.java
index 607e6392f..12a622606 100644
--- a/app/src/main/java/net/kdt/pojavlaunch/Tools.java
+++ b/app/src/main/java/net/kdt/pojavlaunch/Tools.java
@@ -37,7 +37,7 @@ public final class Tools
public static int usingVerCode = 1;
public static String usingVerName = "2.4.2";
- public static String mhomeUrl = "https://khanhduytran0.github.io/PojavLauncher"; // "http://kdtjavacraft.eu5.net";
+ public static String mhomeUrl = "https://pojavlauncherteam.github.io/PojavLauncher"; // "http://kdtjavacraft.eu5.net";
public static String datapath = "/data/data/net.kdt.pojavlaunch";
public static String worksDir = datapath + "/app_working_dir";
@@ -76,11 +76,23 @@ public final class Tools
}
private static boolean isClientFirst = false;
- public static String generate(String version) throws IOException
+ public static String generateLaunchClassPath(String version) throws IOException
{
StringBuilder libStr = new StringBuilder(); //versnDir + "/" + version + "/" + version + ".jar:";
- String[] classpath = generateLibClasspath(getVersionInfo(version).libraries);
+
+ JMinecraftVersionList.Version info = getVersionInfo(version);
+ String[] classpath = generateLibClasspath(info);
+ // Debug: LWJGL 3 override
+ File lwjgl3Folder = new File(Tools.MAIN_PATH, "lwjgl3");
+ if (info.arguments != null && lwjgl3Folder.exists()) {
+ for (File file: lwjgl3Folder.listFiles()) {
+ if (file.getName().endsWith(".jar")) {
+ libStr.append(file.getAbsolutePath() + ":");
+ }
+ }
+ }
+
if (isClientFirst) {
libStr.append(getPatchedFile(version));
}
@@ -158,10 +170,15 @@ public final class Tools
public static void showError(final Context ctx, final Throwable e, final boolean exitIfOk)
{
- showError(ctx, e, exitIfOk, false);
+ showError(ctx, R.string.global_error, e, exitIfOk, false);
}
- private static void showError(final Context ctx, final Throwable e, final boolean exitIfOk, final boolean showMore)
+ public static void showError(final Context ctx, final int titleId, final Throwable e, final boolean exitIfOk)
+ {
+ showError(ctx, titleId, e, exitIfOk, false);
+ }
+
+ private static void showError(final Context ctx, final int titleId, final Throwable e, final boolean exitIfOk, final boolean showMore)
{
Runnable runnable = new Runnable(){
@@ -170,7 +187,7 @@ public final class Tools
{
final String errMsg = showMore ? Log.getStackTraceString(e): e.getMessage();
new AlertDialog.Builder((Context) ctx)
- .setTitle(R.string.global_error)
+ .setTitle(titleId)
.setMessage(errMsg)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
@@ -191,7 +208,7 @@ public final class Tools
@Override
public void onClick(DialogInterface p1, int p2)
{
- showError(ctx, e, exitIfOk, !showMore);
+ showError(ctx, titleId, e, exitIfOk, !showMore);
}
})
.setNeutralButton(android.R.string.copy, new DialogInterface.OnClickListener(){
@@ -296,10 +313,10 @@ public final class Tools
}
}
*/
- public static String[] generateLibClasspath(DependentLibrary[] libs)
- {
+ public static String[] generateLibClasspath(JMinecraftVersionList.Version info) {
List libDir = new ArrayList();
- for (DependentLibrary libItem: libs) {
+
+ for (DependentLibrary libItem: info.libraries) {
String[] libInfos = libItem.name.split(":");
libDir.add(Tools.libraries + "/" + Tools.artifactToPath(libInfos[0], libInfos[1], libInfos[2]));
}
diff --git a/app/src/main/java/net/kdt/pojavlaunch/mcfragments/ConsoleFragment.java b/app/src/main/java/net/kdt/pojavlaunch/mcfragments/ConsoleFragment.java
index e7cdd7ade..91d435188 100644
--- a/app/src/main/java/net/kdt/pojavlaunch/mcfragments/ConsoleFragment.java
+++ b/app/src/main/java/net/kdt/pojavlaunch/mcfragments/ConsoleFragment.java
@@ -20,7 +20,7 @@ public class ConsoleFragment extends Fragment
consoleView = (TextView) view.findViewById(R.id.lmaintabconsoleLogTextView);
consoleView.setTypeface(Typeface.MONOSPACE);
- consoleView.setHint("No log");
+ consoleView.setHint(this.getText(R.string.main_nolog));
return view;
}
diff --git a/app/src/main/java/net/kdt/pojavlaunch/mcfragments/CrashFragment.java b/app/src/main/java/net/kdt/pojavlaunch/mcfragments/CrashFragment.java
index f6ff870da..70b1479bf 100644
--- a/app/src/main/java/net/kdt/pojavlaunch/mcfragments/CrashFragment.java
+++ b/app/src/main/java/net/kdt/pojavlaunch/mcfragments/CrashFragment.java
@@ -40,7 +40,7 @@ public class CrashFragment extends Fragment
crashView = (TextView) getView().findViewById(R.id.lmaintabconsoleLogCrashTextView);
crashView.setTypeface(Typeface.MONOSPACE);
- crashView.setHint("No crash detected.");
+ crashView.setHint(this.getText(R.string.main_nocrash));
//new File(crashPath).mkdirs();
}
diff --git a/app/src/main/java/net/kdt/pojavlaunch/prefs/PojavPreferenceActivity.java b/app/src/main/java/net/kdt/pojavlaunch/prefs/PojavPreferenceActivity.java
index ebfed4e1f..d52085d85 100644
--- a/app/src/main/java/net/kdt/pojavlaunch/prefs/PojavPreferenceActivity.java
+++ b/app/src/main/java/net/kdt/pojavlaunch/prefs/PojavPreferenceActivity.java
@@ -162,7 +162,7 @@ public class PojavPreferenceActivity extends MineActivity implements OnCheckedCh
try {
Field field = R.id.class.getDeclaredField(getId(bar.getId()).replace("seekbar", "progressseek"));
- ((TextView) findViewById(field.get(null))).setText(currProgress + "/" + bar.getMax());
+ ((TextView) findViewById((Integer) field.get(null))).setText(currProgress + "/" + bar.getMax());
} catch (Throwable th) {
throw new RuntimeException(th);
}
diff --git a/app/src/main/java/net/kdt/pojavlaunch/value/customcontrols/ControlView.java b/app/src/main/java/net/kdt/pojavlaunch/value/customcontrols/ControlView.java
index 27cbaa54c..7241a6795 100644
--- a/app/src/main/java/net/kdt/pojavlaunch/value/customcontrols/ControlView.java
+++ b/app/src/main/java/net/kdt/pojavlaunch/value/customcontrols/ControlView.java
@@ -59,7 +59,7 @@ public class ControlView extends Button implements OnLongClickListener, OnTouchL
} else if (properties.specialButtonListener instanceof View.OnTouchListener) {
setOnTouchListener((View.OnTouchListener) properties.specialButtonListener);
} else {
- throw new IllegalArgumentException("Field " + ControlButton.class.getName() + ".specialButtonListener must be View.OnClickListener or View.OnTouchListener");
+ throw new IllegalArgumentException("Field " + ControlButton.class.getName() + ".specialButtonListener must be View.OnClickListener or View.OnTouchListener, but is " + properties.specialButtonListener.getClass().getName());
}
setLayoutParams(new FrameLayout.LayoutParams(properties.width, properties.height));
diff --git a/app/src/main/java/org/apache/harmony/security/fortress/Services.java b/app/src/main/java/org/apache/harmony/security/fortress/Services.java
index ce40203b5..3e565358d 100644
--- a/app/src/main/java/org/apache/harmony/security/fortress/Services.java
+++ b/app/src/main/java/org/apache/harmony/security/fortress/Services.java
@@ -160,6 +160,11 @@ public class Services {
public static synchronized ArrayList getServices(String key) {
return services.get(key);
}
+
+ public static synchronized ArrayList getServices(String type, String algorithm) {
+ return null;
+ }
+
/**
* Returns the default SecureRandom service description.
*/
diff --git a/app/src/main/java/org/lwjgl/BufferChecks.java b/app/src/main/java/org/lwjgl/BufferChecks.java
deleted file mode 100644
index d9e1300c2..000000000
--- a/app/src/main/java/org/lwjgl/BufferChecks.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (c) 2002-2008 LWJGL Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'LWJGL' nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package org.lwjgl;
-
-import java.nio.*;
-
-/**
- *
A class to check buffer boundaries in general. If there is unsufficient space
- * in the buffer when the call is made then a buffer overflow would otherwise
- * occur and cause unexpected behaviour, a crash, or worse, a security risk.
- *
- * Internal class, don't use.
- *
- * @author cix_foo
- * @author elias_naur
- * @version $Revision$
- * $Id$
- */
-public class BufferChecks {
- /** Static methods only! */
- private BufferChecks() {
- }
-
- /**
- * Helper methods to ensure a function pointer is not-null (0)
- */
- public static void checkFunctionAddress(long pointer) {
- if (LWJGLUtil.CHECKS && pointer == 0) {
- // throw new IllegalStateException("Function is not supported");
- }
- }
-
- /**
- * Helper methods to ensure a ByteBuffer is null-terminated
- */
- public static void checkNullTerminated(ByteBuffer buf) {
- if ( LWJGLUtil.CHECKS && buf.get(buf.limit() - 1) != 0) {
- throw new IllegalArgumentException("Missing null termination");
- }
- }
-
- public static void checkNullTerminated(ByteBuffer buf, int count) {
- if ( LWJGLUtil.CHECKS ) {
- int nullFound = 0;
- for ( int i = buf.position(); i < buf.limit(); i++ ) {
- if ( buf.get(i) == 0 )
- nullFound++;
- }
-
- if ( nullFound < count )
- throw new IllegalArgumentException("Missing null termination");
- }
- }
-
- /** Helper method to ensure an IntBuffer is null-terminated */
- public static void checkNullTerminated(IntBuffer buf) {
- if ( LWJGLUtil.CHECKS && buf.get(buf.limit() - 1) != 0 ) {
- throw new IllegalArgumentException("Missing null termination");
- }
- }
-
- /** Helper method to ensure a LongBuffer is null-terminated */
- public static void checkNullTerminated(LongBuffer buf) {
- if ( LWJGLUtil.CHECKS && buf.get(buf.limit() - 1) != 0 ) {
- throw new IllegalArgumentException("Missing null termination");
- }
- }
-
- /** Helper method to ensure a PointerBuffer is null-terminated */
- public static void checkNullTerminated(PointerBuffer buf) {
- if ( LWJGLUtil.CHECKS && buf.get(buf.limit() - 1) != 0 ) {
- throw new IllegalArgumentException("Missing null termination");
- }
- }
-
- public static void checkNotNull(Object o) {
- if ( LWJGLUtil.CHECKS && o == null)
- throw new IllegalArgumentException("Null argument");
- }
-
- /**
- * Helper methods to ensure a buffer is direct (and, implicitly, non-null).
- */
- public static void checkDirect(ByteBuffer buf) {
- if ( LWJGLUtil.CHECKS && !buf.isDirect()) {
- throw new IllegalArgumentException("ByteBuffer is not direct");
- }
- }
-
- public static void checkDirect(ShortBuffer buf) {
- if ( LWJGLUtil.CHECKS && !buf.isDirect()) {
- throw new IllegalArgumentException("ShortBuffer is not direct");
- }
- }
-
- public static void checkDirect(IntBuffer buf) {
- if ( LWJGLUtil.CHECKS && !buf.isDirect()) {
- throw new IllegalArgumentException("IntBuffer is not direct");
- }
- }
-
- public static void checkDirect(LongBuffer buf) {
- if ( LWJGLUtil.CHECKS && !buf.isDirect()) {
- throw new IllegalArgumentException("LongBuffer is not direct");
- }
- }
-
- public static void checkDirect(FloatBuffer buf) {
- if ( LWJGLUtil.CHECKS && !buf.isDirect()) {
- throw new IllegalArgumentException("FloatBuffer is not direct");
- }
- }
-
- public static void checkDirect(DoubleBuffer buf) {
- if ( LWJGLUtil.CHECKS && !buf.isDirect()) {
- throw new IllegalArgumentException("DoubleBuffer is not direct");
- }
- }
-
- public static void checkDirect(PointerBuffer buf) {
- // NO-OP, PointerBuffer is always direct.
- }
-
- public static void checkArray(Object[] array) {
- if ( LWJGLUtil.CHECKS && (array == null || array.length == 0) )
- throw new IllegalArgumentException("Invalid array");
- }
-
- /**
- * This is a separate call to help inline checkBufferSize.
- */
- private static void throwBufferSizeException(Buffer buf, int size) {
- throw new IllegalArgumentException("Number of remaining buffer elements is " + buf.remaining() + ", must be at least " + size + ". Because at most " + size + " elements can be returned, a buffer with at least " + size + " elements is required, regardless of actual returned element count");
- }
-
- private static void throwBufferSizeException(PointerBuffer buf, int size) {
- throw new IllegalArgumentException("Number of remaining pointer buffer elements is " + buf.remaining() + ", must be at least " + size);
- }
-
- private static void throwArraySizeException(Object[] array, int size) {
- throw new IllegalArgumentException("Number of array elements is " + array.length + ", must be at least " + size);
- }
-
- private static void throwArraySizeException(long[] array, int size) {
- throw new IllegalArgumentException("Number of array elements is " + array.length + ", must be at least " + size);
- }
-
- /**
- * Helper method to ensure a buffer is big enough to receive data from a
- * glGet* operation.
- *
- * @param buf
- * The buffer to check
- * @param size
- * The minimum buffer size
- * @throws IllegalArgumentException
- */
- public static void checkBufferSize(Buffer buf, int size) {
- if ( LWJGLUtil.CHECKS && buf.remaining() < size) {
- throwBufferSizeException(buf, size);
- }
- }
-
- /**
- * Detects the buffer type and performs the corresponding check
- * and also returns the buffer position in bytes.
- *
- * @param buffer the buffer to check
- * @param size the size to check
- *
- * @return the buffer position in bytes
- */
- public static int checkBuffer(final Buffer buffer, final int size) {
- final int posShift;
- if ( buffer instanceof ByteBuffer ) {
- BufferChecks.checkBuffer((ByteBuffer)buffer, size);
- posShift = 0;
- } else if ( buffer instanceof ShortBuffer ) {
- BufferChecks.checkBuffer((ShortBuffer)buffer, size);
- posShift = 1;
- } else if ( buffer instanceof IntBuffer ) {
- BufferChecks.checkBuffer((IntBuffer)buffer, size);
- posShift = 2;
- } else if ( buffer instanceof LongBuffer ) {
- BufferChecks.checkBuffer((LongBuffer)buffer, size);
- posShift = 4;
- } else if ( buffer instanceof FloatBuffer ) {
- BufferChecks.checkBuffer((FloatBuffer)buffer, size);
- posShift = 2;
- } else if ( buffer instanceof DoubleBuffer ) {
- BufferChecks.checkBuffer((DoubleBuffer)buffer, size);
- posShift = 4;
- } else
- throw new IllegalArgumentException("Unsupported Buffer type specified: " + buffer.getClass());
-
- return buffer.position() << posShift;
- }
-
- public static void checkBuffer(ByteBuffer buf, int size) {
- if ( LWJGLUtil.CHECKS ) {
- checkBufferSize(buf, size);
- checkDirect(buf);
- }
- }
-
- public static void checkBuffer(ShortBuffer buf, int size) {
- if ( LWJGLUtil.CHECKS ) {
- checkBufferSize(buf, size);
- checkDirect(buf);
- }
- }
-
- public static void checkBuffer(IntBuffer buf, int size) {
- if ( LWJGLUtil.CHECKS ) {
- checkBufferSize(buf, size);
- checkDirect(buf);
- }
- }
-
- public static void checkBuffer(LongBuffer buf, int size) {
- if ( LWJGLUtil.CHECKS ) {
- checkBufferSize(buf, size);
- checkDirect(buf);
- }
- }
-
- public static void checkBuffer(FloatBuffer buf, int size) {
- if ( LWJGLUtil.CHECKS ) {
- checkBufferSize(buf, size);
- checkDirect(buf);
- }
- }
-
- public static void checkBuffer(DoubleBuffer buf, int size) {
- if ( LWJGLUtil.CHECKS ) {
- checkBufferSize(buf, size);
- checkDirect(buf);
- }
- }
-
- public static void checkBuffer(PointerBuffer buf, int size) {
- if ( LWJGLUtil.CHECKS && buf.remaining() < size ) {
- throwBufferSizeException(buf, size);
- }
- }
-
- public static void checkArray(Object[] array, int size) {
- if ( LWJGLUtil.CHECKS && array.length < size )
- throwArraySizeException(array, size);
- }
-
- public static void checkArray(long[] array, int size) {
- if ( LWJGLUtil.CHECKS && array.length < size )
- throwArraySizeException(array, size);
- }
-
-}
diff --git a/app/src/main/java/org/lwjgl/DefaultSysImplementation.java b/app/src/main/java/org/lwjgl/DefaultSysImplementation.java
deleted file mode 100644
index 924841a23..000000000
--- a/app/src/main/java/org/lwjgl/DefaultSysImplementation.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2002-2008 LWJGL Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'LWJGL' nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package org.lwjgl;
-
-
-/**
- *
- * @author elias_naur
- * @version $Revision$
- * $Id$
- */
-abstract class DefaultSysImplementation implements SysImplementation {
- public /* native */ int getJNIVersion() {
- // Bypass JNI Version check.
- return getRequiredJNIVersion();
- }
-
- public /* native */ int getPointerSize() {
- return 1;
- }
- public native void setDebug(boolean debug);
-
- public long getTimerResolution() {
- return 1000;
- }
-
- public boolean has64Bit() {
- return System.getProperty("os.arch").contains("64");
- }
-
- public abstract long getTime();
- public abstract void alert(String title, String message);
- public abstract String getClipboard();
-}
diff --git a/app/src/main/java/org/lwjgl/LWJGLUtil.java b/app/src/main/java/org/lwjgl/LWJGLUtil.java
deleted file mode 100644
index 978233bff..000000000
--- a/app/src/main/java/org/lwjgl/LWJGLUtil.java
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * Copyright (c) 2002-2008 LWJGL Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'LWJGL' nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package org.lwjgl;
-
-import java.io.File;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.nio.ByteBuffer;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.*;
-
-/**
- *
- * Internal library methods
- *
- *
- * @author Brian Matzon
- * @version $Revision$
- * $Id$
- */
-public class LWJGLUtil {
- public static final int PLATFORM_LINUX = 1;
- public static final int PLATFORM_MACOSX = 2;
- public static final int PLATFORM_WINDOWS = 3;
- public static final int PLATFORM_ANDROID = 1337;
- public static final String PLATFORM_LINUX_NAME = "linux";
- public static final String PLATFORM_MACOSX_NAME = "macosx";
- public static final String PLATFORM_WINDOWS_NAME = "windows";
- public static final String PLATFORM_ANDROID_NAME = "android";
-
- private static final String LWJGL_ICON_DATA_16x16 =
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\376\377\377\377\302\327\350\377" +
- "\164\244\313\377\120\213\275\377\124\216\277\377\206\257\322\377" +
- "\347\357\366\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\365\365\365\377\215\217\221\377\166\202\215\377" +
- "\175\215\233\377\204\231\252\377\224\267\325\377\072\175\265\377" +
- "\110\206\272\377\332\347\361\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\364\370\373\377\234\236\240\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\344\344\344\377\204\255\320\377" +
- "\072\175\265\377\133\222\301\377\374\375\376\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\221\266\325\377\137\137\137\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\042\042\042\377\377\377\377\377\350\360\366\377" +
- "\071\174\265\377\072\175\265\377\304\330\351\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\306\331\351\377" +
- "\201\253\316\377\035\035\035\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\146\146\146\377\377\377\377\377\320\340\355\377" +
- "\072\175\265\377\072\175\265\377\215\264\324\377\377\377\377\377" +
- "\362\362\362\377\245\245\245\377\337\337\337\377\242\301\334\377" +
- "\260\305\326\377\012\012\012\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\250\250\250\377\377\377\377\377\227\272\330\377" +
- "\072\175\265\377\072\175\265\377\161\241\312\377\377\377\377\377" +
- "\241\241\241\377\000\000\000\377\001\001\001\377\043\043\043\377" +
- "\314\314\314\377\320\320\320\377\245\245\245\377\204\204\204\377" +
- "\134\134\134\377\357\357\357\377\377\377\377\377\140\226\303\377" +
- "\072\175\265\377\072\175\265\377\155\236\310\377\377\377\377\377" +
- "\136\136\136\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\317\317\317\377\037\037\037\377\003\003\003\377\053\053\053\377" +
- "\154\154\154\377\306\306\306\377\372\374\375\377\236\277\332\377" +
- "\167\245\314\377\114\211\274\377\174\250\316\377\377\377\377\377" +
- "\033\033\033\377\000\000\000\377\000\000\000\377\027\027\027\377" +
- "\326\326\326\377\001\001\001\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\122\122\122\377\345\345\345\377\075\075\075\377" +
- "\150\150\150\377\246\246\247\377\332\336\341\377\377\377\377\377" +
- "\164\164\164\377\016\016\016\377\000\000\000\377\131\131\131\377" +
- "\225\225\225\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\221\221\221\377\233\233\233\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\002\002\002\377\103\103\103\377" +
- "\377\377\377\377\356\356\356\377\214\214\214\377\277\277\277\377" +
- "\126\126\126\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\323\323\323\377\130\130\130\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\063\063\063\377" +
- "\377\377\377\377\377\377\377\377\374\375\376\377\377\377\377\377" +
- "\300\300\300\377\100\100\100\377\002\002\002\377\000\000\000\377" +
- "\033\033\033\377\373\373\373\377\027\027\027\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\170\170\170\377" +
- "\377\377\377\377\377\377\377\377\322\341\356\377\176\251\316\377" +
- "\340\352\363\377\377\377\377\377\324\324\324\377\155\155\155\377" +
- "\204\204\204\377\323\323\323\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\275\275\275\377" +
- "\377\377\377\377\377\377\377\377\376\376\376\377\146\232\305\377" +
- "\075\177\266\377\202\254\320\377\344\355\365\377\377\377\377\377" +
- "\377\377\377\377\345\345\345\377\055\055\055\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\014\014\014\377\366\366\366\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\342\354\364\377" +
- "\115\211\274\377\072\175\265\377\076\200\266\377\207\260\322\377" +
- "\347\357\366\377\377\377\377\377\376\376\376\377\274\274\274\377" +
- "\117\117\117\377\003\003\003\377\112\112\112\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\353\362\370\377\214\263\324\377\126\220\300\377\120\214\275\377" +
- "\167\245\314\377\355\363\370\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\337\337\337\377\346\346\346\377\377\377\377\377";
-
- private static final String LWJGL_ICON_DATA_32x32 =
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\372\374\375\377" +
- "\313\335\354\377\223\267\326\377\157\240\311\377\134\223\302\377\140\226\303\377\172\247\315\377\254\310\340\377\355\363\370\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\374\375\376\377\265\316\343\377\132\222\301\377" +
- "\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\105\205\271\377" +
- "\241\301\334\377\374\375\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\374\374\374\377\342\352\361\377\270\317\343\377\256\311\340\377" +
- "\243\302\334\377\230\272\330\377\214\263\323\377\201\254\317\377\156\237\310\377\075\177\266\377\072\175\265\377\072\175\265\377" +
- "\072\175\265\377\162\242\312\377\365\370\373\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\330\330\330\377\061\061\061\377\044\044\044\377\061\061\061\377\100\100\100\377" +
- "\122\122\122\377\145\145\145\377\164\164\164\377\217\217\217\377\367\370\370\377\254\310\337\377\073\175\265\377\072\175\265\377" +
- "\072\175\265\377\072\175\265\377\171\247\315\377\374\375\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\376\376\376\377\150\150\150\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\266\266\266\377\376\376\376\377\206\256\321\377\072\175\265\377" +
- "\072\175\265\377\072\175\265\377\072\175\265\377\256\312\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\323\342\356\377\341\352\362\377\050\050\050\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\002\002\002\377\336\336\336\377\377\377\377\377\365\370\373\377\133\222\301\377" +
- "\072\175\265\377\072\175\265\377\072\175\265\377\110\206\272\377\364\370\373\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\354\363\370\377\144\231\305\377\327\331\333\377\005\005\005\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\044\044\044\377\376\376\376\377\377\377\377\377\377\377\377\377\300\325\347\377" +
- "\071\174\265\377\072\175\265\377\072\175\265\377\072\175\265\377\253\310\340\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377" +
- "\170\246\314\377\173\247\315\377\236\236\236\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\145\145\145\377\377\377\377\377\377\377\377\377\377\377\377\377\342\354\364\377" +
- "\067\173\264\377\072\175\265\377\072\175\265\377\072\175\265\377\146\232\305\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\303\327\350\377" +
- "\071\175\265\377\262\314\341\377\130\130\130\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\251\251\251\377\377\377\377\377\377\377\377\377\377\377\377\377\274\322\345\377" +
- "\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\100\201\267\377\356\364\371\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\372\374\375\377\132\222\301\377" +
- "\075\177\266\377\335\345\355\377\034\034\034\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\007\007\007\377\347\347\347\377\377\377\377\377\377\377\377\377\377\377\377\377\205\256\321\377" +
- "\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\071\175\265\377\314\336\354\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377\377\272\322\345\377\072\175\265\377" +
- "\127\220\277\377\320\321\321\377\003\003\003\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\063\063\063\377\375\375\375\377\377\377\377\377\377\377\377\377\373\374\375\377\120\213\275\377" +
- "\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\071\175\265\377\261\314\342\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\312\312\312\377\067\067\067\377\141\141\141\377\242\242\242\377\335\335\335\377\344\354\363\377\261\313\341\377" +
- "\264\315\342\377\346\346\346\377\043\043\043\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\162\162\162\377\377\377\377\377\377\377\377\377\377\377\377\377\330\345\360\377\072\175\265\377" +
- "\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\240\300\333\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\146\146\146\377\000\000\000\377\000\000\000\377\000\000\000\377\006\006\006\377\047\047\047\377\146\146\146\377" +
- "\324\324\324\377\377\377\377\377\366\366\366\377\320\320\320\377\227\227\227\377\136\136\136\377\047\047\047\377\004\004\004\377" +
- "\000\000\000\377\003\003\003\377\300\300\300\377\377\377\377\377\377\377\377\377\377\377\377\377\242\301\333\377\072\175\265\377" +
- "\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\236\277\332\377\377\377\377\377\377\377\377\377" +
- "\373\373\373\377\045\045\045\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\134\134\134\377\377\377\377\377\352\352\352\377\217\217\217\377\265\265\265\377\351\351\351\377\375\375\375\377\347\347\347\377" +
- "\262\262\262\377\275\275\275\377\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377\377\153\235\307\377\072\175\265\377" +
- "\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\241\301\334\377\377\377\377\377\377\377\377\377" +
- "\333\333\333\377\003\003\003\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\203\203\203\377\377\377\377\377\137\137\137\377\000\000\000\377\000\000\000\377\013\013\013\377\067\067\067\377\166\166\166\377" +
- "\267\267\267\377\360\360\360\377\377\377\377\377\377\377\377\377\377\377\377\377\360\365\371\377\113\210\273\377\075\177\266\377" +
- "\071\174\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\262\314\342\377\377\377\377\377\377\377\377\377" +
- "\232\232\232\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\305\305\305\377\367\367\367\377\035\035\035\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\007\007\007\377\074\074\074\377\337\337\337\377\377\377\377\377\373\374\375\377\374\375\376\377\363\367\372\377" +
- "\314\335\353\377\236\276\332\377\162\241\311\377\114\211\273\377\072\175\265\377\311\334\353\377\377\377\377\377\377\377\377\377" +
- "\126\126\126\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\017\017\017\377" +
- "\371\371\371\377\321\321\321\377\003\003\003\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\216\216\216\377\377\377\377\377\371\371\371\377\204\204\204\377\160\160\160\377" +
- "\260\260\260\377\352\352\352\377\377\377\377\377\371\373\374\377\334\350\362\377\366\371\374\377\377\377\377\377\377\377\377\377" +
- "\025\025\025\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\116\116\116\377" +
- "\377\377\377\377\221\221\221\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\273\273\273\377\377\377\377\377\236\236\236\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\004\004\004\377\057\057\057\377\160\160\160\377\260\260\260\377\346\346\346\377\376\376\376\377\377\377\377\377" +
- "\071\071\071\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\220\220\220\377" +
- "\377\377\377\377\115\115\115\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\020\020\020\377\360\360\360\377\377\377\377\377\132\132\132\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\011\011\011\377\062\062\062\377\261\261\261\377" +
- "\366\366\366\377\241\241\241\377\065\065\065\377\002\002\002\377\000\000\000\377\000\000\000\377\002\002\002\377\321\321\321\377" +
- "\365\365\365\377\023\023\023\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\105\105\105\377\376\376\376\377\370\370\370\377\035\035\035\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\053\053\053\377" +
- "\377\377\377\377\377\377\377\377\374\374\374\377\276\276\276\377\120\120\120\377\005\005\005\377\045\045\045\377\371\371\371\377" +
- "\302\302\302\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\206\206\206\377\377\377\377\377\322\322\322\377\001\001\001\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\103\103\103\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\376\376\377\334\334\334\377\340\340\340\377\377\377\377\377" +
- "\225\225\225\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\001\001\001\377\310\310\310\377\377\377\377\377\216\216\216\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\210\210\210\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\337\337\337\377\051\051\051\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\030\030\030\377\365\365\365\377\377\377\377\377\112\112\112\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\317\317\317\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\361\366\372\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\371\371\371\377\265\265\265\377\113\113\113\377\006\006\006\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\122\122\122\377\377\377\377\377\370\370\370\377\020\020\020\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\034\034\034\377\370\370\370\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\206\257\321\377\220\265\325\377\352\361\367\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\333\333\333\377\170\170\170\377\033\033\033\377\000\000\000\377" +
- "\000\000\000\377\226\226\226\377\377\377\377\377\306\306\306\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\132\132\132\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\303\330\351\377\072\175\265\377\103\203\270\377" +
- "\224\270\326\377\355\363\370\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\364\364\364\377\247\247\247\377" +
- "\205\205\205\377\364\364\364\377\377\377\377\377\206\206\206\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\235\235\235\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\372\373\375\377\135\224\302\377\072\175\265\377" +
- "\072\175\265\377\106\205\271\377\230\273\330\377\357\364\371\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\233\233\233\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\005\005\005\377\335\335\335\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\305\331\351\377\073\176\266\377" +
- "\072\175\265\377\072\175\265\377\072\175\265\377\110\206\272\377\236\276\332\377\362\366\372\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\373\373\373\377\216\216\216\377\045\045\045\377\001\001\001\377\000\000\000\377" +
- "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\054\054\054\377\374\374\374\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\217\265\325\377" +
- "\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\112\207\273\377\243\302\334\377\363\367\372\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\372\372\372\377\260\260\260\377\105\105\105\377" +
- "\004\004\004\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\156\156\156\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\374\375\376\377" +
- "\205\257\321\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\115\211\274\377" +
- "\250\305\336\377\366\371\374\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\376\376\377" +
- "\322\322\322\377\150\150\150\377\016\016\016\377\000\000\000\377\001\001\001\377\270\270\270\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\376\376\377\377\261\313\342\377\114\211\274\377\071\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377" +
- "\072\175\265\377\115\211\274\377\277\324\347\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\354\354\354\377\223\223\223\377\233\233\233\377\375\375\375\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\363\367\372\377\265\316\343\377\201\254\320\377\145\231\305\377\141\227\304\377\154\236\310\377" +
- "\217\265\325\377\305\331\351\377\367\372\374\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
- "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377";
-
- /** LWJGL Logo - 16 by 16 pixels */
- public static final ByteBuffer LWJGLIcon16x16 = loadIcon(LWJGL_ICON_DATA_16x16);
-
- /** LWJGL Logo - 32 by 32 pixels */
- public static final ByteBuffer LWJGLIcon32x32 = loadIcon(LWJGL_ICON_DATA_32x32);
-
- /** Debug flag. */
- public static final boolean DEBUG = true;/*getPrivilegedBoolean("org.lwjgl.util.Debug");*/
-
- public static final boolean CHECKS = !getPrivilegedBoolean("org.lwjgl.util.NoChecks");
-
- private static final int PLATFORM;
-
- static {
- /*final String osName = getPrivilegedProperty("os.name");
- if ( osName.startsWith("Windows") )
- PLATFORM = PLATFORM_WINDOWS;
- else if ( osName.startsWith("Linux") || osName.startsWith("FreeBSD") || osName.startsWith("SunOS") || osName.startsWith("Unix") )
- PLATFORM = PLATFORM_LINUX;
- else if ( osName.startsWith("Mac OS X") || osName.startsWith("Darwin") )
- PLATFORM = PLATFORM_MACOSX;
- else
- throw new LinkageError("Unknown platform: " + osName);*/
- PLATFORM = PLATFORM_ANDROID;
- }
-
- private static ByteBuffer loadIcon(String data) {
- int len = data.length();
- ByteBuffer bb = BufferUtils.createByteBuffer(len);
- for(int i=0 ; i possible_paths = new ArrayList();
-
- String classloader_path = getPathFromClassLoader(libname, classloader);
- if (classloader_path != null) {
- log("getPathFromClassLoader: Path found: " + classloader_path);
- possible_paths.add(classloader_path);
- }
-
- for ( String platform_lib_name : platform_lib_names ) {
- String lwjgl_classloader_path = getPathFromClassLoader("lwjgl", classloader);
- if ( lwjgl_classloader_path != null ) {
- log("getPathFromClassLoader: Path found: " + lwjgl_classloader_path);
- possible_paths.add(lwjgl_classloader_path.substring(0, lwjgl_classloader_path.lastIndexOf(File.separator))
- + File.separator + platform_lib_name);
- }
-
- // add Installer path
- String alternative_path = getPrivilegedProperty("org.lwjgl.librarypath");
- if ( alternative_path != null ) {
- possible_paths.add(alternative_path + File.separator + platform_lib_name);
- }
-
- // Add all possible paths from java.library.path
- String java_library_path = getPrivilegedProperty("java.library.path");
-
- StringTokenizer st = new StringTokenizer(java_library_path, File.pathSeparator);
- while ( st.hasMoreTokens() ) {
- String path = st.nextToken();
- possible_paths.add(path + File.separator + platform_lib_name);
- }
-
- //add current path
- String current_dir = getPrivilegedProperty("user.dir");
- possible_paths.add(current_dir + File.separator + platform_lib_name);
-
- //add pure library (no path, let OS search)
- possible_paths.add(platform_lib_name);
- }
-
- //create needed string array
- return possible_paths.toArray(new String[possible_paths.size()]);
- }
-
- static void execPrivileged(final String[] cmd_array) throws Exception {
- try {
- Process process = AccessController.doPrivileged(new PrivilegedExceptionAction() {
- public Process run() throws Exception {
- return Runtime.getRuntime().exec(cmd_array);
- }
- });
- // Close unused streams to make sure the child process won't hang
- process.getInputStream().close();
- process.getOutputStream().close();
- process.getErrorStream().close();
- } catch (PrivilegedActionException e) {
- throw (Exception)e.getCause();
- }
- }
-
- private static String getPrivilegedProperty(final String property_name) {
- return AccessController.doPrivileged(new PrivilegedAction() {
- public String run() {
- return System.getProperty(property_name);
- }
- });
- }
-
- /**
- * Tries to locate named library from the current ClassLoader
- * This method exists because native libraries are loaded from native code, and as such
- * is exempt from ClassLoader library loading rutines. It therefore always fails.
- * We therefore invoke the protected method of the ClassLoader to see if it can
- * locate it.
- *
- * @param libname Name of library to search for
- * @param classloader Classloader to use
- * @return Absolute path to library if found, otherwise null
- */
- private static String getPathFromClassLoader(final String libname, final ClassLoader classloader) {
- Class> c = null;
-
- try {
- log("getPathFromClassLoader: searching for: " + libname);
- c = classloader.getClass();
- while (c != null) {
- final Class> clazz = c;
- try {
- return AccessController.doPrivileged(new PrivilegedExceptionAction() {
- public String run() throws Exception {
- Method findLibrary = clazz.getDeclaredMethod("findLibrary", String.class);
- findLibrary.setAccessible(true);
- String path = (String)findLibrary.invoke(classloader, libname);
- return path;
- }
- });
- } catch (PrivilegedActionException e) {
- log("Failed to locate findLibrary method: " + e.getCause());
- c = c.getSuperclass();
- }
- }
- } catch (Exception e) {
- log("Failure locating " + e + " using classloader:" + c);
- }
- return null;
- }
-
- /**
- * Gets a boolean property as a privileged action.
- */
- public static boolean getPrivilegedBoolean(final String property_name) {
- return AccessController.doPrivileged(new PrivilegedAction() {
- public Boolean run() {
- return Boolean.getBoolean(property_name);
- }
- });
- }
-
- /**
- * Gets an integer property as a privileged action.
- *
- * @param property_name the integer property name
- *
- * @return the property value
- */
- public static Integer getPrivilegedInteger(final String property_name) {
- return AccessController.doPrivileged(new PrivilegedAction() {
- public Integer run() {
- return Integer.getInteger(property_name);
- }
- });
- }
-
- /**
- * Gets an integer property as a privileged action.
- *
- * @param property_name the integer property name
- * @param default_val the default value to use if the property is not defined
- *
- * @return the property value
- */
- public static Integer getPrivilegedInteger(final String property_name, final int default_val) {
- return AccessController.doPrivileged(new PrivilegedAction() {
- public Integer run() {
- return Integer.getInteger(property_name, default_val);
- }
- });
- }
-
- /**
- * Prints the given message to System.err if DEBUG is true.
- *
- * @param msg Message to print
- */
- public static void log(CharSequence msg) {
- if (DEBUG) {
- System.err.println("[LWJGL] " + msg);
- }
- }
-
- /**
- * Method to determine if the current system is running a version of
- * Mac OS X better than the given version. This is only useful for Mac OS X
- * specific code and will not work for any other platform.
- */
- public static boolean isMacOSXEqualsOrBetterThan(int major_required, int minor_required) {
- String os_version = getPrivilegedProperty("os.version");
- StringTokenizer version_tokenizer = new StringTokenizer(os_version, ".");
- int major;
- int minor;
- try {
- String major_str = version_tokenizer.nextToken();
- String minor_str = version_tokenizer.nextToken();
- major = Integer.parseInt(major_str);
- minor = Integer.parseInt(minor_str);
- } catch (Exception e) {
- LWJGLUtil.log("Exception occurred while trying to determine OS version: " + e);
- // Best guess, no
- return false;
- }
- return major > major_required || (major == major_required && minor >= minor_required);
- }
-
- /**
- * Returns a map of public static final integer fields in the specified classes, to their String representations.
- * An optional filter can be specified to only include specific fields. The target map may be null, in which
- * case a new map is allocated and returned.
- *
- * This method is useful when debugging to quickly identify values returned from the AL/GL/CL APIs.
- *
- * @param filter the filter to use (optional)
- * @param target the target map (optional)
- * @param tokenClasses an array of classes to get tokens from
- *
- * @return the token map
- */
-
- public static Map getClassTokens(final TokenFilter filter, final Map target, final Class ... tokenClasses) {
- return getClassTokens(filter, target, Arrays.asList(tokenClasses));
- }
-
- /**
- * Returns a map of public static final integer fields in the specified classes, to their String representations.
- * An optional filter can be specified to only include specific fields. The target map may be null, in which
- * case a new map is allocated and returned.
- *
- * This method is useful when debugging to quickly identify values returned from the AL/GL/CL APIs.
- *
- * @param filter the filter to use (optional)
- * @param target the target map (optional)
- * @param tokenClasses the classes to get tokens from
- *
- * @return the token map
- */
- public static Map getClassTokens(final TokenFilter filter, Map target, final Iterable tokenClasses) {
- if ( target == null )
- target = new HashMap();
-
- final int TOKEN_MODIFIERS = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL;
-
- for ( final Class tokenClass : tokenClasses ) {
- for ( final Field field : tokenClass.getDeclaredFields() ) {
- // Get only fields.
- if ( (field.getModifiers() & TOKEN_MODIFIERS) == TOKEN_MODIFIERS && field.getType() == int.class ) {
- try {
- final int value = field.getInt(null);
- if ( filter != null && !filter.accept(field, value) )
- continue;
-
- if ( target.containsKey(value) ) // Print colliding tokens in their hex representation.
- target.put(value, toHexString(value));
- else
- target.put(value, field.getName());
- } catch (IllegalAccessException e) {
- // Ignore
- }
- }
- }
- }
-
- return target;
- }
-
- /**
- * Returns a string representation of the integer argument as an
- * unsigned integer in base 16. The string will be uppercase
- * and will have a leading '0x'.
- *
- * @param value the integer value
- *
- * @return the hex string representation
- */
- public static String toHexString(final int value) {
- return "0x" + Integer.toHexString(value).toUpperCase();
- }
-
- /** Simple interface for Field filtering. */
- public interface TokenFilter {
-
- /**
- * Should return true if the specified Field passes the filter.
- *
- * @param field the Field to test
- * @param value the integer value of the field
- *
- * @result true if the Field is accepted
- */
- boolean accept(Field field, int value);
-
- }
-
-}
diff --git a/app/src/main/java/org/lwjgl/opengl/GLContext.java b/app/src/main/java/org/lwjgl/opengl/GLContext.java
deleted file mode 100644
index fd28528c0..000000000
--- a/app/src/main/java/org/lwjgl/opengl/GLContext.java
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * Copyright (c) 2002-2008 LWJGL Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'LWJGL' nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package org.lwjgl.opengl;
-
-import org.lwjgl.LWJGLException;
-import org.lwjgl.LWJGLUtil;
-import org.lwjgl.MemoryUtil;
-import org.lwjgl.Sys;
-
-import java.lang.reflect.Method;
-import java.nio.ByteBuffer;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedExceptionAction;
-import java.util.*;
-
-import static org.lwjgl.opengl.GL11.*;
-import static org.lwjgl.opengl.GL30.*;
-import static org.lwjgl.opengl.GL32.*;
-
-/**
- *
- * Manages GL contexts. Before any rendering is done by a LWJGL system, a call should be made to GLContext.useContext() with a
- * context. This will ensure that GLContext has an accurate reflection of the current context's capabilities and function
- * pointers.
- *
- * This class is thread-safe in the sense that multiple threads can safely call all public methods. The class is also
- * thread-aware in the sense that it tracks a per-thread current context (including capabilities and function pointers).
- * That way, multiple threads can have multiple contexts current and render to them concurrently.
- *
- * @author elias_naur
- * @version $Revision$
- * $Id$
- */
-public final class GLContext {
-
- /** Maps threads to their current context's ContextCapabilities, if any */
- private static final ThreadLocal current_capabilities = new ThreadLocal();
-
- /**
- * The getCapabilities() method is a potential hot spot in any LWJGL application, since
- * it is needed for context capability discovery (e.g. is OpenGL 2.0 supported?), and
- * for the function pointers of gl functions. However, the 'current_capabilities' ThreadLocal
- * is (relatively) expensive to look up, and since most OpenGL applications use are single threaded
- * rendering, the following two is an optimization for this case.
- *
- * ThreadLocals can be thought of as a mapping between threads and values, so the idea
- * is to use a lock-less cache of mappings between threads and the current ContextCapabilities. The cache
- * could be any size, but in our case, we want a single sized cache for optimal performance
- * in the single threaded case.
- *
- * 'fast_path_cache' is the most recent ContextCapabilities (potentially null) and its owner. By
- * recent I mean the last thread setting the value in setCapabilities(). When getCapabilities()
- * is called, a check to see if the current is the owner of the ContextCapabilities instance in
- * fast_path_cache. If so, the instance is returned, if not, some thread has since taken ownership
- * of the cache entry and the slower current_capabilities ThreadLocal is queried instead.
- *
- * No locks are needed in get/setCapabilities, because even though fast_path_cache can be accessed
- * from multiple threads at once, we are guaranteed by the JVM spec that its value is always valid.
- * Furthermore, if the ownership test in getCapabilities() succeeds, the cache entry can only contain
- * the correct ContextCapabilites (that is, the one from getThreadLocalCapabilites()),
- * since no other thread can set the owner to anyone else than itself.
- */
- private static CapabilitiesCacheEntry fast_path_cache = new CapabilitiesCacheEntry();
-
- /**
- * Simple lock-free cache of CapabilitesEntryCache to avoid allocating more than one
- * cache entry per thread
- */
- private static final ThreadLocal thread_cache_entries = new ThreadLocal();
-
- /**
- * The weak mapping from context Object instances to ContextCapabilities. Used
- * to avoid recreating a ContextCapabilities every time a context is made current.
- */
- private static final Map