diff --git a/.gitignore b/.gitignore
index 77617a1..8cd4281 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
.gradle
-build/
+app/build/
# Ignore Gradle GUI config
gradle-app.setting
diff --git a/README.md b/README.md
index 2c4783a..8758376 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,9 @@
# MinecraftPEServer
An Android application to let you run PocketMine or Nukkit on your phone!
+
+# Uage
+Some code from PocketMine-Android,but most of them have been rewrited!
+
+# Abort JRE
+You can get "nukkit_library.tar.gz" from Here
+
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..72f5c9d
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,25 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.0"
+
+ defaultConfig {
+ applicationId "net.fengberd.minecraftpe_server"
+ minSdkVersion 9
+ targetSdkVersion 21
+ versionCode 3
+ versionName "1.0.2"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.actionbarsherlock:actionbarsherlock:4.4.0'
+}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..ebce3e3
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in C:\tools\adt-bundle-windows-x86_64-20131030\sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..ac056ef
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/assets/busybox b/app/src/main/assets/busybox
new file mode 100644
index 0000000..7c88238
Binary files /dev/null and b/app/src/main/assets/busybox differ
diff --git a/app/src/main/assets/php b/app/src/main/assets/php
new file mode 100644
index 0000000..ee580ce
Binary files /dev/null and b/app/src/main/assets/php differ
diff --git a/app/src/main/java/net/fengberd/minecraftpe_server/HomeActivity.java b/app/src/main/java/net/fengberd/minecraftpe_server/HomeActivity.java
new file mode 100644
index 0000000..3549ec3
--- /dev/null
+++ b/app/src/main/java/net/fengberd/minecraftpe_server/HomeActivity.java
@@ -0,0 +1,344 @@
+package net.fengberd.minecraftpe_server;
+
+import java.io.*;
+
+import android.os.*;
+import android.app.*;
+import android.view.*;
+import android.widget.*;
+import android.content.*;
+import android.view.View.*;
+
+import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuItem;
+import com.actionbarsherlock.app.SherlockActivity;
+
+public class HomeActivity extends SherlockActivity
+{
+ final static int FORCE_CLOSE_CODE = 143;
+ final static int CONSOLE_CODE = FORCE_CLOSE_CODE + 1;
+
+ public static Intent serverIntent=null;
+ public static HomeActivity homeActivity = null;
+ public static RadioButton radio_pocketmine=null,radio_nukkit=null;
+ public static CheckBox check_kusud=null,check_ansi=null;
+ public static Button button_start=null,button_stop=null,button_install_php=null,button_install_jre=null,button_mount=null;
+
+ public static boolean isStarted = false,nukkitMode=false,ansiMode=false;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_home);
+
+ homeActivity=this;
+ ServerUtils.setContext(homeActivity);
+
+ button_stop=(Button) findViewById(R.id.button_stop);
+ button_start=(Button) findViewById(R.id.button_start);
+ button_mount=(Button) findViewById(R.id.button_mount);
+ button_install_php=(Button)findViewById(R.id.button_install_php);
+ button_install_jre=(Button)findViewById(R.id.button_install_jre);
+
+ check_ansi=(CheckBox)findViewById(R.id.check_ansi);
+ check_kusud=(CheckBox)findViewById(R.id.check_kusud);
+
+ radio_nukkit=(RadioButton) findViewById(R.id.radio_nukkit);
+ radio_pocketmine=(RadioButton) findViewById(R.id.radio_pocketmine);
+
+ check_ansi.setChecked(ansiMode);
+
+ radio_nukkit.setChecked(nukkitMode);
+ radio_pocketmine.setChecked(!nukkitMode);
+
+ check_ansi.setOnClickListener(new OnClickListener()
+ {
+ @Override
+ public void onClick(View v)
+ {
+ ansiMode=check_ansi.isChecked();
+ }
+ });
+
+ radio_nukkit.setOnClickListener(new OnClickListener()
+ {
+ @Override
+ public void onClick(View v)
+ {
+ nukkitMode=true;
+ refreshEnabled();
+ }
+ });
+ radio_pocketmine.setOnClickListener(new OnClickListener()
+ {
+ @Override
+ public void onClick(View v)
+ {
+ nukkitMode=false;
+ refreshEnabled();
+ }
+ });
+
+ button_mount.setOnClickListener(new OnClickListener()
+ {
+ @Override
+ public void onClick(View v)
+ {
+ try
+ {
+ String binary="su",busybox=ServerUtils.getAppDirectory()+"/busybox ";
+ if(((CheckBox)findViewById(R.id.check_kusud)).isChecked())
+ {
+ binary="ku.sud";
+ }
+ Runtime.getRuntime().exec(binary+" -c "+busybox+"mount -o rw,remount /").waitFor();
+ if(!new File("/lib").exists())
+ {
+ Runtime.getRuntime().exec(binary+" -c "+busybox+"mkdir /lib").waitFor();
+ }
+ else
+ {
+ Runtime.getRuntime().exec(binary+" -c "+busybox+"umount /lib").waitFor();
+ }
+ Runtime.getRuntime().exec(binary+" -c "+busybox+"mount -o bind "+ServerUtils.getAppDirectory()+"/java/lib /lib").waitFor();
+ toast("Done");
+ }
+ catch(Exception e)
+ {
+ toast(e.toString());
+ }
+ }
+ });
+ button_install_jre.setOnClickListener(new OnClickListener()
+ {
+ @Override
+ public void onClick(View v)
+ {
+ final ProgressDialog dialog=new ProgressDialog(homeActivity);
+ dialog.setCancelable(false);
+ dialog.setMessage(getString(R.string.message_installing));
+ dialog.show();
+ new Thread(new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ File libData=new File(Environment.getExternalStorageDirectory().toString()+"/nukkit_library.tar.gz");
+ if(!libData.exists())
+ {
+ toast(getString(R.string.message_install_fail_path)+" "+Environment.getExternalStorageDirectory().toString());
+ }
+ else
+ {
+ File inside=new File(ServerUtils.getAppDirectory()+"/java/nukkit_library.tar.gz");
+ inside.delete();
+ new File(ServerUtils.getAppDirectory()+"/java").mkdirs();
+ OutputStream os=new FileOutputStream(inside);
+ InputStream is=new FileInputStream(libData);
+ int cou=0;
+ byte[] buffer=new byte[8192];
+ while((cou=is.read(buffer))!=-1)
+ {
+ os.write(buffer,0,cou);
+ }
+ is.close();
+ os.close();
+ installBusybox();
+ Runtime.getRuntime().exec("../busybox tar zxf nukkit_library.tar.gz",new String[0],new File(ServerUtils.getAppDirectory()+"/java")).waitFor();
+ inside.delete();
+ toast(R.string.message_install_success);
+ }
+ }
+ catch(Exception e)
+ {
+ toast(getString(R.string.message_install_fail)+"\n"+e.toString());
+ }
+ runOnUiThread(new Runnable()
+ {
+ public void run()
+ {
+ dialog.dismiss();
+ refreshEnabled();
+ }
+ });
+ }
+ }).start();
+ }
+ });
+ button_install_php.setOnClickListener(new OnClickListener()
+ {
+ @Override
+ public void onClick(View v)
+ {
+ final ProgressDialog dialog=new ProgressDialog(homeActivity);
+ dialog.setCancelable(false);
+ dialog.setMessage(getString(R.string.message_installing));
+ dialog.show();
+ new Thread(new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ installBusybox();
+ copyAsset("php",ServerUtils.getAppDirectory()+"/php");
+ toast(R.string.message_install_success);
+ }
+ catch(Exception e)
+ {
+ toast(getString(R.string.message_install_fail)+"\n"+e.toString());
+ }
+ runOnUiThread(new Runnable()
+ {
+ public void run()
+ {
+ dialog.dismiss();
+ refreshEnabled();
+ }
+ });
+ }
+ }).start();
+ }
+ });
+ button_start.setOnClickListener(new OnClickListener()
+ {
+ @Override
+ public void onClick(View v)
+ {
+ isStarted=true;
+ refreshEnabled();
+ serverIntent=new Intent(homeActivity,ServerService.class);
+ startService(serverIntent);
+ ServerUtils.runServer();
+ }
+ });
+ button_stop.setOnClickListener(new OnClickListener()
+ {
+ @Override
+ public void onClick(View v)
+ {
+ if(ServerUtils.isRunning())
+ {
+ ServerUtils.executeCMD("stop");
+ }
+ }
+ });
+ refreshEnabled();
+ }
+
+ public static void installBusybox() throws Exception
+ {
+ copyAsset("busybox",ServerUtils.getAppDirectory()+"/busybox");
+ new File(ServerUtils.getAppDirectory()+"/busybox").setExecutable(true,true);
+ }
+
+ public static void refreshEnabled()
+ {
+ radio_nukkit.setEnabled(!isStarted);
+ radio_pocketmine.setEnabled(!isStarted);
+ button_mount.setEnabled(!isStarted);
+ button_install_php.setEnabled(!isStarted);
+ button_install_jre.setEnabled(!isStarted);
+ if(nukkitMode && !new File(ServerUtils.getAppDirectory()+"/java/jre/bin/java").exists())
+ {
+ button_start.setEnabled(false);
+ }
+ else if(!nukkitMode && !new File(ServerUtils.getAppDirectory()+"/php").exists())
+ {
+ button_start.setEnabled(false);
+ }
+ else
+ {
+ button_start.setEnabled(!isStarted);
+ }
+ button_stop.setEnabled(isStarted);
+ }
+
+ public static void copyAsset(String name,String target) throws Exception
+ {
+ File tmp=new File(target);
+ tmp.delete();
+ OutputStream os=new FileOutputStream(tmp);
+ InputStream is=homeActivity.getAssets().open(name);
+ int cou=0;
+ byte[] buffer=new byte[8192];
+ while((cou=is.read(buffer))!=-1)
+ {
+ os.write(buffer,0,cou);
+ }
+ is.close();
+ os.close();
+ }
+
+ public static void stopNotifyService()
+ {
+ if(homeActivity != null && serverIntent != null)
+ {
+ homeActivity.runOnUiThread(new Runnable()
+ {
+ public void run()
+ {
+ isStarted=false;
+ refreshEnabled();
+ homeActivity.stopService(serverIntent);
+ }
+ });
+ }
+ }
+
+ public void toast(int text)
+ {
+ toast(getString(text));
+ }
+
+ public void toast(final String text)
+ {
+ if(homeActivity!=null)
+ {
+ homeActivity.runOnUiThread(new Runnable()
+ {
+ public void run()
+ {
+ Toast.makeText(homeActivity,text,Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ menu.add(0,CONSOLE_CODE,0,getString(R.string.menu_console))
+ .setIcon(R.drawable.hardware_dock)
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+ menu.add(0,FORCE_CLOSE_CODE,0,getString(R.string.menu_kill));
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ if(item.getItemId() == android.R.id.home || item.getItemId() == 0)
+ {
+ return false;
+ }
+ if(item.getItemId() == FORCE_CLOSE_CODE)
+ {
+ ServerUtils.stopServer();
+ if(serverIntent != null)
+ {
+ stopService(serverIntent);
+ }
+ isStarted=false;
+ refreshEnabled();
+ }
+ else if(item.getItemId() == CONSOLE_CODE)
+ {
+ startActivity(new Intent(homeActivity,LogActivity.class));
+ }
+ return true;
+ }
+}
+
diff --git a/app/src/main/java/net/fengberd/minecraftpe_server/LogActivity.java b/app/src/main/java/net/fengberd/minecraftpe_server/LogActivity.java
new file mode 100644
index 0000000..2592875
--- /dev/null
+++ b/app/src/main/java/net/fengberd/minecraftpe_server/LogActivity.java
@@ -0,0 +1,120 @@
+package net.fengberd.minecraftpe_server;
+
+import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuItem;
+import com.actionbarsherlock.app.SherlockActivity;
+
+import android.os.*;
+import android.text.*;
+import android.widget.*;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+public class LogActivity extends SherlockActivity
+{
+ final static int CLEAR_CODE = 143;
+ final static int COPY_CODE = CLEAR_CODE + 1;
+
+ public static LogActivity logActivity=null;
+ public static ScrollView sv;
+ public static SpannableStringBuilder currentLog = new SpannableStringBuilder();
+ public static Button button_command=null;
+ public static TextView label_log=null;
+ public static EditText edit_command=null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_log);
+
+ logActivity=this;
+ label_log=(TextView) findViewById(R.id.label_log);
+ label_log.setText(currentLog);
+ edit_command=(EditText)findViewById(R.id.edit_command);
+ sv=(ScrollView) findViewById(R.id.logScrollView);
+ button_command = (Button)findViewById(R.id.button_send);
+ button_command.setOnClickListener(new OnClickListener()
+ {
+ @Override
+ public void onClick(View arg0)
+ {
+ log(">" + edit_command.getText());
+ ServerUtils.executeCMD(edit_command.getText().toString());
+ edit_command.setText("");
+ }
+ });
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ if(item.getItemId() == CLEAR_CODE)
+ {
+ currentLog=new SpannableStringBuilder();
+ label_log.setText("");
+ return true;
+ }
+ else if(item.getItemId() == COPY_CODE)
+ {
+ ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+ clipboard.setText(currentLog);
+ Toast.makeText(this,R.string.message_copied,Toast.LENGTH_SHORT).show();
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ menu.add(0,COPY_CODE,0,getString(R.string.menu_copy))
+ .setIcon(R.drawable.content_copy)
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+ menu.add(0,CLEAR_CODE,0,getString(R.string.menu_clear))
+ .setIcon(R.drawable.content_discard)
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+ return true;
+ }
+
+ public static void log(final String line)
+ {
+ final CharSequence result=HomeActivity.ansiMode?Html.fromHtml("" + line.replace("&","&")
+ .replace("<","<")
+ .replace(">",">")
+ .replace(" "," ")
+ .replace("\u001b[1m","")
+ .replace("\u001b[3m","")
+ .replace("\u001b[4m","")
+ .replace("\u001b[9m","")
+ .replace("\u001b[m","")
+ .replace("\u001b[38;5;16m","")
+ .replace("\u001b[38;5;19m","")
+ .replace("\u001b[38;5;34m","")
+ .replace("\u001b[38;5;37m","")
+ .replace("\u001b[38;5;124m","")
+ .replace("\u001b[38;5;127m","")
+ .replace("\u001b[38;5;214m","")
+ .replace("\u001b[38;5;145m","")
+ .replace("\u001b[38;5;59m","")
+ .replace("\u001b[38;5;63m","")
+ .replace("\u001b[38;5;83m","")
+ .replace("\u001b[38;5;87m","")
+ .replace("\u001b[38;5;203m","")
+ .replace("\u001b[38;5;207m","")
+ .replace("\u001b[38;5;227m","")
+ .replace("\u001b[38;5;231m","") + "
"):(line+"\n");
+ currentLog.append(result);
+ if(logActivity != null)
+ {
+ logActivity.runOnUiThread(new Runnable()
+ {
+ public void run()
+ {
+ label_log.append(result);
+ sv.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ }
+ }
+}
+
diff --git a/app/src/main/java/net/fengberd/minecraftpe_server/ServerService.java b/app/src/main/java/net/fengberd/minecraftpe_server/ServerService.java
new file mode 100644
index 0000000..6a54c1c
--- /dev/null
+++ b/app/src/main/java/net/fengberd/minecraftpe_server/ServerService.java
@@ -0,0 +1,55 @@
+package net.fengberd.minecraftpe_server;
+
+import android.os.*;
+import android.app.*;
+import android.content.*;
+
+public class ServerService extends Service
+{
+ private boolean isRunning = false;
+
+ @Override
+ public int onStartCommand(Intent intent,int flags,int startId)
+ {
+ run();
+ return START_NOT_STICKY;
+ }
+
+ @Override
+ public void onDestroy()
+ {
+ stop();
+ }
+
+ @Override
+ public IBinder onBind(Intent intent)
+ {
+ return null;
+ }
+
+ private void run()
+ {
+ if(!isRunning)
+ {
+ isRunning=true;
+ Context context = getApplicationContext();
+ Notification note = new Notification(R.drawable.ic_launcher,(HomeActivity.nukkitMode?"Nukkit":"PocketMine")+" is running",System.currentTimeMillis());
+ Intent i = new Intent(context,HomeActivity.class);
+ i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ PendingIntent pi = PendingIntent.getActivity(this,0,i,0);
+ note.setLatestEventInfo(this,(HomeActivity.nukkitMode?"Nukkit":"PocketMine")+" "+HomeActivity.homeActivity.getString(R.string.message_running),HomeActivity.homeActivity.getString(R.string.message_tap_open),pi);
+ note.flags|=Notification.FLAG_NO_CLEAR;
+ startForeground(1337,note);
+ }
+ }
+
+ private void stop()
+ {
+ if(isRunning)
+ {
+ isRunning=false;
+ stopForeground(true);
+ }
+ }
+}
+
diff --git a/app/src/main/java/net/fengberd/minecraftpe_server/ServerUtils.java b/app/src/main/java/net/fengberd/minecraftpe_server/ServerUtils.java
new file mode 100644
index 0000000..92b8c71
--- /dev/null
+++ b/app/src/main/java/net/fengberd/minecraftpe_server/ServerUtils.java
@@ -0,0 +1,249 @@
+package net.fengberd.minecraftpe_server;
+
+import java.io.*;
+import java.nio.charset.Charset;
+
+import android.content.Context;
+
+public final class ServerUtils
+{
+ public static Context mContext;
+
+ private static OutputStream stdin;
+ private static InputStream stdout;
+
+ final public static void setContext(Context mContext)
+ {
+ ServerUtils.mContext=mContext;
+ }
+
+ final public static String getAppDirectory()
+ {
+ return mContext.getApplicationInfo().dataDir;
+ }
+
+ final public static String getDataDirectory()
+ {
+ String dir=android.os.Environment.getExternalStorageDirectory().getPath() + (HomeActivity.nukkitMode?"/Nukkit":"/PocketMine");
+ new File(dir).mkdirs();
+ return dir;
+ }
+
+ final public static Boolean killProcessByName(String mProcessName)
+ {
+ return execCommand(getAppDirectory() + "/busybox killall -9 " + mProcessName);
+ }
+
+ final public static void stopServer()
+ {
+ killProcessByName(HomeActivity.nukkitMode?"java":"php");
+ }
+
+ static Process serverProc;
+
+ public static Boolean isRunning()
+ {
+ try
+ {
+ serverProc.exitValue();
+ }
+ catch(Exception e)
+ {
+ return true;
+ }
+ return false;
+ }
+
+ final public static void runServer()
+ {
+ File f = new File(getDataDirectory(),"/tmp");
+ if(!f.exists())
+ {
+ f.mkdir();
+ }
+ else if(!f.isDirectory())
+ {
+ f.delete();
+ f.mkdir();
+ }
+ setPermission();
+ String file = "/Nukkit.jar";
+ if(!HomeActivity.nukkitMode)
+ {
+ if(new File(getDataDirectory() + "/PocketMine-MP.phar").exists())
+ {
+ file="/PocketMine-MP.phar";
+ }
+ else
+ {
+ file = "/src/pocketmine/PocketMine.php";
+ }
+ }
+ File ini=new File(getDataDirectory() + "/php.ini");
+ if(!HomeActivity.nukkitMode && !ini.exists())
+ {
+ try
+ {
+ ini.createNewFile();
+ FileOutputStream os=new FileOutputStream(ini);
+ os.write("phar.readonly=0\nphar.require_hash=1\ndate.timezone=Asia/Shanghai\nshort_open_tag=0\nasp_tags=0\nopcache.enable=1\nopcache.enable_cli=1\nopcache.save_comments=1\nopcache.fast_shutdown=0\nopcache.max_accelerated_files=4096\nopcache.interned_strings_buffer=8\nopcache.memory_consumption=128\nopcache.optimization_level=0xffffffff".getBytes("UTF8"));
+ os.close();
+ }
+ catch(Exception e)
+ {
+
+ }
+ }
+ String[] args=null;
+ if(HomeActivity.nukkitMode)
+ {
+ args=new String[]
+ {
+ getAppDirectory() + "/java/jre/bin/java",
+ "-jar",
+ getDataDirectory() + file,
+ HomeActivity.ansiMode?"enable-ansi":"disable-ansi"
+ };
+ }
+ else
+ {
+ args=new String[]
+ {
+ getAppDirectory() + "/php",
+ "-c",
+ getDataDirectory() + "/php.ini",
+ getDataDirectory() + file,
+ HomeActivity.ansiMode?"--enable-ansi":"--disable-ansi"
+ };
+ }
+ ProcessBuilder builder = new ProcessBuilder(args);
+ builder.redirectErrorStream(true);
+ builder.directory(new File(getDataDirectory()));
+ builder.environment().put("TMPDIR",getDataDirectory() + "/tmp");
+ try
+ {
+ serverProc=builder.start();
+ stdout=serverProc.getInputStream();
+ stdin=serverProc.getOutputStream();
+ Thread tMonitor = new Thread()
+ {
+ public void run()
+ {
+ InputStreamReader reader = new InputStreamReader(stdout,Charset.forName("UTF-8"));
+ BufferedReader br = new BufferedReader(reader);
+ while(isRunning())
+ {
+ try
+ {
+ char[] buffer = new char[8192];
+ int size = 0;
+ while((size = br.read(buffer,0,buffer.length)) != -1)
+ {
+ StringBuilder s = new StringBuilder();
+ for(int i = 0; i < size; i++)
+ {
+ char c = buffer[i];
+ if(c == '\r')
+ {
+ continue;
+ }
+ if(c == '\n' || c == '\u0007')
+ {
+ String line = s.toString();
+ if(c == '\u0007' && line.startsWith("\u001B]0;"))
+ {
+ //Do nothing.
+ }
+ else
+ {
+ LogActivity.log(line);
+ }
+ s=new StringBuilder();
+ }
+ else
+ {
+ s.append(buffer[i]);
+ }
+ }
+ }
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ try
+ {
+ br.close();
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ LogActivity.log("[PE Server] Server was stopped.");
+ HomeActivity.stopNotifyService();
+ }
+ };
+ tMonitor.start();
+ }
+ catch(Exception e)
+ {
+ LogActivity.log("[PE Server] Unable to start "+(HomeActivity.nukkitMode?"Java":"PHP")+".");
+ LogActivity.log(e.toString());
+ HomeActivity.stopNotifyService();
+ killProcessByName(HomeActivity.nukkitMode?"java":"php");
+ }
+ return;
+ }
+
+ final public static boolean execCommand(String mCommand)
+ {
+ Runtime r = Runtime.getRuntime();
+ try
+ {
+ r.exec(mCommand).waitFor();
+ }
+ catch(Exception e)
+ {
+ r=null;
+ return false;
+ }
+ return true;
+ }
+
+ final static public void setPermission()
+ {
+ try
+ {
+ if(HomeActivity.nukkitMode)
+ {
+ Runtime.getRuntime().exec("./busybox chmod -R 755 java",new String[0],new File(getAppDirectory())).waitFor();
+ }
+ else
+ {
+ new File(getAppDirectory()+"/php").setExecutable(true,true);
+ }
+ }
+ catch(Exception e)
+ {
+
+ }
+ }
+
+ public static void executeCMD(String Cmd)
+ {
+ try
+ {
+ stdin.write((Cmd + "\r\n").getBytes());
+ stdin.flush();
+ }
+ catch(Exception e)
+ {
+
+ }
+ }
+}
+
diff --git a/app/src/main/res/drawable-hdpi/content_copy.png b/app/src/main/res/drawable-hdpi/content_copy.png
new file mode 100644
index 0000000..72c6bc6
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/content_copy.png differ
diff --git a/app/src/main/res/drawable-hdpi/content_discard.png b/app/src/main/res/drawable-hdpi/content_discard.png
new file mode 100644
index 0000000..ffd19d9
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/content_discard.png differ
diff --git a/app/src/main/res/drawable-hdpi/hardware_dock.png b/app/src/main/res/drawable-hdpi/hardware_dock.png
new file mode 100644
index 0000000..37f3a93
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/hardware_dock.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_launcher.png b/app/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..143b1a7
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml
new file mode 100644
index 0000000..435f242
--- /dev/null
+++ b/app/src/main/res/layout/activity_home.xml
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_log.xml b/app/src/main/res/layout/activity_log.xml
new file mode 100644
index 0000000..0d469c1
--- /dev/null
+++ b/app/src/main/res/layout/activity_log.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml
new file mode 100644
index 0000000..4275202
--- /dev/null
+++ b/app/src/main/res/values-zh/strings.xml
@@ -0,0 +1,36 @@
+
+
+ MinecraftPE 服务器
+
+ PE Server
+ 控制台
+
+ 发送
+ 关闭服务器
+ 开启服务器
+ 挂载Java运行库(ROOT)
+ 安装PHP
+ 安装Java
+
+ Nukkit
+ PocketMine
+ 启用ANSI支持
+ 使用 ku.sud 请求root权限
+
+ 已复制.
+ 正在运行
+ 点击打开 MinecraftPE 服务器
+ 正在安装,请稍候...
+ 安装失败:
+ 安装成功.
+ 安装失败,请将 "nukkit_library.tar.gz" 放入
+
+ 服务器管理
+ 辅助工具
+ 服务器类型
+
+ 控制台
+ 强制停止服务器
+ 清空
+ 复制
+
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..fe991af
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,4 @@
+
+ 16dp
+ 16dp
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..254e0d8
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,36 @@
+
+
+ MinecraftPE Server
+
+ PE Server
+ Console
+
+ Send
+ Stop Server
+ Start Server
+ Mount Java Library(ROOT)
+ Install PHP
+ Install Java
+
+ Nukkit
+ PocketMine
+ Enable ANSI support
+ Use ku.sud to request root
+
+ Copied.
+ is running
+ Tap to open MinecraftPE Server
+ Installing,Please wait...
+ Install failed:
+ Install successfully.
+ Install failed,please put "nukkit_library.tar.gz" to
+
+ Server Management
+ Assistant Tools
+ Server Type
+
+ Console
+ Kill server
+ Clear
+ Copy
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..b096e9c
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..3e7c358
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.+'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..d3db109
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':app'