summaryrefslogtreecommitdiff
path: root/src/pw/cloudef/rpg/Rtp.java
blob: e647cdbce4c5ff590b0cab92b0ad3715aa88f315 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
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();
   }
}