Browse Source

Added old sources; initial commit.

Ondřej Hruška 5 years ago
parent
commit
3d7bda9331
100 changed files with 39615 additions and 0 deletions
  1. 41 0
      .classpath
  2. 2 0
      .gitignore
  3. 17 0
      .project
  4. 11 0
      .settings/org.eclipse.jdt.core.prefs
  5. BIN
      lib/OpenAL32.dll
  6. BIN
      lib/OpenAL64.dll
  7. BIN
      lib/commons-io-2.4-src.zip
  8. BIN
      lib/commons-io-2.4.jar
  9. BIN
      lib/commons-logging-1.1.1.jar
  10. BIN
      lib/httpclient-4.2.2.jar
  11. BIN
      lib/httpcomponents-client-4.2.2-src.zip
  12. BIN
      lib/httpcore-4.2.2.jar
  13. BIN
      lib/jdom-2.0.3-sources.zip
  14. BIN
      lib/jdom-2.0.3.jar
  15. BIN
      lib/jinput-dx8.dll
  16. BIN
      lib/jinput-dx8_64.dll
  17. BIN
      lib/jinput-raw.dll
  18. BIN
      lib/jinput-raw_64.dll
  19. BIN
      lib/jinput.jar
  20. BIN
      lib/jogg-0.0.7.jar
  21. BIN
      lib/jorbis-0.0.15.jar
  22. BIN
      lib/libjinput-linux.so
  23. BIN
      lib/libjinput-linux64.so
  24. BIN
      lib/libjinput-osx.jnilib
  25. BIN
      lib/liblwjgl.jnilib
  26. BIN
      lib/liblwjgl.so
  27. BIN
      lib/liblwjgl64.so
  28. BIN
      lib/libopenal.so
  29. BIN
      lib/libopenal64.so
  30. BIN
      lib/lwjgl-source-2.8.4.zip
  31. BIN
      lib/lwjgl.dll
  32. BIN
      lib/lwjgl.jar
  33. BIN
      lib/lwjgl64.dll
  34. BIN
      lib/lwjgl_util.jar
  35. BIN
      lib/slick-util-src.zip
  36. BIN
      lib/slick-util.jar
  37. 390 0
      php-server/class.DbUtil.php
  38. 35 0
      php-server/class.SimpleDocument.php
  39. 38 0
      php-server/class.Util.php
  40. 207 0
      php-server/class.XmlGen.php
  41. 75 0
      php-server/db-structure-mysql.php
  42. 423 0
      php-server/levels/alpha14test.xml
  43. 22 0
      php-server/mysql.php
  44. 281 0
      php-server/server.php
  45. 53 0
      res/drivers/base.xml
  46. 41 0
      res/drivers/bird.xml
  47. 81 0
      res/drivers/burger.xml
  48. 73 0
      res/drivers/cube.xml
  49. 340 0
      res/drivers/driver_doc.xml
  50. 38 0
      res/drivers/falcon.xml
  51. 19 0
      res/drivers/fighter.xml
  52. 19 0
      res/drivers/manifest.xml
  53. 15 0
      res/drivers/mine.xml
  54. 78 0
      res/drivers/powerup.xml
  55. 61 0
      res/drivers/shark.xml
  56. BIN
      res/fonts/atomic_clock_radio.ttf
  57. BIN
      res/fonts/digital_dream/bold.ttf
  58. BIN
      res/fonts/digital_dream/bold_italic.ttf
  59. BIN
      res/fonts/digital_dream/italic.ttf
  60. BIN
      res/fonts/digital_dream/narrow.ttf
  61. BIN
      res/fonts/digital_dream/narrow_bold.ttf
  62. BIN
      res/fonts/digital_dream/narrow_italic.ttf
  63. BIN
      res/fonts/digital_dream/narrow_italic_bold.ttf
  64. BIN
      res/fonts/digital_dream/normal.ttf
  65. BIN
      res/fonts/lcd_a/mono/bold.ttf
  66. BIN
      res/fonts/lcd_a/mono/heavy.ttf
  67. BIN
      res/fonts/lcd_a/mono/light.ttf
  68. BIN
      res/fonts/lcd_a/mono/normal.ttf
  69. BIN
      res/fonts/lcd_a/prop/bold.ttf
  70. BIN
      res/fonts/lcd_a/prop/heavy.ttf
  71. BIN
      res/fonts/lcd_a/prop/light.ttf
  72. BIN
      res/fonts/lcd_a/prop/normal.ttf
  73. BIN
      res/fonts/lcd_b/bold.ttf
  74. BIN
      res/fonts/lcd_b/boldi.ttf
  75. BIN
      res/fonts/lcd_b/italic.ttf
  76. BIN
      res/fonts/lcd_b/normal.ttf
  77. BIN
      res/fonts/simple/narrow.ttf
  78. BIN
      res/fonts/simple/normal.ttf
  79. BIN
      res/fonts/simple/outline.ttf
  80. BIN
      res/fonts/simple/wide.ttf
  81. BIN
      res/fonts/spaceage.ttf
  82. BIN
      res/images/designer_icons.png
  83. BIN
      res/images/particles_blend.png
  84. BIN
      res/images/particles_plain.png
  85. BIN
      res/images/shield.png
  86. 108 0
      res/levels/designer.xml
  87. 9 0
      res/levels/manifest.xml
  88. 56 0
      res/levels/template.xml
  89. 13 0
      res/models/asteroids/asteroid02.mtl
  90. 5467 0
      res/models/asteroids/asteroid02.obj
  91. 13 0
      res/models/asteroids/asteroid03.mtl
  92. 7887 0
      res/models/asteroids/asteroid03.obj
  93. 13 0
      res/models/asteroids/asteroid04.mtl
  94. 7887 0
      res/models/asteroids/asteroid04.obj
  95. 14 0
      res/models/asteroids/asteroid05.mtl
  96. 7887 0
      res/models/asteroids/asteroid05.obj
  97. 14 0
      res/models/asteroids/asteroid06.mtl
  98. 7887 0
      res/models/asteroids/asteroid06.obj
  99. BIN
      res/models/asteroids/black.jpg
  100. 0 0
      res/models/asteroids/brown.jpg

+ 41 - 0
.classpath View File

@@ -0,0 +1,41 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<classpath>
3
+	<classpathentry kind="src" path="src"/>
4
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
5
+	<classpathentry kind="lib" path="lib/jinput.jar" sourcepath="lib/lwjgl-source-2.8.4.zip">
6
+		<attributes>
7
+			<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="Sector-game/lib"/>
8
+		</attributes>
9
+	</classpathentry>
10
+	<classpathentry kind="lib" path="lib/lwjgl_util.jar" sourcepath="lib/lwjgl-source-2.8.4.zip">
11
+		<attributes>
12
+			<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="Sector-game/lib"/>
13
+		</attributes>
14
+	</classpathentry>
15
+	<classpathentry kind="lib" path="lib/lwjgl.jar" sourcepath="lib/lwjgl-source-2.8.4.zip">
16
+		<attributes>
17
+			<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="Sector-game/lib"/>
18
+		</attributes>
19
+	</classpathentry>
20
+	<classpathentry kind="lib" path="lib/slick-util.jar" sourcepath="lib/slick-util-src.zip">
21
+		<attributes>
22
+			<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="Sector-game/lib"/>
23
+		</attributes>
24
+	</classpathentry>
25
+	<classpathentry kind="lib" path="lib/jogg-0.0.7.jar">
26
+		<attributes>
27
+			<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="Sector-game/lib"/>
28
+		</attributes>
29
+	</classpathentry>
30
+	<classpathentry kind="lib" path="lib/jorbis-0.0.15.jar">
31
+		<attributes>
32
+			<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="Sector-game/lib"/>
33
+		</attributes>
34
+	</classpathentry>
35
+	<classpathentry kind="lib" path="lib/jdom-2.0.3.jar" sourcepath="lib/jdom-2.0.3-sources.zip"/>
36
+	<classpathentry kind="lib" path="lib/httpclient-4.2.2.jar" sourcepath="lib/httpcomponents-client-4.2.2-src.zip"/>
37
+	<classpathentry kind="lib" path="lib/httpcore-4.2.2.jar" sourcepath="lib/httpcomponents-client-4.2.2-src.zip"/>
38
+	<classpathentry kind="lib" path="lib/commons-io-2.4.jar" sourcepath="lib/commons-io-2.4-src.zip"/>
39
+	<classpathentry kind="lib" path="lib/commons-logging-1.1.1.jar"/>
40
+	<classpathentry kind="output" path="bin"/>
41
+</classpath>

+ 2 - 0
.gitignore View File

@@ -0,0 +1,2 @@
1
+/bin/
2
+*~

+ 17 - 0
.project View File

@@ -0,0 +1,17 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<projectDescription>
3
+	<name>Sector-game</name>
4
+	<comment></comment>
5
+	<projects>
6
+	</projects>
7
+	<buildSpec>
8
+		<buildCommand>
9
+			<name>org.eclipse.jdt.core.javabuilder</name>
10
+			<arguments>
11
+			</arguments>
12
+		</buildCommand>
13
+	</buildSpec>
14
+	<natures>
15
+		<nature>org.eclipse.jdt.core.javanature</nature>
16
+	</natures>
17
+</projectDescription>

+ 11 - 0
.settings/org.eclipse.jdt.core.prefs View File

@@ -0,0 +1,11 @@
1
+eclipse.preferences.version=1
2
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
4
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
5
+org.eclipse.jdt.core.compiler.compliance=1.6
6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
7
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
8
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
9
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
10
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
11
+org.eclipse.jdt.core.compiler.source=1.6

BIN
lib/OpenAL32.dll View File


BIN
lib/OpenAL64.dll View File


BIN
lib/commons-io-2.4-src.zip View File


BIN
lib/commons-io-2.4.jar View File


BIN
lib/commons-logging-1.1.1.jar View File


BIN
lib/httpclient-4.2.2.jar View File


BIN
lib/httpcomponents-client-4.2.2-src.zip View File


BIN
lib/httpcore-4.2.2.jar View File


BIN
lib/jdom-2.0.3-sources.zip View File


BIN
lib/jdom-2.0.3.jar View File


BIN
lib/jinput-dx8.dll View File


BIN
lib/jinput-dx8_64.dll View File


BIN
lib/jinput-raw.dll View File


BIN
lib/jinput-raw_64.dll View File


BIN
lib/jinput.jar View File


BIN
lib/jogg-0.0.7.jar View File


BIN
lib/jorbis-0.0.15.jar View File


BIN
lib/libjinput-linux.so View File


BIN
lib/libjinput-linux64.so View File


BIN
lib/libjinput-osx.jnilib View File


BIN
lib/liblwjgl.jnilib View File


BIN
lib/liblwjgl.so View File


BIN
lib/liblwjgl64.so View File


BIN
lib/libopenal.so View File


BIN
lib/libopenal64.so View File


BIN
lib/lwjgl-source-2.8.4.zip View File


BIN
lib/lwjgl.dll View File


BIN
lib/lwjgl.jar View File


BIN
lib/lwjgl64.dll View File


BIN
lib/lwjgl_util.jar View File


BIN
lib/slick-util-src.zip View File


BIN
lib/slick-util.jar View File


+ 390 - 0
php-server/class.DbUtil.php View File

