-
Notifications
You must be signed in to change notification settings - Fork 0
/
getRecInfo.php
222 lines (191 loc) · 6.2 KB
/
getRecInfo.php
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
<?php
/* Some necessary stuff from vk's mapmaker script*/
list ($endiantest) = array_values (unpack ('L1L', pack ('V',1)));
if ($endiantest != 1) define ('BIG_ENDIAN_MACHINE',1);
if (defined ('BIG_ENDIAN_MACHINE')) $unpack_workaround = 'big_endian_unpack';
else $unpack_workaround = 'unpack';
/* Function from vk's mapmaker script that recieves info about polys and objects from level */
function getLevData($file)
{
global $unpack_workaround;
$f = fopen($file, "rb") or die("Couldn't open $file");
fread($f, 130);
$numpolys = floatval( implode("", unpack("d", fread($f, 8))) ) - 0.4643643;
for($i=0; $i < $numpolys; $i++)
{
$grass = implode("", unpack("L", fread($f, 4)));
$vertices = implode("", unpack("L", fread($f, 4)));
if (!$grass)
{
for($j=0; $j< $vertices; $j++)
{
$x = implode("", $unpack_workaround("d", fread($f, 8)));
$y = implode("", $unpack_workaround("d", fread($f, 8)));
$polys[$i][$j] = array($x, $y);
}
}
else
fread($f, 16*$vertices);
}
$numobjects = floatval( implode("", unpack("d", fread($f, 8))) ) - 0.4643643;
for($i=0; $i < $numobjects; $i++)
{
$x = implode( "", $unpack_workaround("d", fread($f, 8)) );
$y = implode( "", $unpack_workaround("d", fread($f, 8)) );
$a = implode( "", unpack("l", fread($f, 4)) );
$b = implode( "", unpack("l", fread($f, 4)) );
$c = implode( "", unpack("l", fread($f, 4)) );
$objects[$i] = array($x, $y, $a, $b, $c);
}
return array($polys, $objects);
}
/* Function that checks the object type from a given index found in replay file (not used) */
function getObjectType($filename, $object){
list($polys, $objects) = getLevData($filename);
$type = $objects[$object]['2'];
return "$type";
}
/* Function that counts number of apples in a level */
function applesInLev($filename){
list($polys, $objects) = getLevData($filename);
$apples = 0;
foreach($objects as $o){
$type = $o['2'];
if($type == 2){
$apples++;
}
}
return $apples;
}
/* Function that counts number of killers in a level */
function killersInLev($filename){
list($polys, $objects) = getLevData($filename);
$killers = 0;
foreach($objects as $o){
$type = $o['2'];
if($type == 3){
$killers++;
}
}
return $killers;
}
/* *** getRecInfo(); *********************** *** ** *
* Authors: milagros, skint0r and Viper_KillerGuy
* Date: 2005-11-01
* Updated: 2010-07-14 by Kopaka
*********** *** ** *
A function to return time, level name or CRC from a .rec file.
$filename is obviously the file you should pass as a parameter.
$tlc specifies wether you want the time, the level name or the crc from
the replay, use the values "t", "l" or "c" respectively.
The function shows the time by default, so you don't *really*
need to pass the $tlc parameter unless you want the level name.
Ex: to get the level name from a replay: getRecInfo("01mopo.rec", l);
Update includes extra security, checking if last object is indeed flower
and if all apples have been taken. It also includes counting apples and
returning number of apples if replay is not finished and "a" parameter is given.
Also gives possibility to get time if not finished with "n" parameter.
This update requires the 3 functions getLevData, applesInLev and killersInLev */
function getRecInfo($filename, $tlc='t', $fixedname=false) {
/* Specify directory with levels */
$leveldir = "levs/";
/* First of all, check if the file even exists */
if(!file_exists($filename)) {
return "The filename specified does not exist.";
}
/* $f is a file pointer to the filename */
$f = fopen($filename, "r");
/* $no is set as the number of frames in the replay */
list(, $no) = unpack("V", fread($f, 4));
/* Read 12 bytes of junk */
for($i = 0; $i < 12; $i++) {
fread($f, 1);
}
/* The next 4 bytes is the CRC checksum */
$crc = bin2hex(fread($f, 4));
/* The 12 next bytes is the name of the level file */
$lev = fread($f, 12);
/* remove some junk after filename */
list($splitlev, $splitlevext) = explode(".",$lev);
$lev = "$splitlev.lev";
$levdir = $leveldir . $lev;
if($fixedname != false){
$levdir = $leveldir . $fixedname . ".lev";
}
/* Read 27 * rec frames + 4 bytes of junk */
for($i = 0; $i < 27 * $no + 4; $i++) {
fread($f, 1);
}
/* $no is set as number of events in the replay */
list(, $no) = unpack("V", fread($f, 4));
/* For each event, read info and check if $k is 0, i.e. an object
$j is the number of the object, $d is the time of the event */
if($tlc != "c" && $tlc != "l"){
$killers = killersInLev($levdir);
$apples = applesInLev($levdir);
$lowestflower = $apples + $killers;
$apps = 0;
for($i = 0; $i < $no; $i++) {
list(, $d) = unpack("d", fread($f, 8));
list(, $j) = unpack("V", fread($f, 4));
list(, $k) = unpack("V", fread($f, 4));
if ($k == 0) {
/* If higher than apple indices its a flower */
if($j >= $lowestflower){
$time = $d;
/* Otherwise its an apple if higher than killer indices */
}elseif($j >= $killers){
$apps++;
}
}
if ($d != $time) {
$time = -1;
}
}
}
/* Close file */
fclose($f);
/* Check if all apples are taken */
if($time >= 0){
if ($apps < $apples){
$time = -1;
}
}
/* If the replay is finished, do some weird calculatinons
and set $outtime to the time in the format 0:00,00 */
if ($time >= 0) {
$i = $time * 62500 / 273;
$outtime = sprintf("%01d:%02d,%02d", $i/6000, ($i/100)%60, $i%100);
}
/* Else, $time is -1 which means the rec is not finished, and we set $outtime to null */
else {
$i = $time * 62500 / 273;
$nonfinish = sprintf("%01d:%02d,%02d", $i/6000, ($i/100)%60, $i%100);
$outtime = "";
}
/* If the user specified the l parameter, we output the level name */
if ($tlc == 'l') {
return $lev;
}
/* If not, perhaps the user want the CRC from the replay? */
elseif ($tlc == 'c') {
return $crc;
}
/* return number of apples taken in replay if not finished, or time if finished */
elseif ($tlc == 'a'){
if($time == -1){
return $apps;
}else{
return $outtime;
}
}
/* return time no matter if finished or not */
elseif ($tlc == 'n'){
return $nonfinish;
}
/* Else, the user either specified the t parameter, or none at all, so we output the time */
else {
return $outtime;
}
}
?>