diff options
| author | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2022-02-17 04:38:05 +0900 | 
|---|---|---|
| committer | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2022-02-17 04:38:05 +0900 | 
| commit | bae16c41fd728ac411bee9baef69433d508ecc63 (patch) | |
| tree | 64cda39fb51066084f602f54fa5f15938469e7ae | |
| parent | cc700c1118f22d4ab63d7c2fe214e5cace25eeb0 (diff) | |
rtp support wiprtp-support
| -rwxr-xr-x | AndroidManifest.xml | 3 | ||||
| -rw-r--r-- | build.gradle | 5 | ||||
| -rw-r--r-- | jni/Android.mk | 2 | ||||
| -rw-r--r-- | jni/Application.mk | 2 | ||||
| -rw-r--r-- | jni/libmspack.mk | 15 | ||||
| -rw-r--r-- | jni/unshield.mk | 14 | ||||
| -rw-r--r-- | src/pw/cloudef/rpg/Launcher.java | 1 | ||||
| -rw-r--r-- | src/pw/cloudef/rpg/Rtp.java | 133 | 
8 files changed, 174 insertions, 1 deletions
| diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 19d351a..924d827 100755 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -26,6 +26,9 @@             >             <meta-data android:name="android.app.lib_name" android:value=""/>          </activity> +        <activity android:name=".Rtp" android:exported="true"> +           <meta-data android:name="android.app.lib_name" android:value="" /> +        </activity>          <activity android:name=".Launcher" android:exported="true">             <meta-data android:name="android.app.lib_name" android:value="" />          </activity> diff --git a/build.gradle b/build.gradle index cbd2455..2fcbde4 100644 --- a/build.gradle +++ b/build.gradle @@ -61,4 +61,9 @@ android {            universalApk false         }      } +    buildTypes { +       debug { +          jniDebuggable true +       } +    }  } diff --git a/jni/Android.mk b/jni/Android.mk index b0cbf4c..fd15b4e 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -15,6 +15,8 @@ include jni/SDL_mixer/Android.mk  LOCAL_PATH := .  include jni/SDL_mixer.vorbis.mk  include jni/boost.mk +include jni/libmspack.mk +include jni/unshield.mk  include jni/OpenAL.mk  include jni/SDL_sound.mk  include jni/physfs.mk diff --git a/jni/Application.mk b/jni/Application.mk index 91f5cd6..dd8341a 100644 --- a/jni/Application.mk +++ b/jni/Application.mk @@ -4,5 +4,5 @@ APP_OPTIM := release  APP_STL := c++_static  APP_CPPFLAGS := -std=c++11 -frtti -fexceptions  APP_CFLAGS := -fsigned-char -UNDEBUG -APP_MODULES := mkxp easyrpg physfs-serve +APP_MODULES := mkxp easyrpg physfs-serve cabextract unshield  APP_DEBUG := 1 diff --git a/jni/libmspack.mk b/jni/libmspack.mk new file mode 100644 index 0000000..f7e53f8 --- /dev/null +++ b/jni/libmspack.mk @@ -0,0 +1,15 @@ +include $(CLEAR_VARS) +LOCAL_C_INCLUDES := jni/libmspack/libmspack/mspack +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES) +LOCAL_MODULE := mspack +LOCAL_SRC_FILES := $(filter-out %/debug.c, $(wildcard jni/libmspack/libmspack/mspack/*.c)) +include $(BUILD_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_CFLAGS := -DVERSION=\"1.9.1\" -DHAVE_MKDIR -DHAVE_ICONV -DHAVE_UMASK -DICONV_CONST= -pie +LOCAL_C_INCLUDES := jni/libmspack/cabextract +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES) +LOCAL_MODULE := cabextract +LOCAL_SRC_FILES := jni/libmspack/cabextract/src/cabextract.c jni/libmspack/cabextract/md5.c +LOCAL_STATIC_LIBRARIES := mspack iconv +include $(BUILD_SHARED_LIBRARY) diff --git a/jni/unshield.mk b/jni/unshield.mk new file mode 100644 index 0000000..1d1d406 --- /dev/null +++ b/jni/unshield.mk @@ -0,0 +1,14 @@ +include $(CLEAR_VARS) +LOCAL_CFLAGS := -DHAVE_ICONV -DUSE_OUR_OWN_MD5 -DSIZE_FORMAT=\"%%zu\" -pie +LOCAL_C_INCLUDES := jni/unshield +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES) +LOCAL_MODULE := unshield +LOCAL_SRC_FILES := jni/unshield/src/unshield.c $(wildcard jni/unshield/lib/*.c) jni/unshield/lib/md5/md5c.c jni/unshield/lib/convert_utf/ConvertUTF.c +LOCAL_STATIC_LIBRARIES := iconv +LOCAL_LDLIBS := -lz + +jni/unshield/lib/unshield_config.h: +	touch $@ + +unshield: jni/unshield/lib/unshield_config.h +include $(BUILD_SHARED_LIBRARY) diff --git a/src/pw/cloudef/rpg/Launcher.java b/src/pw/cloudef/rpg/Launcher.java index ab2e9b2..1a5659d 100644 --- a/src/pw/cloudef/rpg/Launcher.java +++ b/src/pw/cloudef/rpg/Launcher.java @@ -52,6 +52,7 @@ public class Launcher extends Activity {           GameType type = GameType.UNKNOWN;           while (zipEntries.hasMoreElements()) {              String fname = ((ZipEntry)zipEntries.nextElement()).getName(); +            Log.d("pw.cloudef.rpg", fname);              try {                 String base = fname.split(".+?/(?=[^/]+$)")[1];                 String name = base.split("\\.(?=[^\\.]+$)")[0]; diff --git a/src/pw/cloudef/rpg/Rtp.java b/src/pw/cloudef/rpg/Rtp.java new file mode 100644 index 0000000..e647cdb --- /dev/null +++ b/src/pw/cloudef/rpg/Rtp.java @@ -0,0 +1,133 @@ +package pw.cloudef.rpg; +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.net.Uri; +import android.system.Os; +import android.util.Log; +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.FileOutputStream; +import java.nio.charset.Charset; +import java.util.zip.ZipFile; +import java.util.zip.ZipEntry; +import java.util.Enumeration; + +public class Rtp extends Activity { +   protected String rtpDir() { +      return getApplicationContext().getFilesDir().toPath().toString() + "/rtp"; +   } + +   protected String workDir() { +      return getApplicationContext().getCacheDir().toPath().toString() + "/temp"; +   } + +   protected String zipPath() { +      return workDir() + "/rtp.zip"; +   } + +   protected void shell(String cmd) { +      try { Runtime.getRuntime().exec(cmd); } catch (Exception e) {} +   } + +   protected void rm(String path) { +      shell("rm -rf '" + path + "'"); +   } + +   protected void run(String cmd, String args, String input) { +      shell("'" + getApplicationContext().getApplicationInfo().nativeLibraryDir + "/" + cmd + "' " + args + " '" + workDir() + "/" + input + "'"); +   } + +   protected boolean matches(String name, String[] wants) { +      for (int i = 0; i < wants.length; ++i) if (name.equals(wants[i])) return true; +      return false; +   } + +   protected void unzip(File file, String[] wants, String dest) { +      ZipFile zipFile; +      try { +         zipFile = new ZipFile(file, java.util.zip.ZipFile.OPEN_READ, Charset.forName("Windows-31J")); +      } catch (Exception e) { +         Log.d("pw.cloudef.rpg", e.toString()); +         return; +      } + +      try { +         Enumeration zipEntries = zipFile.entries(); +         while (zipEntries.hasMoreElements()) { +            final ZipEntry entry = (ZipEntry)zipEntries.nextElement(); +            if (!matches(entry.getName(), wants)) continue; +            InputStream input = zipFile.getInputStream(entry); +            String base = entry.getName().split(".+?/(?=[^/]+$)")[1]; +            File out = new File(dest, base); +            if (!out.getCanonicalPath().startsWith(dest)) +               throw new Exception("Zip path traversal detected"); +            out.mkdirs(); +            OutputStream output = new FileOutputStream(out); +            byte[] buf = new byte[8 * 1024]; +            for (int read = 0; (read = input.read(buf)) != -1;) output.write(buf, 0, read); +            output.close(); input.close(); +            break; +         } +      } catch (Exception e) { +         Log.d("pw.cloudef.rpg", e.toString()); +      } + +      try { zipFile.close(); } catch (Exception e) {} +   } + +   protected String rtpId() { +      return getIntent().getExtras().getString("id"); +   } + +   protected void onCreate(Bundle savedInstanceState) { +      super.onCreate(savedInstanceState); +      try { +         InputStream input = getContentResolver().openInputStream(getIntent().getData()); +         File file = new File(zipPath()); +         file.mkdirs(); +         OutputStream output = new FileOutputStream(file); +         byte[] buf = new byte[8 * 1024]; +         for (int read = 0; (read = input.read(buf)) != -1;) output.write(buf, 0, read); +         output.close(); input.close(); +         if (rtpId().equals("2000") || rtpId().equals("2003")) { +            String prefix = (rtpId().equals("2003") ? "2003" : ""); +            // STEP 1 unzip +            unzip(file, new String[]{prefix + "RTPセットアップ/" + rtpId() + "RTP.exe"}, workDir()); +            // STEP 2 cabextract +            run("libcabextract.so", "-d '" + workDir() + "' -e CP932 ", rtpId() + "RTP.exe"); +            // STEP 3 unshield +            run("libunshield.so", "-d '" + workDir() + "' -e CP932 x", "data1.cab"); +            run("libunshield.so", "-d '" + workDir() + "' -e CP932 x", "data2.cab"); +         } else if (rtpId().equals("XP")) { +            // STEP 1 unzip +            unzip(file, new String[]{"RPGXP_RTP103/Setup.exe"}, workDir()); +            // STEP 2 innoextract +            run("libinnoextract.so", "-d '" + workDir() + "' -I app ", "Setup.exe"); +            // STEP 3 move to RTP dir +            shell("mv '" + workDir() + "/app' '" + rtpDir() + "/XP'"); +         } else if (rtpId().equals("VX")) { +            // STEP 1 unzip +            unzip(file, new String[]{"RPGVX_RTP202/setup.exe"}, workDir()); +            // STEP 2 innoextract +            run("libinnoextract.so", "-d '" + workDir() + "' -I app ", "setup.exe"); +            // STEP 3 move to RTP dir +            shell("mv '" + workDir() + "/app' '" + rtpDir() + "/VX'"); +         } else if (rtpId().equals("VXAce")) { +            // STEP 1 unzip +            unzip(file, new String[]{"RPGVXAce_RTP100/Setup.exe", "RPGVXAce_RTP100/Setup-1.bin"}, workDir()); +            // STEP 2 innoextract +            run("libinnoextract.so", "-d '" + workDir() + "' -I app ", "Setup.exe"); +            // STEP 3 move to RTP dir +            shell("mv '" + workDir() + "/app' '" + rtpDir() + "/VXAce'"); +         } else { +            throw new Exception("Unknown RTP"); +         } +      } catch (Exception e) { +         Log.d("pw.cloudef.rpg", e.toString()); +      } +      // rm(workDir()); +      finishAndRemoveTask(); +   } +} | 