@@ -0,0 +1,390 @@
1
+<?php
2
+class DbUtil{
3
+	public static function registerNewUser($name, $password, $email = "", $country = ""){
4
+		$name = mysql_real_escape_string($name);
5
+		$password = mysql_real_escape_string($password);
6
+		$country = mysql_real_escape_string($country);
7
+		$email = mysql_real_escape_string($email);
8
+		
9
+		$result = self::query("SELECT COUNT(*) FROM `SECTOR_USERS` WHERE `name` = '$name';");
10
+		$rows=0;
11
+		list($rows) = mysql_fetch_row($result);
12
+		if($rows != 0){
13
+			XmlGen::error_exit("REGISTRATION_FAILED","Entered name is already taken.");
14
+		}
15
+
16
+		$uid = "";
17
+		while(true){
18
+			$uid = "U-".Util::uniqueString(12);
19
+			$result = self::query("SELECT COUNT(*) FROM `SECTOR_USERS` WHERE `uid` = '$uid' AND `removed` = '0';");
20
+			$row = mysql_fetch_row($result);
21
+			if($row[0] == 0) break;
22
+		}
23
+
24
+		$time = time();
25
+
26
+		self::query("
27
+			INSERT 
28
+				INTO `SECTOR_USERS`
29
+					(`uid`,`name`,`password`,`email`,`reg_time`,`country`)
30
+				VALUES 
31
+					('$uid','$name','$password','$email','$time','$country');
32
+		");
33
+
34
+		self::refreshLogin($uid);
35
+
36
+		exit();
37
+	}
38
+/*
39
+		$_REQUEST["uid"],
40
+		$_REQUEST["name"],
41
+		$_REQUEST["password"],
42
+		$_REQUEST["email"],
43
+		$_REQUEST["country"]
44
+*/
45
+
46
+	public static function deleteProfile($uid){
47
+
48
+		$u = mysql_real_escape_string($uid);
49
+		self::query("UPDATE `SECTOR_USERS` SET `removed`='1' WHERE `uid` = '$u' LIMIT 1;");
50
+		self::query("UPDATE `SECTOR_SCORES` SET `removed`='1' WHERE `uid` = '$u';");
51
+
52
+//		self::query("DELETE FROM `SECTOR_USERS` WHERE `uid` = '$u' LIMIT 1;");
53
+//		self::query("DELETE FROM `SECTOR_SCORES` WHERE `uid` = '$u';");
54
+
55
+		echo XmlGen::deleteMessage();
56
+
57
+		exit();
58
+	}
59
+
60
+
61
+
62
+	public static function modifyProfile($uid,$name,$password,$email,$country){
63
+
64
+		if($name == null && $password == null && $email == null && $country == null){
65
+			XmlGen::error_exit("INCOMPLETE_COMMAND","Nothing to change.");
66
+		}
67
+
68
+		$n = mysql_real_escape_string($name);
69
+		$u = mysql_real_escape_string($uid);
70
+		$result = self::query("SELECT COUNT(*) FROM `SECTOR_USERS` WHERE `name` = '$n' AND `uid` != '$u';");
71
+		$rows=0;
72
+		list($rows) = mysql_fetch_row($result);
73
+		if($rows != 0){
74
+			XmlGen::error_exit("NAME_NOT_UNIQUE");
75
+		}
76
+
77
+
78
+		$sql = "";
79
+		
80
+		if($name != null){
81
+			$sql .= ",`name` = '".mysql_real_escape_string($name)."'";
82
+		}
83
+
84
+		if($password != null){
85
+			$sql .= ",`password` = '".mysql_real_escape_string($password)."'";
86
+		}
87
+
88
+		if($email == null) $email = "";
89
+		
90
+		$sql .= ",`email` = '".mysql_real_escape_string($email)."'";
91
+		
92
+
93
+		if($country == null) $country = "";
94
+
95
+		$sql .= ",`country` = '".mysql_real_escape_string($country)."'";
96
+		
97
+
98
+		$sql = substr($sql,1);
99
+
100
+		self::query("
101
+			UPDATE `SECTOR_USERS`
102
+				SET $sql
103
+				WHERE `uid` = '$uid'
104
+				LIMIT 1;
105
+		");
106
+
107
+		self::refreshLogin($uid);
108
+
109
+		exit();		
110
+	}
111
+
112
+	public static function logIn($name, $passwordHash){
113
+		$name = mysql_real_escape_string(trim($name));
114
+		
115
+		$result = self::query("SELECT `uid`,`password` FROM `SECTOR_USERS` WHERE `name` = '$name' AND `removed` = '0';");
116
+
117
+		if(mysql_num_rows($result) == 0){
118
+			XmlGen::error_exit("LOGIN_FAILED","Bad name or password.");
119
+		}
120
+
121
+		$row = mysql_fetch_assoc($result);
122
+		$dbPwd = $row['password'];
123
+		$uid = $row['uid'];
124
+		
125
+		// double hash with ugly salt!
126
+		if( Util::calcSecureHash($name,$dbPwd) != $passwordHash){
127
+			XmlGen::error_exit("LOGIN_FAILED","Bad name or password.");
128
+		}
129
+
130
+		self::refreshLogin($uid);
131
+
132
+		exit();
133
+	}
134
+
135
+	public static function isTokenValid($uid, $token){
136
+		$uid = mysql_real_escape_string($uid);
137
+		$result = self::query("SELECT `auth_token` FROM `SECTOR_USERS` WHERE `uid` = '$uid' AND `removed` = '0';");
138
+
139
+		if(mysql_num_rows($result) == 0){
140
+			return false; // bad UID
141
+		}
142
+
143
+		$row = mysql_fetch_array($result);
144
+		return $row[0] == $token;
145
+	}
146
+	
147
+	public static function getInfo(){
148
+		
149
+		$result = self::query("SELECT * FROM `SECTOR_INFO`;");
150
+
151
+		$entries = array();
152
+
153
+		while($row = mysql_fetch_row($result)){
154
+			$entries[$row[0]] = $row[1];
155
+		}
156
+		
157
+		$version = $entries['VERSION_NUMBER']+0;
158
+		
159
+		if($_REQUEST["VERSION"]<=$version){
160
+			// only publicly available releases are counted,
161
+			// not prepared ones with higher version number
162
+			
163
+			// add to counter.
164
+			$midnight = strtotime('midnight');
165
+			
166
+			$result = self::query("SELECT COUNT(*) FROM `SECTOR_COUNTER` WHERE `date` = '$midnight';");
167
+			$row = mysql_fetch_array($result);
168
+			if($row[0] == 0){
169
+				self::query("INSERT INTO `SECTOR_COUNTER`(`date`,`visits`) VALUES ('$midnight','1');");
170
+			}else{
171
+				self::query("UPDATE `SECTOR_COUNTER` SET `visits`=`visits`+1 WHERE `date` = '$midnight' LIMIT 1;");
172
+			}
173
+		}
174
+
175
+		echo XmlGen::infoTable($entries);
176
+
177
+		exit();
178
+	}
179
+
180
+	public static function getUsers(){
181
+		
182
+		$result = self::query("SELECT `name`,`reg_time`,`country` FROM `SECTOR_USERS` WHERE `removed` = '0';");
183
+
184
+		$entries = array();
185
+
186
+		while($row = mysql_fetch_array($result)){
187
+			$entries[] = $row;
188
+		}
189
+
190
+		echo XmlGen::userList($entries);
191
+
192
+		exit();
193
+	}
194
+
195
+
196
+	public static function getLevels(){
197
+
198
+		$result = self::query("SELECT `value` FROM `SECTOR_INFO` WHERE `key` = 'LEVELS_PATH';");
199
+		$row = mysql_fetch_array($result);
200
+		$path = $row[0];
201
+
202
+		
203
+		$result = self::query("SELECT `lid`,`title`,`filename`,`checksum`,`time` FROM `SECTOR_LEVELS` WHERE `removed` = '0';");
204
+
205
+		$entries = array();
206
+
207
+		while($row = mysql_fetch_array($result)){
208
+			$row[2] = $path.$row[2];
209
+			$entries[] = $row;
210
+		}
211
+
212
+		echo XmlGen::levelList($entries);
213
+
214
+		exit();
215
+	}
216
+
217
+	public static function getLevelScores($lid, $changeFlag = null, $lastRecord = null){
218
+		$lid = mysql_real_escape_string($lid);
219
+
220
+		$result = self::query("SELECT COUNT(*) FROM `SECTOR_LEVELS` WHERE `lid` = '$lid' AND `removed` = '0';");
221
+		$row = mysql_fetch_array($result);
222
+		$cnt = $row[0];
223
+		
224
+		if($cnt==0) XmlGen::error_exit("NO_SUCH_LEVEL","No level with matching ID was found.");
225
+
226
+		$result = self::query("
227
+			SELECT 
228
+				`SECTOR_USERS`.`name` AS `username`,
229
+				`SECTOR_SCORES`.`uid`,
230
+				`SECTOR_SCORES`.`time`,
231
+				`SECTOR_SCORES`.`score`
232
+			FROM `SECTOR_SCORES` JOIN `SECTOR_USERS`
233
+			WHERE 
234
+				(`SECTOR_SCORES`.`uid` = `SECTOR_USERS`.`uid`)
235
+				AND	(`lid`='$lid')
236
+				AND (`SECTOR_SCORES`.`removed` = '0')
237
+			ORDER BY `score` DESC, `time` DESC;
238
+		");
239
+		
240
+		// username, uid, time, score
241
+		$entries = array();
242
+
243
+		while($row = mysql_fetch_array($result)){
244
+			$entries[] = $row;
245
+		}
246
+
247
+		echo XmlGen::scoreList($lid, $entries, $changeFlag, $lastRecord);
248
+
249
+		exit();
250
+	}
251
+
252
+	public static function submitScore($uid, $lid, $score){
253
+		$lid = mysql_real_escape_string($lid);
254
+		$uid = mysql_real_escape_string($uid);
255
+		$score = $score+0;
256
+
257
+		$result = self::query("SELECT COUNT(*) FROM `SECTOR_LEVELS` WHERE `lid` = '$lid' AND `removed` = '0';");
258
+		$row = mysql_fetch_array($result);
259
+		$cnt = $row[0];
260
+
261
+		if($cnt==0) XmlGen::error_exit("NO_SUCH_LEVEL","No level with matching ID was found.");
262
+
263
+		
264
+		$result = self::query("SELECT COUNT(*) FROM `SECTOR_SCORES` WHERE `lid` = '$lid' AND `uid` = '$uid';");
265
+		$row = mysql_fetch_array($result);
266
+		$cnt = $row[0];
267
+
268
+		$time = time();
269
+		
270
+		$change = "false";
271
+		$lastRecord = "-1";
272
+
273
+		if($cnt==0){
274
+			// INSERT
275
+			self::query("INSERT INTO `SECTOR_SCORES`(`uid`,`lid`,`time`,`score`) VALUES ('$uid','$lid','$time','$score');");
276
+			$change = "true";
277
+		}else{
278
+			$result = self::query("SELECT `score` FROM `SECTOR_SCORES` WHERE `lid` = '$lid' AND `uid` = '$uid';");
279
+			$row = mysql_fetch_array($result);
280
+			$scoreOld = $row[0];
281
+			
282
+			$lastRecord = "$scoreOld";
283
+			if($scoreOld > $score){
284
+				
285
+			}else{			
286
+				// UPDATE
287
+				self::query("UPDATE `SECTOR_SCORES` SET `time`='$time', `score`='$score' WHERE `lid` = '$lid' AND `uid` = '$uid' LIMIT 1;");
288
+				if($scoreOld != $score) $change = "true";
289
+			}
290
+		}
291
+		
292
+		self::getLevelScores($lid, $change, $lastRecord);
293
+
294
+		exit();
295
+	}
296
+
297
+	public static function refreshLogin($uid){
298
+		$token = Util::uniqueString(20);
299
+
300
+		self::query("
301
+			UPDATE `SECTOR_USERS`
302
+				SET `auth_token` = '$token'
303
+				WHERE `uid` = '$uid'
304
+				LIMIT 1;
305
+		");
306
+
307
+		$result = self::query("SELECT `name`,`email`,`reg_time`,`country` FROM `SECTOR_USERS` WHERE `uid` = '$uid';");
308
+		
309
+		$row = mysql_fetch_assoc($result);
310
+
311
+		$name = $row["name"];
312
+		$email = $row["email"];
313
+		$reg_time = $row["reg_time"];
314
+		$country = $row["country"];
315
+
316
+		echo XmlGen::sessionInfo($uid, $token, $name, $email, $reg_time, $country);
317
+	}
318
+
319
+
320
+
321
+	public static function addLevel($title, $filename){
322
+
323
+		$result = self::query("SELECT COUNT(*) FROM `SECTOR_LEVELS` WHERE `filename` = '".mysql_real_escape_string($filename)."';");
324
+		$row = mysql_fetch_array($result);
325
+		$cnt = $row[0];
326
+		
327
+		if($cnt>0) XmlGen::error_exit("LEVEL_ALREADY_ADDED");
328
+
329
+		$result = self::query("SELECT COUNT(*) FROM `SECTOR_LEVELS` WHERE `title` = '".mysql_real_escape_string($title)."';");
330
+		$row = mysql_fetch_array($result);
331
+		$cnt = $row[0];
332
+		
333
+		if($cnt>0) XmlGen::error_exit("LEVEL_NAME_NOT_UNIQUE");
334
+
335
+		$result = self::query("SELECT `value` FROM `SECTOR_INFO` WHERE `key` = 'LEVELS_PATH_RELATIVE_TO_SERVER';");
336
+		$row = mysql_fetch_array($result);
337
+		$path = $row[0];
338
+
339
+		$result = self::query("SELECT `value` FROM `SECTOR_INFO` WHERE `key` = 'LEVELS_PATH';");
340
+		$row = mysql_fetch_array($result);
341
+		$apath = $row[0];
342
+		
343
+		$fpath = $path.$filename;
344
+
345
+
346
+		if(!file_exists($fpath)){
347
+			XmlGen::error_exit("FILE_NOT_FOUND","Level file does not exist: ".$fpath);
348
+		}
349
+
350
+		if(substr($filename,strlen($filename)-4) != ".xml"){
351
+			XmlGen::error_exit("BAD_FILE_FORMAT", "Level file must be XML: ".$fpath);
352
+		}
353
+
354
+
355
+		// generate a LID
356
+		$lid = "";
357
+		while(true){
358
+			$lid = "L-".Util::uniqueString(9);
359
+			$result = self::query("SELECT COUNT(*) FROM `SECTOR_LEVELS` WHERE `lid` = '$lid';");
360
+			$row = mysql_fetch_row($result);
361
+			if($row[0] == 0) break;
362
+		}
363
+
364
+
365
+		$hash = md5_file($fpath);
366
+		
367
+		$title = mysql_real_escape_string($title);
368
+		$filename = mysql_real_escape_string($filename);
369
+		
370
+		$time = time();
371
+		
372
+		
373
+		self::query("
374
+			INSERT 
375
+				INTO `SECTOR_LEVELS`
376
+					(`lid`,`title`,`filename`,`checksum`,`time`)
377
+				VALUES 
378
+					('$lid','$title','$filename','$hash','$time');
379
+		");
380
+
381
+		echo XmlGen::levelAddedInfo($lid, $title, $apath.$filename, $hash, $time);
382
+
383
+		exit();
384
+	}
385
+
386
+	public static function query($q){
387
+		$res = mysql_query($q) or die(XmlGen::error("INTERNAL_ERROR", "DbError: ".mysql_error()));
388
+		return $res;
389
+	}
390
+}

+ 35 - 0
php-server/class.SimpleDocument.php View File

@@ -0,0 +1,35 @@
1
+<?php
2
+
3
+# Class for easier XML generation
4
+class SimpleDocument extends DOMDocument{
5
+	private $rootNode = null;
6
+	public function __construct($rootName='xml', $attribs = array()){
7
+		parent::__construct('1.0', 'UTF-8');
8
+		$rootElement = $this->createElement($rootName, $attribs);
9
+
10
+		$this->rootNode = $this->appendChild($rootElement);
11
+	}
12
+
13
+	public function createAttribute($name, $value){
14
+		$a = parent::createAttribute($name);
15
+		$a->value = $value;
16
+		return $a;
17
+	}
18
+
19
+	public function createElement($name='element', $attribs = null, $inner=''){
20
+		$elem = parent::createElement($name,$inner);
21
+
22
+		if($attribs != null){
23
+			foreach($attribs as $key => $value){
24
+				$a = $this->createAttribute($key, $value);
25
+				$elem->appendChild($a);
26
+			}
27
+		}
28
+		
29
+		return $elem;
30
+	}
31
+
32
+	public function appendChildToRoot(DOMElement $element){
33
+		return $this->rootNode->appendChild($element);
34
+	}
35
+}

+ 38 - 0
php-server/class.Util.php View File

@@ -0,0 +1,38 @@
1
+<?php
2
+class Util{
3
+	// this needs name for salt.
4
+	public static function calcSecureHash($name, $password){
5
+		// !!! When changing this, it must also be changed in the client piece!
6
+		return sha1( $name."S^1edT@R+ kN0w9e".md5( "troe(l01".$password."d*G -? df lo%iUq" )."myL!tT1e(P)0nNY" );
7
+	}
8
+
9
+	public static function uniqueString($len){
10
+		$scale = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
11
+		$token = "";
12
+		for($i=0;$i<$len;$i++){
13
+			$token .= substr($scale, rand(0, strlen($scale)-1), 1);
14
+		}
15
+		return $token;
16
+	}
17
+
18
+	public static function remoteFileExists($url) {
19
+		$curl = curl_init($url);
20
+		curl_setopt($curl, CURLOPT_NOBODY, true);
21
+		$result = curl_exec($curl);
22
+		$ret = false;
23
+		if ($result !== false) {
24
+			$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);  
25
+
26
+			if ($statusCode == 200) {
27
+				$ret = true;   
28
+			}
29
+		}
30
+		curl_close($curl);
31
+		return $ret;
32
+	}
33
+
34
+	public static function trimNullSafe($string){
35
+		if($string == null) return null;
36
+		return trim($string);
37
+	}
38
+}

+ 207 - 0
php-server/class.XmlGen.php View File

@@ -0,0 +1,207 @@
1
+<?php
2
+
3
+global $ERR;
4
+
5
+# XML generator
6
+class XmlGen{
7
+
8
+	public static function sendHeaders(){
9
+		header("content-type: application/xml; charset=UTF-8");
10
+		header("Cache-Control: no-cache, must-revalidate");
11
+	}
12
+
13
+	public static function hashCode($hash){
14
+		self::sendHeaders();
15
+		$doc = new SimpleDocument("hash");
16
+		$doc->appendChildToRoot( $doc->createElement("hash", null, $hash) );
17
+		return $doc->saveXML();
18
+	}
19
+
20
+	public static function deleteMessage(){
21
+		self::sendHeaders();
22
+		$doc = new SimpleDocument("status");
23
+		$doc->appendChildToRoot( $doc->createElement("msg", null, "Profile deleted.") );
24
+		return $doc->saveXML();
25
+	}
26
+
27
+	public static function infoTable($info){
28
+		self::sendHeaders();
29
+		$doc = new SimpleDocument("info");
30
+		foreach($info as $k => $v){
31
+			$eElem = $doc->createElement("entry");
32
+			$enode = $doc->appendChildToRoot($eElem);
33
+
34
+			$enode->appendChild($doc->createElement("key", null, $k));
35
+			$enode->appendChild($doc->createElement("value", null, $v));
36
+		}
37
+		return $doc->saveXML();
38
+	}
39
+
40
+	public static function userList($users){
41
+		self::sendHeaders();
42
+		$doc = new SimpleDocument("users");
43
+		foreach($users as $u){
44
+			$userElem = $doc->createElement("user");
45
+			$unode = $doc->appendChildToRoot($userElem);
46
+
47
+			$unode->appendChild($doc->createElement("name", null, $u[0]));
48
+			$unode->appendChild($doc->createElement("reg_time", null, $u[1]));
49
+			$unode->appendChild($doc->createElement("country", null, $u[2]));
50
+		}
51
+		return $doc->saveXML();
52
+	}
53
+
54
+	public static function levelList($data){ // `lid`,`title`,`filename`,`checksum`,`time`
55
+		self::sendHeaders();
56
+		$doc = new SimpleDocument("levels");
57
+		foreach($data as $l){
58
+			$level = $doc->createElement("level");
59
+			
60
+			$lnode = $doc->appendChildToRoot($level);
61
+			$lnode->appendChild($doc->createElement("lid", null, $l[0]));
62
+			$lnode->appendChild($doc->createElement("title", null, $l[1]));
63
+			$lnode->appendChild($doc->createElement("url", null, $l[2]));
64
+			$lnode->appendChild($doc->createElement("checksum", null, $l[3]));
65
+			$lnode->appendChild($doc->createElement("created", null, $l[4]));
66
+		}
67
+		return $doc->saveXML();
68
+	}
69
+
70
+	public static function scoreList($lid, $data, $changeFlag=null, $lastRecord=null){ // username, uid, time, score
71
+		self::sendHeaders();
72
+		$attrs = array();
73
+		if($changeFlag!=null) $attrs["score_improved"] = $changeFlag;
74
+		if($changeFlag!=null) $attrs["last_score"] = $lastRecord;
75
+		$doc = new SimpleDocument("scores", $attrs);
76
+		foreach($data as $l){
77
+			$level = $doc->createElement("score");
78
+			
79
+			$lnode = $doc->appendChildToRoot($level);
80
+			$lnode->appendChild($doc->createElement("uid", null, $l[1]));
81
+			$lnode->appendChild($doc->createElement("name", null, $l[0]));
82
+			$lnode->appendChild($doc->createElement("time", null, $l[2]));
83
+			$lnode->appendChild($doc->createElement("score", null, $l[3]));
84
+		}
85
+		return $doc->saveXML();
86
+	}
87
+
88
+	public static function levelAddedInfo($lid, $title, $url, $hash, $time){
89
+		self::sendHeaders();
90
+		$doc = new SimpleDocument("level");
91
+
92
+		$doc->appendChildToRoot( $doc->createElement("lid", null, $lid) );
93
+		$doc->appendChildToRoot( $doc->createElement("title", null, $title) );
94
+		$doc->appendChildToRoot( $doc->createElement("url", null, $url) );
95
+		$doc->appendChildToRoot( $doc->createElement("checksum", null, $hash) );
96
+		$doc->appendChildToRoot( $doc->createElement("created", null, $time) );
97
+
98
+		return $doc->saveXML();
99
+	}
100
+
101
+	public static function sessionInfo($uid, $token, $name=null, $email=null, $reg_time=null, $country=null){
102
+		self::sendHeaders();
103
+		$doc = new SimpleDocument("session");
104
+
105
+		$doc->appendChildToRoot( $doc->createElement("uid", null, $uid) );
106
+		$doc->appendChildToRoot( $doc->createElement("auth_token", null, $token) );
107
+
108
+		$doc->appendChildToRoot( $doc->createElement("name", null, $name) );
109
+		$doc->appendChildToRoot( $doc->createElement("email", null, $email) );
110
+		$doc->appendChildToRoot( $doc->createElement("reg_time", null, $reg_time) );
111
+		$doc->appendChildToRoot( $doc->createElement("country", null, $country) );
112
+
113
+		return $doc->saveXML();
114
+	}
115
+
116
+	public static function error($error, $msg=""){
117
+		self::sendHeaders();
118
+		global $ERR;
119
+		$e = $ERR[$error];
120
+		$doc = new SimpleDocument("error");
121
+
122
+		$doc->appendChildToRoot( $doc->createElement("code", null, $e[0]) );
123
+		$doc->appendChildToRoot( $doc->createElement("message", null, $e[1]) );
124
+		$doc->appendChildToRoot( $doc->createElement("cause", null, $msg) );
125
+
126
+		return $doc->saveXML();
127
+	}
128
+
129
+	public static function error_exit($error, $msg=""){
130
+		self::sendHeaders();
131
+		global $ERR;
132
+		$e = $ERR[$error];
133
+		$doc = new SimpleDocument("error");
134
+
135
+		$doc->appendChildToRoot( $doc->createElement("code", null, $e[0]) );
136
+		$doc->appendChildToRoot( $doc->createElement("message", null, $e[1]) );
137
+		$doc->appendChildToRoot( $doc->createElement("cause", null, $msg) );
138
+
139
+		echo $doc->saveXML();
140
+		exit();
141
+	}
142
+
143
+
144
+
145
+	public static function hacking_exit(){
146
+
147
+		srand(round(time()/7200));
148
+
149
+		if(rand(0,10)==0){
150
+			$full_url_path = "http://".$_SERVER['HTTP_HOST'].preg_replace("#/[^/]*\.php$#simU", "/", $_SERVER["PHP_SELF"])."nothingHere.txt";
151
+
152
+			$ch = curl_init();
153
+			$timeout = 5;
154
+			curl_setopt($ch, CURLOPT_URL, $full_url_path);
155
+			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
156
+			curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
157
+			echo curl_exec($ch);
158
+			curl_close($ch);
159
+
160
+/*		echo "<HTML>
161
+<HEAD>
162
+<TITLE>404 Not Found</TITLE>
163
+</HEAD>
164
+<BODY>
165
+<H1>Not Found</H1>
166
+The requested document was not found on this server.
167
+<P>
168
+<HR>
169
+<ADDRESS>
170
+Web Server at ".$_SERVER['SERVER_NAME']."
171
+</ADDRESS>
172
+</BODY>
173
+</HTML>";*/
174
+
175
+			exit();
176
+		}
177
+
178
+		self::sendHeaders();
179
+
180
+		$doc = new SimpleDocument("error");
181
+
182
+		$msgs = array(
183
+			15 => "Internal server error.",
184
+			"Database connection timed out.",
185
+			"Service temporarily overloaded.",
186
+			"Service temporarily not available.",
187
+			"Operation not permitted.",
188
+			"Session has expired.",
189
+			"Brandwidth limit reached, aborting.",
190
+			"Access denied.",
191
+			"Unauthorised server access.",
192
+			"Invalid command exception.",
193
+			"Operation aborted.",
194
+			"Bad database entry format.",
195
+		);
196
+
197
+
198
+		$e = rand(15,15+count($msgs)-1);
199
+
200
+		$doc->appendChildToRoot( $doc->createElement("code", null, $e) );
201
+		$doc->appendChildToRoot( $doc->createElement("message", null, $msgs[$e]) );
202
+		$doc->appendChildToRoot( $doc->createElement("cause", null, "") );
203
+
204
+		echo $doc->saveXML();
205
+		exit();
206
+	}
207
+}

+ 75 - 0
php-server/db-structure-mysql.php View File

@@ -0,0 +1,75 @@
1
+<?php
2
+
3
+// DUMP OF MYSQL DATABASE FOR SECTOR
4
+
5
+/*
6
+
7
+
8
+SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
9
+
10
+
11
+
12
+
13
+CREATE TABLE IF NOT EXISTS `SECTOR_INFO` (
14
+  `key` varchar(30) NOT NULL COMMENT 'Property key',
15
+  `value` text NOT NULL COMMENT 'Property value (text)',
16
+  PRIMARY KEY (`key`)
17
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Information for Sector, eg. Info about updates, messages etc';
18
+
19
+
20
+
21
+
22
+INSERT INTO `SECTOR_INFO` (`key`, `value`) VALUES
23
+('LEVELS_PATH', 'http://www.ondrovo.com/sector/api/levels/'),
24
+('VERSION', 'Alpha 14'),
25
+('VERSION_NUMBER', '14'),
26
+('LEVELS_PATH_RELATIVE_TO_SERVER', 'levels/');
27
+
28
+
29
+
30
+
31
+CREATE TABLE IF NOT EXISTS `SECTOR_LEVELS` (
32
+  `lid` varchar(20) NOT NULL COMMENT 'Level id',
33
+  `title` varchar(120) NOT NULL COMMENT 'Level title (shown is game)',
34
+  `filename` varchar(100) NOT NULL COMMENT 'File name in storage',
35
+  `checksum` varchar(100) NOT NULL COMMENT 'hashcode of the file',
36
+  `time` int(12) unsigned NOT NULL COMMENT 'time of creation',
37
+  PRIMARY KEY (`lid`),
38
+  UNIQUE KEY `title` (`title`)
39
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Table of official sector levels';
40
+
41
+
42
+
43
+
44
+INSERT INTO `SECTOR_LEVELS` (`lid`, `title`, `filename`, `checksum`, `time`) VALUES
45
+('L-i5dvKm6Fv', 'Demo level', 'alpha14test.xml', 'b9d8db8da9c2ca54e78bf8d2a8a2dc6c', 1356545440);
46
+
47
+
48
+
49
+
50
+CREATE TABLE IF NOT EXISTS `SECTOR_SCORES` (
51
+  `id` int(12) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Entry ID',
52
+  `uid` varchar(20) NOT NULL COMMENT 'User ID',
53
+  `lid` varchar(20) NOT NULL COMMENT 'Level ID',
54
+  `time` int(12) NOT NULL COMMENT 'Time when this score has been made',
55
+  `score` int(12) NOT NULL COMMENT 'Highest score for player/level',
56
+  PRIMARY KEY (`id`)
57
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COMMENT='Table of SECTOR highscores';
58
+
59
+
60
+
61
+
62
+CREATE TABLE IF NOT EXISTS `SECTOR_USERS` (
63
+  `uid` varchar(20) NOT NULL COMMENT 'User ID',
64
+  `name` varchar(50) NOT NULL COMMENT 'User''s nickname',
65
+  `password` varchar(80) NOT NULL COMMENT 'User''s password',
66
+  `auth_token` varchar(120) NOT NULL COMMENT 'Authentication code used to make communication more secure.',
67
+  `email` varchar(120) NOT NULL COMMENT 'Email for password recovery',
68
+  `reg_time` int(12) NOT NULL COMMENT 'Registration timestamp (for stats)',
69
+  `country` varchar(120) NOT NULL DEFAULT '' COMMENT 'Country for stats',
70
+  PRIMARY KEY (`uid`),
71
+  UNIQUE KEY `uname` (`name`)
72
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COMMENT='Table of SECTOR''s registered users';
73
+
74
+
75
+*/

+ 423 - 0
php-server/levels/alpha14test.xml View File

@@ -0,0 +1,423 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<level>
3
+
4
+	<info>
5
+		<title>Alpha 14 test level</title>
6
+		<subtitle>Challenge level with bosses</subtitle>
7
+		<author>MightyPork</author>
8
+		<minv>14</minv>
9
+	</info>
10
+
11
+
12
+
13
+	<config>
14
+		<money>40000</money>
15
+		<building>NORMAL</building>
16
+	</config>
17
+	
18
+	
19
+	
20
+
21
+	<discoveries>
22
+		<all level="max" />	
23
+		<discovery name="cannon" level="0" />
24
+	</discoveries>
25
+	
26
+	
27
+	<ship>
28
+	      <dim x="9" y="9" />
29
+			  <sys energy="4" shield="2" />
30
+			  <struct>
31
+			    <row>
32
+			      <null />
33
+			      <null />
34
+			      <null />
35
+			      <piece id="w_cannon" level="3" rotate="0" health="1.5" trigger="BTN_DOWN:0" />
36
+			      <piece id="w_emp" level="1" rotate="0" health="3.0" trigger="BTN_DOWN:1" />
37
+			      <piece id="w_cannon" level="3" rotate="0" health="1.5" trigger="BTN_DOWN:0" />
38
+			      <null />
39
+			      <null />
40
+			      <null />
41
+			    </row>
42
+			    <row>
43
+			      <null />
44
+			      <null />
45
+			      <piece id="w_laser" level="3" rotate="0" health="2.0" trigger="BTN_DOWN:0" />
46
+			      <piece id="bs_triangle" level="1" rotate="90" health="1.5" />
47
+			      <piece id="bs_side1" level="1" rotate="180" health="1.5" />
48
+			      <piece id="bs_triangle" level="1" rotate="0" health="1.5" />
49
+			      <piece id="w_laser" level="3" rotate="0" health="2.0" trigger="BTN_DOWN:0" />
50
+			      <null />
51
+			      <null />
52
+			    </row>
53
+			    <row>
54
+			      <null />
55
+			      <piece id="w_plasma" level="2" rotate="0" health="4.0" trigger="BTN_DOWN:0" />
56
+			      <piece id="bs_triangle" level="1" rotate="90" health="1.5" />
57
+			      <piece id="bs_corner1" level="1" rotate="90" health="1.5" />
58
+			      <piece id="bb_cube" level="1" rotate="0" health="1.5" />
59
+			      <piece id="bs_corner1" level="1" rotate="0" health="1.5" />
60
+			      <piece id="bs_triangle" level="1" rotate="0" health="1.5" />
61
+			      <piece id="w_plasma" level="2" rotate="0" health="4.0" trigger="BTN_DOWN:0" />
62
+			      <null />
63
+			    </row>
64
+			    <row>
65
+			      <piece id="w_plasma" level="2" rotate="0" health="4.0" trigger="BTN_DOWN:0" />
66
+			      <piece id="bw_triangle" level="1" rotate="90" health="1.5" />
67
+			      <piece id="bs_side1" level="1" rotate="270" health="1.5" />
68
+			      <piece id="bb_cube" level="1" rotate="0" health="1.5" />
69
+			      <piece id="bb_cube" level="1" rotate="0" health="1.5" />
70
+			      <piece id="bb_cube" level="1" rotate="0" health="1.5" />
71
+			      <piece id="bs_side1" level="1" rotate="90" health="1.5" />
72
+			      <piece id="bw_triangle" level="1" rotate="0" health="1.5" />
73
+			      <piece id="w_plasma" level="2" rotate="0" health="4.0" trigger="BTN_DOWN:0" />
74
+			    </row>
75
+			    <row>
76
+			      <piece id="bw_triangle" level="1" rotate="90" health="1.5" />
77
+			      <piece id="bw_cube" level="1" rotate="0" health="1.5" />
78
+			      <piece id="bs_side1" level="1" rotate="270" health="1.5" />
79
+			      <piece id="bb_cube" level="1" rotate="0" health="1.5" />
80
+			      <piece id="bb_cube" level="1" rotate="0" health="1.5" />
81
+			      <piece id="bb_cube" level="1" rotate="0" health="1.5" />
82
+			      <piece id="bs_side1" level="1" rotate="90" health="1.5" />
83
+			      <piece id="bw_cube" level="1" rotate="0" health="1.5" />
84
+			      <piece id="bw_triangle" level="1" rotate="0" health="1.5" />
85
+			    </row>
86
+			    <row>
87
+			      <piece id="bw_cube" level="1" rotate="0" health="1.5" />
88
+			      <piece id="bw_cube" level="1" rotate="0" health="1.5" />
89
+			      <piece id="bs_side1" level="1" rotate="270" health="1.5" />
90
+			      <piece id="bb_cube" level="1" rotate="0" health="1.5" />
91
+			      <piece id="bb_cube" level="1" rotate="0" health="1.5" />
92
+			      <piece id="bb_cube" level="1" rotate="0" health="1.5" />
93
+			      <piece id="bs_side1" level="1" rotate="90" health="1.5" />
94
+			      <piece id="bw_cube" level="1" rotate="0" health="1.5" />
95
+			      <piece id="bw_cube" level="1" rotate="0" health="1.5" />
96
+			    </row>
97
+			    <row>
98
+			      <piece id="bw_cube" level="1" rotate="0" health="1.5" />
99
+			      <piece id="bw_triangle" level="1" rotate="270" health="1.5" />
100
+			      <piece id="bs_triangle" level="1" rotate="180" health="1.5" />
101
+			      <piece id="bs_corner1" level="1" rotate="180" health="1.5" />
102
+			      <piece id="bb_cube" level="1" rotate="0" health="1.5" />
103
+			      <piece id="bs_corner1" level="1" rotate="270" health="1.5" />
104
+			      <piece id="bs_triangle" level="1" rotate="270" health="1.5" />
105
+			      <piece id="bw_triangle" level="1" rotate="180" health="1.5" />
106
+			      <piece id="bw_cube" level="1" rotate="0" health="1.5" />
107
+			    </row>
108
+			    <row>
109
+			      <piece id="bw_triangle" level="1" rotate="270" health="1.5" />
110
+			      <null />
111
+			      <null />
112
+			      <piece id="bs_triangle" level="1" rotate="180" health="1.5" />
113
+			      <piece id="bs_side1" level="1" rotate="0" health="1.5" />
114
+			      <piece id="bs_triangle" level="1" rotate="270" health="1.5" />
115
+			      <null />
116
+			      <null />
117
+			      <piece id="bw_triangle" level="1" rotate="180" health="1.5" />
118
+			    </row>
119
+			    <row>
120
+			      <null />
121
+			      <null />
122
+			      <null />
123
+			      <null />
124
+			      <piece id="engine_ion" level="3" rotate="0" health="4.0" />
125
+			      <null />
126
+			      <null />
127
+			      <null />
128
+			      <null />
129
+			    </row>
130
+			  </struct>
131
+	</ship>
132
+
133
+
134
+	<sequence>
135
+		
136
+		<rockshift coord="0;-1" />
137
+	
138
+		<rockgen id="rocks" >
139
+			<type num="-1" />
140
+			<size range="2-8" />
141
+			<speed num="3" />
142
+			<rarity num="10" />
143
+			<x range="-30-30" />
144
+			<z range="100-120" />
145
+		</rockgen>
146
+			
147
+		<pause t="2" />
148
+		<msg str="Welcome to Sector!" t="3" /> 
149
+		<msg str="Level by MightyPork" t="1" /> 
150
+		<msg str="" t="1" /> 
151
+		<msg str="Enjoy!" t="1.5" /> 
152
+		
153
+		<pause t="5" /> 
154
+		
155
+		<shipgen id="mines" >
156
+			<entity str="mine" />
157
+			<rarity num="60" />
158
+			<x range="-10-10" />
159
+			<z range="100-120" />
160
+		</shipgen>
161
+		
162
+		<shipgen id="fighters" >
163
+			<entity str="fighter" />
164
+			<rarity num="110" />
165
+			<size range="0.5-1" />
166
+			<x range="-5-5" />
167
+			<z range="100-120" />
168
+			<wave str="annoyers" />
169
+		</shipgen>
170
+		
171
+		<shipgen id="birds" >
172
+			<entity str="bird" />
173
+			<rarity num="150" />
174
+			<size range="0.5-1" />
175
+			<x range="-15:15" />
176
+			<z range="100-120" />
177
+			<wave str="annoyers" />
178
+		</shipgen>
179
+				
180
+			
181
+		<pause t="5" />
182
+	
183
+		<cycle>
184
+				
185
+			
186
+	<!--  cleanup  -->       
187
+			<disable gen="birds" />	
188
+			<disable gen="fighters" />        
189
+			<wait for="annoyers" />  
190
+			
191
+					
192
+			
193
+	<!--  SNAKEY  -->
194
+			<msg str="Snakey!" t="4"/>
195
+		
196
+			<spawn>
197
+				<entity str="snake" />
198
+				<x range="-20:20" />
199
+				<z range="100:110"/>
200
+				<wave str="boss" />
201
+				<count range="5-7" />
202
+				<dist num="2" />
203
+				<variant range="0-5" />
204
+				<uniform bool="true" />
205
+				<artifact bool="true" />
206
+				<formation str="snake" />
207
+			</spawn>
208
+			
209
+			<wait for="boss" />
210
+			
211
+	<!-- /SNAKEY -->
212
+	
213
+	
214
+	
215
+	<!--  SNAKEY  -->
216
+			<msg str="And snake again!" t="4"/>
217
+		
218
+			<spawn>
219
+				<entity str="snake" />
220
+				<x range="-20:20" />
221
+				<z range="100:110"/>
222
+				<wave str="boss" />
223
+				<count range="5-7" />
224
+				<dist num="2" />
225
+				<variant range="0-5" />
226
+				<uniform bool="true" />
227
+				<artifact bool="true" />
228
+				<formation str="snake" />
229
+			</spawn>
230
+			
231
+			<wait for="boss" />
232
+			
233
+	<!-- /SNAKEY -->
234
+			
235
+			
236
+	
237
+	<!-- BURGERS -->	    
238
+			<pause t="3" />
239
+			<enable gen="birds" />	
240
+			<enable gen="fighters" />
241
+			
242
+			<spawn>
243
+				<entity str="burger" />
244
+				<driver str="burger_zone" />
245
+				<x num="0" />
246
+				<z num="100" />
247
+				<count num="10" />
248
+				<formation str="line" />
249
+				<uniform bool="true" />
250
+				<dist num="3" />
251
+				<wave str="annoyers" />
252
+			</spawn>
253
+			
254
+			<pause t="3" />
255
+			
256
+			<disable gen="birds" />	
257
+			<disable gen="fighters" />	
258
+			<wait for="annoyers" />
259
+	<!-- /BURGERS -->
260
+	
261
+	
262
+	
263
+			
264
+	<!-- Getting ready for SHARK -->
265
+			<disable gen="birds" />	
266
+			<disable gen="fighters" />	
267
+			<disable gen="mines" />			
268
+				
269
+			<msg str="Better reload your shield!" t="3" />
270
+			<wait for="annoyers" />	 
271
+			<disable gen="rocks" />
272
+			<pause t="10" />
273
+		
274
+			
275
+				
276
+	
277
+	<!-- SHARK -->  
278
+			<msg str="* Sushi Time *" t="2" /> 
279
+			<msg str="" t="1" /> 
280
+			<msg str="Want some seafood?" t="3" />  
281
+			<msg str="It's all yours!" t="2" /> 
282
+			<pause t="3" /> 		       
283
+				
284
+			<spawn>
285
+				<entity str="shark" />
286
+				<driver str="shark" />
287
+				<x num="0" />
288
+				<z num="110" />
289
+				<count num="1" />
290
+				<artifact bool="true" />
291
+				<wave str="boss" />
292
+				<health num="2" />
293
+			</spawn>   
294
+			
295
+			<wait for="boss" />	
296
+	<!-- /SHARK -->
297
+	
298
+	
299
+	<!-- Reload shield in some rocks. -->		
300
+			<enable gen="rocks" />	
301
+			<pause t="6" />
302
+			<disable gen="rocks" />
303
+			<pause t="8" />
304
+			
305
+			
306
+			
307
+	<!--  FALCONS  -->
308
+			<msg str="Falcons, oh man!" t="3"/>		
309
+			
310
+			<spawn>
311
+				<entity str="falcon" />
312
+				<driver str="falcon" />
313
+				<x range="-10:10" />
314
+				<z num="110" />
315
+				<count num="3" />
316
+				<wave str="boss" />
317
+				<formation str="row" />
318
+				<dist num="2.5" />
319
+			</spawn>   
320
+			
321
+			<wait for="boss" />
322
+	<!--  /FALCONS -->	
323
+	
324
+			<enable gen="rocks" />
325
+			<msg str="" t="3"/>
326
+			<msg str="Ever played" t="1"/>
327
+			<msg str="MINESWEEPER?" t="3"/>		
328
+			<wait t="10" />	
329
+		
330
+			<disable gen="rocks" />
331
+			<pause t="7" />
332
+			<msg str="WATCH OUT!" t="1.5"/>	
333
+			<pause t="4" />
334
+			
335
+			<rockshift coord="0;-2.5" />
336
+			<repeat i="12">
337
+				
338
+				<spawn>
339
+					<entity str="mine" />
340
+					<scale num="1.3" />
341
+					<x num="0" />
342
+					<z range="110" />
343
+					<count num="15" />
344
+					<wave str="mines" />
345
+					<formation str="row" />
346
+					<dist num="1.5" />
347
+				</spawn>
348
+				
349
+				<pause t="0.08" />
350
+				<rockshift coord="-0.3;-2.5" />
351
+				<pause t="0.08" />
352
+				<rockshift coord="-0.6;-2.5" />
353
+				<pause t="0.08" />
354
+				<rockshift coord="-0.8;-2.5" />
355
+				<pause t="0.08" />
356
+				<rockshift coord="-0.6;-2.5" />
357
+				<pause t="0.08" />
358
+				<rockshift coord="-0.3;-2.5" />
359
+				<pause t="0.08" />
360
+				<pause t="0.08" />
361
+				<rockshift coord="0;-2.5" />
362
+				<pause t="0.08" />
363
+				
364
+				<spawn>
365
+					<entity str="mine" />
366
+					<scale num="1.3" />
367
+					<x num="0" />
368
+					<z range="110" />
369
+					<count num="15" />
370
+					<wave str="mines" />
371
+					<formation str="row" />
372
+					<dist num="1.5" />
373
+				</spawn>
374
+				
375
+				<rockshift coord="0.3;-2.5" />
376
+				<pause t="0.08" />
377
+				<rockshift coord="0.6;-2.5" />
378
+				<pause t="0.08" />
379
+				<rockshift coord="0.8;-2.5" />
380
+				<pause t="0.08" />
381
+				<rockshift coord="0.6;-2.5" />
382
+				<pause t="0.08" />
383
+				<rockshift coord="0.3;-2.5" />
384
+				<pause t="0.08" />
385
+				<rockshift coord="0;-2.5" />
386
+				
387
+			</repeat>
388
+		
389
+			<wait for="mines" />
390
+			<msg str="Wasn't this fun?" t="3"/>
391
+			<rockshift coord="0;-1" />
392
+			<enable gen="rocks" />
393
+		
394
+		
395
+		<!-- a bit of rocks & annoyers -->	
396
+			<msg str="Relax..." t="1.5"/>
397
+			<msg str="You're almost there..." t="3"/>
398
+			<pause t="10" />
399
+			
400
+			<enable gen="birds" />	
401
+			<enable gen="fighters" />	
402
+			<enable gen="mines" />	
403
+			<pause t="10" />
404
+			<disable gen="birds" />	
405
+			<disable gen="fighters" />	
406
+			<disable gen="mines" />	
407
+			
408
+			<msg str="Congratulations!" t="3" />
409
+			<msg str="" t="2" />
410
+			
411
+			<msg str="Welcome to the" t="2" />    		
412
+			<msg str="End of level!" t="3" />	
413
+			
414
+			<msg str="" t="2" />
415
+			<msg str="[repeat all]" t="1" />
416
+			
417
+			<pause t="14" />
418
+					
419
+		</cycle>
420
+		
421
+	</sequence>
422
+
423
+</level>

+ 22 - 0
php-server/mysql.php View File

@@ -0,0 +1,22 @@
1
+<?php
2
+
3
+define("SQL_HOST","localhost");
4
+define("SQL_DBNAME","tridni_net_main");
5
+define("SQL_USERNAME","tridni_net_main");
6
+define("SQL_PASSWORD","ondra");
7
+
8
+mysql_connect(SQL_HOST, SQL_USERNAME, SQL_PASSWORD);
9
+
10
+mysql_set_charset("utf8");
11
+
12
+mysql_select_db(SQL_DBNAME);
13
+
14
+mysql_query(
15
+	"SET NAMES 'utf8' COLLATE 'utf8_general_ci';".
16
+	"SET CHARACTER SET utf8;".
17
+	"SET character_set_client = utf8;".
18
+	"SET character_set_connection = utf8;".
19
+	"SET character_set_results = utf8;"
20
+);
21
+
22
+?>

+ 281 - 0
php-server/server.php View File

@@ -0,0 +1,281 @@
1
+<?php
2
+
3
+# Error codes and messages
4
+$ERR = array(
5
+	"NO_COMMAND"			=> array(0, "No command received."),
6
+	"INVALID_COMMAND" 		=> array(1, "Invalid command requested."),
7
+	"INTERNAL_ERROR" 		=> array(2, "Internal server error."),
8
+	"INCOMPLETE_COMMAND" 	=> array(3, "Incomplete command received"),
9
+	"REGISTRATION_FAILED" 	=> array(4, "Registration failed."),
10
+	"LOGIN_FAILED" 			=> array(5, "Login failed."),
11
+	"INVALID_TOKEN" 		=> array(6, "Authentication failed."),
12
+	"FILE_NOT_FOUND" 		=> array(7, "File does not exist."),
13
+	"BAD_FILE_FORMAT" 		=> array(8, "Bad file format."),
14
+	"LEVEL_ALREADY_ADDED" 	=> array(9, "Level file is already registered to the Global Leaderboard."),
15
+	"LEVEL_NAME_NOT_UNIQUE" => array(10, "Title already used by other level."),
16
+	"NO_SUCH_LEVEL" 		=> array(11, "No such level exists."),
17
+	"HACKING_DETECTED" 		=> array(12, "Access denied."),
18
+);
19
+
20
+define("CFG_FAKE_ERROR_FOR_HACKERS",true);
21
+
22
+
23
+
24
+require_once("mysql.php");
25
+
26
+require_once("class.SimpleDocument.php");
27
+require_once("class.XmlGen.php");
28
+require_once("class.DbUtil.php");
29
+require_once("class.Util.php");
30
+
31
+
32
+
33
+if(isset($_REQUEST["cmd"]) && ($_REQUEST["cmd"]=="ADD_LEVEL")){}else{ //||$_REQUEST["cmd"]=="HASH"
34
+
35
+	// Check if the request came from a genuine Sector game
36
+	$headers = apache_request_headers();
37
+
38
+	if(
39
+		$headers["User-Agent"] != "Sector/HttpHelper"
40
+		or !isset($headers["X-SECTOR-VERSION"])
41
+		or isset($headers["Cookie"])
42
+		or isset($headers["Accept-Encoding"])
43
+		or isset($headers["Accept-Language"])
44
+		or isset($headers["Accept-Charset"])
45
+		or isset($headers["Accept"])
46
+	){
47
+		if(CFG_FAKE_ERROR_FOR_HACKERS){
48
+			XmlGen::hacking_exit();
49
+		}else{
50
+			XmlGen::error_exit("HACKING_DETECTED","Unauthorized server access.");
51
+		}
52
+	}
53
+
54
+	$_REQUEST["VERSION"] = $headers["X-SECTOR-VERSION"]+0;
55
+}
56
+
57
+
58
+
59
+
60
+
61
+if(!isset($_REQUEST["cmd"])){
62
+	XmlGen::error_exit("NO_COMMAND");
63
+}
64
+
65
+
66
+
67
+
68
+switch($_REQUEST["cmd"]){
69
+
70
+	case "REGISTER":
71
+		// check if name and password exist
72
+		if(!isset($_REQUEST["name"]) || !isset($_REQUEST["password"])){
73
+			XmlGen::error_exit("INCOMPLETE_COMMAND","Missing 'name' or 'password'.");
74
+		}
75
+
76
+		// trim, null -> ""
77
+		if(!isset($_REQUEST["email"])) $_REQUEST["email"] = "";
78
+		if(!isset($_REQUEST["country"])) $_REQUEST["country"] = "";
79
+
80
+		$name = trim($_REQUEST["name"]);
81
+		$email = trim($_REQUEST["email"]);
82
+		$password = trim($_REQUEST["password"]);
83
+		$country = trim($_REQUEST["country"]);
84
+
85
+		// check name and password length
86
+		if(strlen($_REQUEST["name"])==0 || strlen($_REQUEST["password"])==0){
87
+			XmlGen::error_exit("INCOMPLETE_COMMAND","Zero-length 'name' or 'password'.");
88
+		}
89
+		
90
+		// register and return uid+auth_token
91
+		DbUtil::registerNewUser(
92
+			$name,
93
+			$password,
94
+			$email,
95
+			$country
96
+		);
97
+
98
+		exit();
99
+
100
+
101
+
102
+	case "EDIT_PROFILE":
103
+		// check if name and password exist
104
+		if(!isset($_REQUEST["uid"]) || !isset($_REQUEST["auth_token"])){
105
+			XmlGen::error_exit("INCOMPLETE_COMMAND","Missing 'uid' or 'auth_token'.");
106
+		}
107
+
108
+		if(!DbUtil::isTokenValid($_REQUEST["uid"], $_REQUEST["auth_token"])){
109
+			XmlGen::error_exit("INVALID_TOKEN");
110
+		}
111
+
112
+		// replace not set variables with nulls
113
+		if(!isset($_REQUEST["email"])) $_REQUEST["email"] = "";
114
+		if(!isset($_REQUEST["country"])) $_REQUEST["country"] = "";
115
+		if(!isset($_REQUEST["name"])) $_REQUEST["name"] = null;
116
+		if(!isset($_REQUEST["password"])) $_REQUEST["password"] = null;
117
+
118
+		$uid = $_REQUEST["uid"];
119
+		$name = Util::trimNullSafe($_REQUEST["name"]);
120
+		$email = trim($_REQUEST["email"]);
121
+		$password = Util::trimNullSafe($_REQUEST["password"]);
122
+		$country = trim($_REQUEST["country"]);
123
+		
124
+		// register and return uid+auth_token
125
+		DbUtil::modifyProfile(
126
+			$uid,
127
+			$name,
128
+			$password,
129
+			$email,
130
+			$country
131
+		);
132
+
133
+		exit();
134
+
135
+
136
+
137
+	case "DELETE_PROFILE":
138
+		// check if name and password exist
139
+		if(!isset($_REQUEST["uid"]) || !isset($_REQUEST["auth_token"])){
140
+			XmlGen::error_exit("INCOMPLETE_COMMAND","Missing 'uid' or 'auth_token'.");
141
+		}
142
+
143
+		if(!DbUtil::isTokenValid($_REQUEST["uid"], $_REQUEST["auth_token"])){
144
+			XmlGen::error_exit("INVALID_TOKEN");
145
+		}
146
+		
147
+		$uid = $_REQUEST["uid"];
148
+		
149
+		// register and return uid+auth_token
150
+		DbUtil::deleteProfile(
151
+			$uid
152
+		);
153
+
154
+		exit();
155
+
156
+
157
+	case "ADD_LEVEL":
158
+		// check if name and password exist
159
+		if(!isset($_REQUEST["title"]) || !isset($_REQUEST["filename"])){
160
+			XmlGen::error_exit("INCOMPLETE_COMMAND","Missing 'title' or 'filename'.");
161
+		}
162
+
163
+		$title = trim($_REQUEST["title"]);
164
+		$file = trim($_REQUEST["filename"]);
165
+
166
+		DbUtil::addLevel(
167
+			$title,
168
+			$file
169
+		);
170
+
171
+		exit();
172
+
173
+
174
+
175
+	case "GET_LEVELS":
176
+		DbUtil::getLevels();
177
+		exit();
178
+
179
+
180
+
181
+	case "GET_SCORES":
182
+		if(!isset($_REQUEST["lid"])){
183
+			XmlGen::error_exit("INCOMPLETE_COMMAND","Missing 'lid'.");
184
+		}
185
+		
186
+		DbUtil::getLevelScores($_REQUEST["lid"]);
187
+
188
+		exit();
189
+
190
+
191
+
192
+	case "LOG_IN":
193
+		// check if name and password exist
194
+		if(!isset($_REQUEST["name"]) || !isset($_REQUEST["password"])){
195
+			XmlGen::error_exit("INCOMPLETE_COMMAND","Missing 'name' or 'password'.");
196
+		}
197
+
198
+		$name = trim($_REQUEST["name"]);
199
+		$password = trim($_REQUEST["password"]);
200
+		
201
+		// log in and return uid+auth_token
202
+		DbUtil::logIn(
203
+			$name,
204
+			$password
205
+		);
206
+
207
+		exit();
208
+
209
+
210
+
211
+	case "GET_PROFILE_INFO":
212
+		if(!isset($_REQUEST["uid"]) || !isset($_REQUEST["auth_token"])){
213
+			XmlGen::error_exit("INCOMPLETE_COMMAND", "Missing 'uid' or 'auth_token'.");
214
+		}
215
+
216
+		if(!DbUtil::isTokenValid($_REQUEST["uid"], $_REQUEST["auth_token"])){
217
+			XmlGen::error_exit("INVALID_TOKEN");
218
+		}
219
+		
220
+		// log in and return uid+auth_token
221
+		DbUtil::refreshLogin(
222
+			$_REQUEST["uid"],
223
+			$_REQUEST["auth_token"]
224
+		);
225
+
226
+		exit();
227
+
228
+
229
+
230
+	case "SUBMIT_SCORE":
231
+		if(!isset($_REQUEST["uid"]) || !isset($_REQUEST["auth_token"])){
232
+			XmlGen::error_exit("INCOMPLETE_COMMAND", "Missing 'uid' or 'auth_token'.");
233
+		}
234
+
235
+		if(!isset($_REQUEST["lid"]) || !isset($_REQUEST["score"])){
236
+			XmlGen::error_exit("INCOMPLETE_COMMAND", "Missing 'lid' or 'score'.");
237
+		}
238
+
239
+		if(!DbUtil::isTokenValid($_REQUEST["uid"], $_REQUEST["auth_token"])){
240
+			XmlGen::error_exit("INVALID_TOKEN");
241
+		}
242
+		
243
+		// log in and return uid+auth_token
244
+		DbUtil::submitScore(
245
+			$_REQUEST["uid"],
246
+			$_REQUEST["lid"],
247
+			$_REQUEST["score"]
248
+		);
249
+
250
+		exit();
251
+
252
+
253
+
254
+// 	case "HASH":
255
+// 		// check if name and password exist
256
+// 		if(!isset($_REQUEST["password"]) || !isset($_REQUEST["name"])){
257
+// 			XmlGen::error_exit("INCOMPLETE_COMMAND", "Missing 'name' or 'password'.");
258
+// 		}
259
+// 		
260
+// 		echo XmlGen::hashCode(Util::calcSecureHash($_REQUEST["name"],$_REQUEST["password"]));
261
+// 
262
+// 		exit();
263
+
264
+
265
+
266
+	case "GET_INFO":
267
+		DbUtil::getInfo();
268
+		exit();
269
+
270
+
271
+
272
+	case "GET_USERS":
273
+		DbUtil::getUsers();
274
+
275
+		exit();
276
+
277
+
278
+
279
+	default:
280
+		XmlGen::error_exit("INVALID_COMMAND");
281
+}

+ 53 - 0
res/drivers/base.xml View File

@@ -0,0 +1,53 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+
3
+<pack>    
4
+    <!-- the most basic ai structure -->
5
+    <driver name="basic">
6
+		<task id="_begin"></task>	  
7
+		<check for="can_fire" id="can_fire"></check>		
8
+		<task if="can_fire" id="fire"></task>
9
+		<task id="fly"></task>
10
+		<task id="avoid"></task>
11
+		<task id="turn"></task>
12
+		<task id="_end"></task>
13
+	</driver>
14
+    
15
+    <!--  -->
16
+	<driver name="basic_ship" extends="basic">		      
17
+		<check replace="can_fire">
18
+			<fn str="CAN_SHOOT" />	
19
+			<gun num="0" />
20
+			<spare str="ENEMY" />		
21
+		</check>
22
+		
23
+		<!-- Needs replace -->
24
+		<task replace="fire"></task>
25
+		
26
+		<!-- Needs replace -->
27
+		<task replace="fly"></task>
28
+		
29
+		<task replace="avoid">
30
+			<fn str="AVOID" />
31
+			<avoid str="NATURAL,SHOT_GOOD,SHOT_BAD,ENEMY,MINE" />
32
+		</task>
33
+		
34
+		<task replace="turn">
35
+		    <fn str="TURN_TO" />
36
+		    <dir coord="MOVE_DIR" />
37
+		</task>
38
+	</driver>
39
+	
40
+	
41
+	<driver name="basic_saucer" extends="basic_ship">
42
+		
43
+		<!-- Needs replace -->
44
+		<task replace="fire"></task>
45
+		
46
+		<task replace="turn">
47
+		    <fn str="ROTATE" />
48
+		    <add num="3" />
49
+		    <random_dir bool="true"/>
50
+		</task>
51
+	</driver>
52
+	
53
+</pack>

+ 41 - 0
res/drivers/bird.xml View File

@@ -0,0 +1,41 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+
3
+<pack>    
4
+	<driver name="bird" extends="basic_ship">   
5
+	    
6
+	    <check for="in_zone" id="ck1" after="can_fire">
7
+			<fn str="IS_IN_RECT" />
8
+			<x range="-20:20" />
9
+			<z range="-20:30" />
10
+		</check>	
11
+		
12
+		<task replace="fire" if="can_fire&amp;in_zone">
13
+			<fn str="SHOOT" />
14
+			<count range="1" />
15
+			<gap_group num="0.6" />
16
+			<gun num="0" />
17
+		</task>
18
+		
19
+		<task replace="fly">
20
+			<fn str="FLY_TO_RECT" />
21
+			<x range="-4-4"/>
22
+			<z range="15-25"/>
23
+			<weight num="30" />
24
+		</task>
25
+		
26
+		
27
+		<task replace="turn">
28
+		    <fn str="TURN_TO" />
29
+		    <dir coord="PLAYER_DIR" />
30
+		</task>
31
+		
32
+		<task replace="avoid">
33
+			<fn str="AVOID" />
34
+			<avoid str="NATURAL,SHOT_GOOD,SHOT_BAD,ENEMY,MINE" />
35
+			<range num="4" />
36
+			<weight num="4" />
37
+			<square bool="true" />
38
+		</task>
39
+		
40
+	</driver>	
41
+</pack>

+ 81 - 0
res/drivers/burger.xml View File

@@ -0,0 +1,81 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+
3
+<pack>
4
+    
5
+	<driver name="burger" extends="basic_saucer">		
6
+		<task replace="fire">
7
+			<fn str="SHOOT" />
8
+			<count range="2:4" />
9
+			<gap_shot num="0.07" />
10
+			<gap_group range="2:4" />
11
+			<gun num="0" />
12
+		</task>
13
+				
14
+		<task replace="avoid">
15
+			<fn str="AVOID" />
16
+			<avoid str="NATURAL,SHOT_GOOD,ENEMY,MINE" />
17
+			<weight num="1" />
18
+		</task>		
19
+			    
20
+	    <task replace="fly">	        
21
+			<fn str="FLY_TO_POINT" />
22
+			<target coord="PLAYER_POS" />
23
+	    </task>
24
+	</driver>
25
+	
26
+	
27
+	<driver name="burger_zone" extends="burger">   	
28
+		<task replace="fly">
29
+			<fn str="FLY_TO_RECT" />
30
+			<x range="-10:10" />
31
+			<z range="25:40" />
32
+			<weight num="60" />
33
+		</task>
34
+	</driver>
35
+	
36
+	<driver name="burger_zone_mad" extends="burger_zone">
37
+		<task replace="fire">
38
+			<fn str="SHOOT" />
39
+			<count range="15-25" />
40
+			<gap_shot num="0.08" />			
41
+			<gap_group range="1:5" />
42
+			<gun num="0" />
43
+		</task>
44
+	</driver>
45
+	
46
+	<driver name="burger_mad" extends="burger_zone">
47
+		<task replace="fire">
48
+			<fn str="SHOOT" />
49
+			<count range="15-25" />
50
+			<gap_shot num="0.08" />			
51
+			<gap_group range="2:5" />
52
+			<gun num="0" />
53
+		</task>
54
+	</driver>
55
+	
56
+	<driver name="burger_king" extends="basic_saucer">
57
+	    
58
+	    <check for="in_zone" id="ck1">
59
+			<fn str="IS_IN_RECT" />
60
+			<x range="-20:20" />
61
+			<z range="-5:70" />
62
+		</check>
63
+		
64
+		<task replace="fire" if="in_zone">
65
+			<fn str="SHOOT" />
66
+			<count range="10:20" />			
67
+			<bullets range="3:5" />
68
+			<gap_group num="1" />
69
+			<gap_shot num="0.02" />
70
+			<gun num="0" /> <!--range="0-1" -->
71
+		</task>
72
+				
73
+	    <task replace="fly">	        
74
+			<fn str="FLY_TO_RECT" />
75
+			<x range="-10:10" />
76
+			<z range="20:40" />
77
+			<weight num="10" />
78
+	    </task>
79
+	</driver>
80
+	
81
+</pack>

+ 73 - 0
res/drivers/cube.xml View File

@@ -0,0 +1,73 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+
3
+<pack>    
4
+	<driver name="cube_snake"> 
5
+	    
6
+	    <check for="in_zone">
7
+			<fn str="IS_IN_RECT" />
8
+			<x range="-20:20" />
9
+			<z range="-20:60" />
10
+		</check>	
11
+	    		
12
+		<check for="fire">
13
+			<fn str="CAN_SHOOT" />	
14
+			<gun num="0" />
15
+			<spare str="ENEMY" />
16
+			<!-- ignore_formation bool="true" /-->
17
+		</check>
18
+			
19
+		<task if="fire*in_zone">
20
+			<fn str="SHOOT" />
21
+			<count range="1:3" />
22
+			<gap_group range="0.5:2.5" />
23
+			<gap_shot num="0.09" />
24
+			<gun num="0" />
25
+		</task>
26
+				
27
+		<task>
28
+		    <fn str="TURN_TO" />
29
+		    <dir coord="MOVE_DIR" />
30
+		</task>
31
+		
32
+		
33
+		<!--  SNAKE CODE  -->		    			
34
+		<check for="is_leader">
35
+			<fn str="IS_LEADER" />	
36
+		</check>	
37
+		
38
+		<check for="is_tail">
39
+			<fn str="IS_TAIL" />	
40
+		</check>	
41
+		
42
+		<task if="is_leader">
43
+			<fn str="FLY_TO_RECT" />
44
+			<x range="-10:10" />
45
+			<z range="25:35" />
46
+			<weight num="5" />
47
+		</task>		
48
+			
49
+		<task if="!is_leader">
50
+			<fn str="FLY_TO_POINT" />			
51
+			<target coord="LEADER_POS" />
52
+			<weight num="10" />
53
+		</task>
54
+		
55
+		<task if="!is_leader">
56
+			<fn str="KEEP_DISTANCE" />
57
+			<from coord="LEADER_POS" />			
58
+			<dist range="1.5:2" />
59
+		</task>
60
+		
61
+		
62
+		<task if="is_leader">
63
+			<fn str="AVOID" />
64
+			<avoid str="ENEMY,MINE,PLAYER,NATURAL,SHOT_GOOD" />
65
+			<weight num="1.5" />
66
+			<range num="5" />
67
+			<ignore_formation bool="true" />
68
+		</task>
69
+
70
+		<!-- END OF SNAKE CODE -->
71
+		
72
+	</driver>
73
+</pack>

+ 340 - 0
res/drivers/driver_doc.xml View File

@@ -0,0 +1,340 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+
3
+<!-- This file shows all that can be done in a driver. -->
4
+
5
+<!-- The root tag "pack" can contain multiple "driver" tags, but nothing else -->
6
+<pack>
7
+	
8
+	<!-- Here we declare a driver -->
9
+	<driver name="driver1">
10
+	    
11
+	    
12
+		<!-- TASKS AND CHECKS -->
13
+	    
14
+		<!--
15
+		
16
+		Inside a driver, there can be various task and check statements.
17
+		[Checks] test something in the drone's environment, and saves the result as a true/false flag.
18
+		[Tasks] perform some actual operation - shoot, steer, rotate and similar.
19
+		
20
+		Tasks can be contitioned by the results of Checks.
21
+		
22
+		There is a list of all existing tasks and checks lower - here for the sake of simplicity
23
+		we will use FAKE tasks and checks.
24
+		-->
25
+		
26
+		
27
+		<!-- the result of a "check" is stored to a flag whose name you declare here -->
28
+		<check id="ck" for="flag_name">
29
+			<!-- some stuff here --> 
30
+		</check>
31
+		
32
+		
33
+		<!--
34
+		task executes only if the given flag is true.
35
+		Use | as OR, & as AND, and brakcets to group the flags.
36
+		
37
+		Example:
38
+			if="((A|B)&(C|D))|E"		
39
+			if="canShoot"
40
+		-->
41
+		<task id="ts" if="flag_name">
42
+			<!-- some stuff here --> 
43
+		</check>
44
+		
45
+		
46
+		
47
+		
48
+		<!-- TASK CONTENTS -->
49
+		
50
+		<task id="fakeTask">
51
+			
52
+			<!-- name of the function used to perform this check or task -->
53
+			<fn str="NAME_OF_THE__FUNCTION" />
54
+			
55
+			<!-- here come arguments for the function -->			
56
+			<argname argtype="argvalue" />
57
+			
58
+			<!--
59
+			Most tasks and checks take several arguments.
60
+			
61
+			Table of argument types:		
62
+					
63
+				str -> "A string value."
64
+				
65
+				num -> Number, integer "12" or float "8.751"			
66
+					(also work for numbers: int, float, double)	
67
+					
68
+				bool -> Boolean.
69
+					Allowed values are "true", "false", "0", "1", "yes", "no"	
70
+							
71
+				range -> numeric range
72
+					format: "MIN:MAX", eg. "-13:15.5" or "3:5"
73
+					Use RANGE in place of NUM to make it generate random number from range.
74
+					That can be used for all task functions.
75
+				
76
+				coord -> a coordinate, or a vector
77
+					format: "X_COORD;Z_COORD"
78
+					This is because the Sector's scene is flat, all is at Y=0
79
+					You can use both integer and float numbers.
80
+					
81
+					Coord has one special feature: MAGIC VALUES!
82
+					If you declare the argument as coord, but stuff it with a "magic" string value,
83
+					it will become a dynamic coordinate, always returning calculated value of the
84
+					"magic" coordinate.	Example: coord="MOVE_DIR"
85
+					
86
+					Magic values:
87
+						PLAYER_POS - player's current position
88
+						PLAYER_MOTION - player's current motion vector
89
+						
90
+						POS	- current position
91
+						MOTION - current motion vector of this ship
92
+						
93
+						MOVE_DIR - same as MOTION
94
+						PLAYER_DIR - vector towards player ship
95
+				
96
+			-->			
97
+			
98
+			<!-- real-life examples -->
99
+			<dir coord="PLAYER_DIR" />
100
+			<fn str="FLY_TO_RECT" />
101
+			<gap_shot num="3" />
102
+			<gap_group range="3:5" />
103
+			<hello str="world" />
104
+			
105
+		</task>
106
+		
107
+	</driver>
108
+	
109
+	
110
+	
111
+	<!-- INHERITANCE -->
112
+	
113
+	<!-- 
114
+	
115
+	Drivers can be extended, their tasks and checks overriden.
116
+	
117
+	Replacing task does not need to define the "if" and "for", unless you want 
118
+	to replace their value with your own.
119
+	
120
+	It's illegal to extend driver not defined yet. If your drivers are spread
121
+	among multiple files, make sure they are properly ordered in the manifest file. 
122
+	
123
+	-->
124
+	
125
+	<driver name="base_driver">	    
126
+	    
127
+	    <!-- 
128
+	    "id" attribute of Task or Check contains an unique identifier of the task.
129
+	    "id" is not required, but in case you want to extend your driver it is neccesary.
130
+	    
131
+	    Task with empty contents will be considered as abstract = do-nothing task.
132
+	     -->
133
+	    
134
+	    <!-- here come some abstract tasks (will do nothing if not overriden) -->
135
+	    <check for="flag1" id="myCheck"></check>		
136
+		<task if="flag1" id="myTask"></task>
137
+		
138
+		<!-- Rotate task, implemented here - but can be overriden too. -->
139
+		<task id="rotateTask">
140
+		    <fn str="ROTATE" />
141
+		    <add num="-3" />
142
+		</task>
143
+		
144
+	</driver>
145
+		
146
+	<!-- here is a driver extending "base_driver" -->
147
+	<driver name="droid" extends="base_driver">	 
148
+		
149
+	    <!-- this task will replace entirely a task "myTask" from "base_driver" -->
150
+	    <!-- note that here we dont need to define the "if" condition - it's inherited. -->
151
+		<task replace="myTask">		    
152
+			<fn str="SHOOT" />
153
+			<count range="1" />
154
+			<gap_group range="3" />
155
+			<gun num="0" />			
156
+		</task>
157
+		
158
+		<!-- how to add new tasks -->
159
+		
160
+		<!-- this task is added newly, and is placed right after "rotateTask" from "base_driver" -->
161
+		<task id="steer" after="rotateTask">
162
+		    <!-- something here -->
163
+		</task>
164
+		
165
+		<!-- here we want to put this before "myCheck" -->
166
+		<task id="aim" before="myCheck">
167
+		    <!-- something here -->
168
+		</task>
169
+		
170
+		<!-- note: before and after keywords work in all tasks, not only when extending -->
171
+		
172
+	</driver>
173
+	
174
+	
175
+	
176
+	<!-- LIST OF ALL TASKS AND CHECKS -->
177
+	
178
+	<!-- Asterisk * indicates optional arguments. -->
179
+	
180
+	<driver name="library">
181
+	    
182
+	    <!-- Steer towards given coordinate -->
183
+	    <task>
184
+	        <fn str="FLY_TO_POINT" />
185
+	        
186
+	        <target coord="0;0" /> 		<!-- the target coordinate; exact coord or magic word, eg. PLAYER_POS -->
187
+	        <weight num="1" /> 			<!-- * how fast to change direction (default 1) - can be float. -->
188
+	        
189
+	        <!-- if you do not define "target", you can use these: -->
190
+	        <!-- target will be set to random coord in between, and preserved in memory -->
191
+	        <x range="-3:3" />
192
+	        <z range="5:10" />
193
+	        
194
+	    </task>
195
+	    
196
+	    
197
+	    
198
+	    <!-- Steer towards given rectangular zone -->
199
+	    <task>
200
+	        <fn str="FLY_TO_RECT" />
201
+
202
+	        <x range="-3:3" />	<!-- The rectangular zone is defined by it's MIN and MAX coord - it is axis-aligned. -->
203
+	        <z range="5:10" />
204
+	        
205
+	        <weight num="1" /> 			<!-- * how fast to change direction (default 1) - can be float. -->
206
+	    </task>
207
+	    
208
+	    
209
+	    
210
+	    <!-- 
211
+	    Homming missile AI	    
212
+	    Locks to one particular enemy it selects, and then navigates to crash into it.
213
+	    Should be used together with AVOID task
214
+	    -->
215
+	    <task>
216
+	        <fn str="FOLLOW_TARGET" />
217
+	        
218
+	        <target str="PLAYER,NATURAL" />		<!-- List of allowed targets (PLAYER, NATURAL, ENEMY, SHOT_GOOD, SHOT_BAD, POWERUP etc.) -->
219
+	        <range num="60" /> 					<!-- * radar radius - zone from which the targets can be chosen -->
220
+	    </task>
221
+	    
222
+	    
223
+	    
224
+	    <!-- 
225
+	    Magnetic missile AI	    
226
+	    When gets close to a suitable enemy, flies towards it as if attracted by a magnet.
227
+	    -->
228
+	    <task>
229
+	        <fn str="MAGNET" />
230
+	        
231
+	        <target str="PLAYER,NATURAL" />		<!-- List of allowed targets (PLAYER, NATURAL, ENEMY, SHOT_GOOD, SHOT_BAD, POWERUP etc.) -->	        
232
+	        <range num="15" /> 					<!-- * radar radius - zone from which the targets can be chosen -->	        
233
+	        <weight num="1" /> 					<!-- * how fast to change direction (default 1) - can be float. -->
234
+	    </task>
235
+	    
236
+	    
237
+	    
238
+	    <!-- Avoid enemies and obstacles -->
239
+	    <task>
240
+	        <fn str="AVOID" />
241
+	                
242
+	        <range num="3" /> 			<!-- * max distance of obstacle to notice it (counted from surface of collider) -->	        
243
+	        <weight num="1" /> 			<!-- * steering weight (default 1) -->
244
+	        <square bool="false" />		<!-- * if enabled, the strength grows with proximity by square -->	
245
+	        <avoid str="NATURAL,SHOT_GOOD,SHOT_BAD,ENEMY" />
246
+	    </task>
247
+	    
248
+	    
249
+	    
250
+	    <!-- Add angle to rotation -->
251
+	    <task>
252
+	        <fn str="ROTATE" />
253
+	                	
254
+	        <add num="3" />				<!-- degrees to add -->	   
255
+	        <random_dir bool="true" />	<!-- * direction is random (CW, CWW) - chosen when first run; default=false --> 
256
+	    </task>
257
+	    
258
+	    
259
+	    
260
+	    <!-- Rotate to direction -->
261
+	    <task>
262
+	        <fn str="TURN_TO" />
263
+	        	                
264
+	        <dir coord="MOVE_DIR" /> <!-- vector X;Z, or "magic" keywords MOVE_DIR, PLAYER_DIR -->	    
265
+	    </task>
266
+	    
267
+	    	
268
+	    
269
+	    <!--
270
+	    Shoot a gun
271
+	    	    
272
+	    This task allows two types of operation: 
273
+	    X------X------X------X--- ...
274
+	    X-X-X------X-X-X------X-X-X--- ...	    
275
+	    (times are in seconds)
276
+	    -->
277
+	    <task>
278
+	        <fn str="SHOOT" />
279
+	        	                
280
+	        <count num="3" />			<!-- number of shots in a group -->
281
+	        <gap_shot num="0.07" />		<!-- * gap between two shots in a group (optional if count=0) -->
282
+	        <gap_group num="3" />		<!-- gap between two groups -->
283
+	        
284
+	        <gun num="0" />				<!-- * gun index, telling the drone which gun to fire -->	        
285
+	    </task>
286
+	    
287
+	    
288
+	        
289
+	    <!-- Heal - in given interval adds health points to the drone's health meter -->
290
+	    <task>
291
+	        <fn str="HEAL" />
292
+	        	                
293
+	        <gap num="1" />				<!-- gap (sec) betwen healings -->
294
+	        <add num="5" />				<!-- health points to add --> 
295
+	        <percent bool="true" />		<!-- indicates that "heal" is in % of max health -->  
296
+	    </task>
297
+	    
298
+	    <!-- ### CHECKS ###  -->
299
+	    	        
300
+	    <!-- 	    
301
+	    Check: can shoot in direction?
302
+	    You can use this to make sure your shots won't hit an allied ship. 
303
+	    -->
304
+	    <check for="x">
305
+	        <fn str="CAN_SHOOT" />
306
+	        
307
+	        <spare str="ENEMY" />		<!-- list of entity types to spare (the allied entities) -->   
308
+	        <gun num="0" />				<!-- * index of the gun probed -->
309
+	    </check>
310
+	    
311
+	    
312
+	    	    	        
313
+	    <!-- Check: is drone in a rectangular zone? -->
314
+	    <check for="x">
315
+	        <fn str="IS_IN_RECT" />
316
+	        	        
317
+	        <!-- The rectangular zone is defined by it's MIN and MAX coord - it is axis-aligned. -->
318
+	        <x range="-3:3" />
319
+	        <z range="5:10" />
320
+	    </check>
321
+	    
322
+	    
323
+	    
324
+	    <!-- Check: is this ship a leader of the formation? -->
325
+	    <check for="x"/>
326
+	    	<fn str="IS_LEADER" />
327
+	    </check>
328
+	    
329
+	
330
+	
331
+	    <!-- Check: is this ship a tail = last ship of the formation? -->
332
+	    <check for="x"/>
333
+	    	<fn str="IS_TAIL" />
334
+	    </check>
335
+	    
336
+	</driver>
337
+	
338
+	<!-- that's all, now you can start inventing your own AIs! -->
339
+	
340
+</pack>

+ 38 - 0
res/drivers/falcon.xml View File

@@ -0,0 +1,38 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+
3
+<pack>    
4
+	<driver name="falcon" extends="basic_ship">   
5
+	    
6
+	    <check for="in_zone" id="ck1" after="can_fire">
7
+			<fn str="IS_IN_RECT" />
8
+			<x range="-20:20" />
9
+			<z range="-5:45" />
10
+		</check>	
11
+		
12
+		<task replace="fire" if="can_fire&amp;in_zone">
13
+			<fn str="SHOOT" />
14
+			<count range="6:15" />
15
+			<gap_shot num="0.07" />
16
+			<gap_group range="2:4" />
17
+			<gun num="0" />
18
+		</task>
19
+		
20
+		<task replace="fly">
21
+			<fn str="FLY_TO_RECT" />
22
+			<x range="-10-10" />
23
+			<z range="25:40" />	
24
+			<weight num="10" />
25
+		</task>
26
+		
27
+		<task replace="turn" if="!in_zone">
28
+		    <fn str="TURN_TO" />
29
+		    <dir coord="MOVE_DIR" />
30
+		</task>
31
+		
32
+		<task after="turn" if="in_zone">
33
+		    <fn str="TURN_TO" />
34
+		    <dir coord="PLAYER_DIR" />
35
+		</task>
36
+		
37
+	</driver>	
38
+</pack>

+ 19 - 0
res/drivers/fighter.xml View File

@@ -0,0 +1,19 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+
3
+<pack>    
4
+	<driver name="fighter" extends="basic_ship"> 
5
+	    
6
+	    <task replace="fly">	        
7
+			<fn str="FLY_TO_POINT" />
8
+			<target coord="PLAYER_POS" />
9
+	    </task>
10
+		
11
+		<task replace="fire">
12
+			<fn str="SHOOT" />
13
+			<count num="1" />
14
+			<gap_group num="3" />
15
+			<gun num="0" />
16
+		</task>
17
+		
18
+	</driver>	
19
+</pack>

+ 19 - 0
res/drivers/manifest.xml View File

@@ -0,0 +1,19 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+
3
+<manifest>
4
+    
5
+    <!-- This file indicates the loading order of all the sibling files. -->
6
+        
7
+    <drivers>
8
+        <file>base.xml</file>
9
+        <file>burger.xml</file>
10
+        <file>fighter.xml</file>
11
+        <file>falcon.xml</file>
12
+        <file>bird.xml</file>
13
+        <file>shark.xml</file>
14
+        <file>cube.xml</file>
15
+        <file>powerup.xml</file>
16
+        <file>mine.xml</file>
17
+    </drivers>
18
+    
19
+</manifest>

+ 15 - 0
res/drivers/mine.xml View File

@@ -0,0 +1,15 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+
3
+<pack>
4
+    
5
+	<driver name="mine">
6
+		
7
+	    <task>
8
+	        <fn str="ROTATE" />
9
+	        <add num="3" />
10
+	        <random_dir bool="true" />
11
+	    </task>
12
+	    
13
+	</driver>
14
+	
15
+</pack>

+ 78 - 0
res/drivers/powerup.xml View File

@@ -0,0 +1,78 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+
3
+<pack>
4
+    
5
+	<driver name="powerup_shield">	
6
+	    
7
+	    <check for="fly">
8
+	        <fn str="IS_IN_RECT" />
9
+	        <x range="-30;30" />
10
+	        <z range="0;100" />
11
+	    </check>
12
+		
13
+	    <task>
14
+	        <fn str="ROTATE" />
15
+	        <add num="3" />
16
+	        <random_dir bool="true" />
17
+	    </task>
18
+	    
19
+	    <task if="fly">
20
+	        <fn str="FLY_TO_RECT" />	        
21
+	        <x range="-2;2" />
22
+	        <z range="3;6" />
23
+	        <weight num="0.5" />
24
+	    </task>
25
+	    
26
+	    <task>
27
+	        <fn str="MAGNET" />
28
+	        <range num="5" />
29
+	        <weight num="0.3" />
30
+	        <target str="PLAYER" />
31
+	    </task>
32
+	    
33
+		<task>
34
+	        <fn str="AVOID" />	                
35
+	        <range num="3" />  
36
+	        <weight num="0.2" />
37
+			<avoid str="NATURAL,ENEMY,MINE" />
38
+	    </task>
39
+	    
40
+	</driver>
41
+	
42
+	<driver name="powerup_artifact">	
43
+	    
44
+	    <check for="fly">
45
+	        <fn str="IS_IN_RECT" />
46
+	        <x range="-30;30" />
47
+	        <z range="0;100" />
48
+	    </check>
49
+		
50
+	    <task>
51
+	        <fn str="ROTATE" />
52
+	        <add num="2.5" />
53
+	        <random_dir bool="true" />
54
+	    </task>
55
+	    
56
+	    <task if="fly">
57
+	        <fn str="FLY_TO_RECT" />	        
58
+	        <x range="-2;2" />
59
+	        <z range="3;8" />
60
+	        <weight num="0.5" />
61
+	    </task>
62
+	    
63
+	    <task>
64
+	        <fn str="MAGNET" />
65
+	        <range num="20" />
66
+	        <weight num="0.6" />
67
+	        <target str="PLAYER" />
68
+	    </task>
69
+	    
70
+		<task>
71
+	        <fn str="AVOID" />	                
72
+	        <range num="3" />  
73
+	        <weight num="0.2" />
74
+			<avoid str="NATURAL,ENEMY,MINE" />
75
+	    </task>
76
+	    
77
+	</driver>
78
+</pack>

+ 61 - 0
res/drivers/shark.xml View File

@@ -0,0 +1,61 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+
3
+<pack>    
4
+	<driver name="shark" extends="basic_ship">   
5
+	    
6
+	    <check for="in_zone1" id="ck1" after="can_fire">
7
+			<fn str="IS_IN_RECT" />
8
+			<x range="-20:20" />
9
+			<z range="-5:60" />
10
+		</check>	
11
+		
12
+	    <check for="in_zone2" id="ck2" after="ck1">
13
+			<fn str="IS_IN_RECT" />
14
+			<x range="-20:20" />
15
+			<z range="-5:80" />
16
+		</check>	
17
+		
18
+		<task replace="fire" if="can_fire*in_zone1">
19
+			<fn str="SHOOT" />
20
+			<count range="4:8" />			
21
+			<bullets range="3:5" />
22
+			<gap_group num="1.5" />
23
+			<gap_shot num="0.02" />
24
+			<gun num="0" /> <!--range="0-1" -->
25
+		</task>
26
+		
27
+		<task replace="avoid">
28
+			<fn str="AVOID" />
29
+			<avoid str="NATURAL,SHOT_GOOD,SHOT_BAD,ENEMY,MINE" />
30
+			<weight num="1.7" />
31
+		</task>
32
+		
33
+		<task replace="fly">
34
+			<fn str="FLY_TO_RECT" />
35
+			<x range="-5-5" />
36
+			<z range="18:34" />
37
+			<weight num="30" />
38
+		</task>
39
+		
40
+		<task replace="turn" if="!in_zone1">
41
+		    <fn str="TURN_TO" />
42
+		    <dir coord="MOVE_DIR" />
43
+		</task>
44
+		
45
+		<task id="t1" after="turn" if="in_zone1">
46
+		    <fn str="TURN_TO" />
47
+		    <dir coord="PLAYER_DIR" />
48
+		</task>
49
+		
50
+<!-- 		<TASK AFTER="T1" ID="T2" IF="IN_ZONE"> -->
51
+<!-- 		    <FN STR="SET_SPEED"/> -->
52
+<!-- 		    <SPEED NUM="0.5"/> -->
53
+<!-- 		</TASK> -->
54
+		
55
+<!-- 		<task after="t2" if="!in_zone"> -->
56
+<!-- 		    <fn str="SET_SPEED"/> -->
57
+<!-- 		    <speed num="1"/> -->
58
+<!-- 		</task> -->
59
+		
60
+	</driver>	
61
+</pack>

BIN
res/fonts/atomic_clock_radio.ttf View File


BIN
res/fonts/digital_dream/bold.ttf View File


BIN
res/fonts/digital_dream/bold_italic.ttf View File


BIN
res/fonts/digital_dream/italic.ttf View File


BIN
res/fonts/digital_dream/narrow.ttf View File


BIN
res/fonts/digital_dream/narrow_bold.ttf View File


BIN
res/fonts/digital_dream/narrow_italic.ttf View File


BIN
res/fonts/digital_dream/narrow_italic_bold.ttf View File


BIN
res/fonts/digital_dream/normal.ttf View File


BIN
res/fonts/lcd_a/mono/bold.ttf View File


BIN
res/fonts/lcd_a/mono/heavy.ttf View File


BIN
res/fonts/lcd_a/mono/light.ttf View File


BIN
res/fonts/lcd_a/mono/normal.ttf View File


BIN
res/fonts/lcd_a/prop/bold.ttf View File


BIN
res/fonts/lcd_a/prop/heavy.ttf View File


BIN
res/fonts/lcd_a/prop/light.ttf View File


BIN
res/fonts/lcd_a/prop/normal.ttf View File


BIN
res/fonts/lcd_b/bold.ttf View File


BIN
res/fonts/lcd_b/boldi.ttf View File


BIN
res/fonts/lcd_b/italic.ttf View File


BIN
res/fonts/lcd_b/normal.ttf View File


BIN
res/fonts/simple/narrow.ttf View File


BIN
res/fonts/simple/normal.ttf View File


BIN
res/fonts/simple/outline.ttf View File


BIN
res/fonts/simple/wide.ttf View File


BIN
res/fonts/spaceage.ttf View File


BIN
res/images/designer_icons.png View File


BIN
res/images/particles_blend.png View File


BIN
res/images/particles_plain.png View File


BIN
res/images/shield.png View File


+ 108 - 0
res/levels/designer.xml View File

@@ -0,0 +1,108 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<level>
3
+
4
+	<info>
5
+		<title>Ship Building Site</title>
6
+		<subtitle>Infinite money!</subtitle>
7
+		<author>MightyPork</author>
8
+		<minv>15</minv>
9
+	</info>
10
+
11
+
12
+
13
+	<config>
14
+		<building>FREE</building>
15
+		<timer>30</timer>
16
+	</config>
17
+
18
+	
19
+	<discoveries>
20
+		<all level="max" />
21
+	</discoveries>
22
+
23
+
24
+	<sequence>
25
+		
26
+		<rockshift coord="0;-1" />
27
+	
28
+		<rockgen id="rocks1" >
29
+			<type num="0" />
30
+			<size range="2-8" />
31
+			<speed num="1" />
32
+			<rarity num="40" />
33
+			<x range="-30:-18" />
34
+			<z range="100-120" />
35
+		</rockgen>
36
+	
37
+		<rockgen id="rocks2" >
38
+			<type num="1" />
39
+			<size range="2-8" />
40
+			<speed num="1" />
41
+			<rarity num="30" />
42
+			<x range="-18:-6" />
43
+			<z range="100-120" />
44
+		</rockgen>
45
+	
46
+		<rockgen id="rocks3" >
47
+			<type num="2" />
48
+			<size range="2-8" />
49
+			<speed num="1" />
50
+			<rarity num="30" />
51
+			<x range="-6:6" />
52
+			<z range="100-120" />
53
+		</rockgen>
54
+	
55
+		<rockgen id="rocks4" >
56
+			<type num="3" />
57
+			<size range="2-8" />
58
+			<speed num="1" />
59
+			<rarity num="30" />
60
+			<x range="6:18" />
61
+			<z range="100-120" />
62
+		</rockgen>
63
+	
64
+		<rockgen id="rocks5" >
65
+			<type num="4" />
66
+			<size range="2-8" />
67
+			<speed num="1" />
68
+			<rarity num="40" />
69
+			<x range="18:30" />
70
+			<z range="100-120" />
71
+		</rockgen>
72
+		
73
+		
74
+		
75
+		<shipgen id="mines" >
76
+			<entity str="mine" />
77
+			<rarity num="50" />
78
+			<x range="-10-10" />
79
+			<z range="100-120" />