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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
|
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Threading;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Media;
using System.Drawing;
using System.Xml;
using System.Windows.Forms;
namespace love2dToAPK {
class Compiler {
public string ProjectPath { get; set; }
public string ResponseCode { get; set; }
private string _toolsPath = AppDomain.CurrentDomain.BaseDirectory;
private string _packageIdentifier;
public bool BuildSuccessful;
public Compiler(string projectPath) {
ProjectPath = projectPath;
_toolsPath += "//tools//";
}
public void compile() {
/* the actual routine is in compile-routine, this is because we want a nicer looking try-catch thing */
try {
compileRoutine();
log("###############################");
log("BUILD SUCCESSFULL!!!");
log("###############################");
Program.frmOutput.setColor(ColorTranslator.FromHtml("#13c116"));
SystemSounds.Hand.Play();
BuildSuccessful = true;
} catch (Exception e) {
log("###############################");
log("BUILD FAILED!!!");
log("###############################");
log(e.ToString());
Program.frmOutput.setColor(ColorTranslator.FromHtml("#e01616"));
SystemSounds.Asterisk.Play();
BuildSuccessful = false;
}
}
private void compileRoutine() {
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
log("-- Starting compiler --");
log(">> Checking for required files...");
requiredFilesExist();
log(">> Cleaning up old junk...");
cleanupOldJunk();
log(">> Getting project settings...");
extractProjectSettings();
log(">> Zipping source-dir...");
ZipFile.CreateFromDirectory(ProjectPath, "tools\\game.love");
log(">> Putting all the files in the bowl, mixing, and pouring them to different locations.");
lastPreparationBeforeCompiling();
log(">> Launching Ant-compiler...");
runAnt();
log(">> Move build to build folder...");
moveOutputFiles();
log(">> Cleanup...");
cleanUpNewJunk();
log(">> Installing on phone");
moveToPhone();
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
log("-- Finished compiling in " + elapsedTime + " --");
}
private void requiredFilesExist() {
/* This method checks if all the required tools and files exist */
// This directory is required because everything that is needed during the compilation is here
if (!Directory.Exists("tools")) {
throw new Exception("TOOLS NOT FOUND; PANICKING! SUPRISE MAFA**A, THERE IS NO CAKE!");
}
// This directory is required becuase we want to have something to compile
if (!Directory.Exists(ProjectPath)) {
throw new Exception("Project folder not found! \n path at " + ProjectPath);
}
}
private void cleanupOldJunk() {
/* This method cleans up old files that could be left behind from old compilations */
// Not really nececarry, just to stop the folder from entering our game.love file
if (Directory.Exists(ProjectPath + "\\build\\")) {
log("Buildfolder found, deleting before compiling...");
Directory.Delete(ProjectPath + "\\build\\", true);
}
// Delete old game.love, to stop us from conflicts when zipping the project
if (File.Exists("tools\\game.love")) {
log("Deleting old game.love");
File.Delete("tools\\game.love");
}
// Delete old game.apk, this is not really a problem, as we are going to copy it elsewehre anyway
if (File.Exists("tools\\game.apk")) {
log("Deleting old game apk");
File.Delete("tools\\game.apk");
}
// Delete old source compilation, again to protect from conflicts
if (Directory.Exists("tools\\tools\\love-android-sdl2\\src\\love")) {
log("Deleting old source-folder");
Directory.Delete("tools\\tools\\love-android-sdl2\\src\\love", true);
}
// This is the old game.love file, again, stop from conflicts.
if (File.Exists("tools\\tools\\love-android-sdl2\\assets\\game.love")) {
log("Deleting old game apk");
File.Delete("tools\\tools\\love-android-sdl2\\assets\\game.love");
}
}
private void extractProjectSettings() {
/* This copies potential custom app settings, and reads things like the app name.
* For when we are going to use ADB later */
// Delete old manifest file, to protect from conflicts
if (File.Exists(_toolsPath + "tools\\love-android-sdl2\\AndroidManifest.xml")) {
File.Delete(_toolsPath + "tools\\love-android-sdl2\\AndroidManifest.xml");
}
// Copy manifest file from project path if it exists
// If not we want the default manifest file.
if (File.Exists(ProjectPath + "\\AndroidManifest.xml")) {
log("Found manifest file.");
File.Copy(ProjectPath + "\\AndroidManifest.xml", _toolsPath + "tools\\love-android-sdl2\\AndroidManifest.xml");
} else {
log("No maifest file found, using default,");
File.Copy(_toolsPath + "tools\\love-android-sdl2\\original\\AndroidManifest.xml", _toolsPath + "tools\\love-android-sdl2\\AndroidManifest.xml");
}
// We should do something about our icon here as well
// Read package identifier from the androidManifest
XmlDocument doc = new XmlDocument();
doc.Load(_toolsPath + "tools\\love-android-sdl2\\AndroidManifest.xml");
_packageIdentifier = doc.SelectSingleNode("manifest").Attributes["package"].InnerText;
}
private void zipGameSource() {
}
private void lastPreparationBeforeCompiling() {
/* This method will make the sourceDir,
* get the new game.love file, fiddle with the icon and generate LtaActivityFile */
// Create the source-dir
Directory.CreateDirectory("tools\\tools\\love-android-sdl2\\src\\love");
Directory.CreateDirectory("tools\\tools\\love-android-sdl2\\src\\love\\to");
Directory.CreateDirectory("tools\\tools\\love-android-sdl2\\src\\love\\to\\android");
// Fetch the new game.love file
File.Move("tools\\game.love", "tools\\tools\\love-android-sdl2\\assets\\game.love");
// TODO Move icon to folder, have to make a default as well. Move icon to root in extractProjectSettings
generateLtaActivityFile();
}
private void generateLtaActivityFile() {
/* I Have no clue what this file really does,
* but to change the package name we have to generate it
* instead of just copying it from source */
string[] lines = {
"package " + _packageIdentifier + ";",
"import org.love2d.android.GameActivity;",
"",
"public class LtaActivity extends GameActivity {}"
};
File.WriteAllLines("tools\\tools\\love-android-sdl2\\src\\love\\to\\android\\LtaActivity.java", lines);
}
private void runAnt() {
/* This runs a batch file that excecutes the compiler-batch-thingy ANT */
var processInfo = new ProcessStartInfo();
processInfo.WorkingDirectory = _toolsPath;
processInfo.FileName = "cmd.exe";
processInfo.Arguments = "/c startAnt.bat";
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
var process = Process.Start(processInfo);
process.OutputDataReceived += (object sender, DataReceivedEventArgs e) => log(e.Data);
process.BeginOutputReadLine();
process.ErrorDataReceived += (object sender, DataReceivedEventArgs e) => log("[error] >> " + e.Data);
process.BeginErrorReadLine();
process.WaitForExit();
log("Exitcode: " + process.ExitCode.ToString());
process.Close();
}
private void moveOutputFiles() {
Directory.CreateDirectory(ProjectPath + "\\build\\");
File.Copy("tools\\tools\\love-android-sdl2\\bin\\love_android_sdl2-debug.apk", ProjectPath + "\\build\\game.apk");
}
private void cleanUpNewJunk() {
File.Delete("tools\\game.love");
File.Delete("tools\\game.apk");
}
private void moveToPhone() {
adb adb = new adb();
adb.install(ProjectPath + "\\build\\game.apk"); // This installs the app, if an older version exists, update it.
log(">> Launching app, please make sure it is unlocked. If it isn't monkey might go crazy!!!");
Thread.Sleep(1000);
adb.launchApp(_packageIdentifier);
}
private void log(string str) {
Program.frmOutput.log(str);
}
}
}
|