1 |
root |
1.1 |
#!@PERL@ |
2 |
|
|
# scores.pl |
3 |
|
|
# (c) Pertti Karppinen a.k.a roWer <pjka@iki.fi> |
4 |
|
|
# |
5 |
|
|
# thanks for Sami Ylönen a.k.a klux for some cleaning up |
6 |
|
|
# |
7 |
|
|
# This program is free software; you can redistribute it |
8 |
|
|
# and/or modify it under the terms of the GNU General Public |
9 |
|
|
# License as published by the Free Software Foundation; |
10 |
|
|
# either version 2 of the License, or (at your option) any |
11 |
|
|
# later version. |
12 |
|
|
# This program is distributed in the hope that it will be |
13 |
|
|
# useful, but WITHOUT ANY WARRANTY; without even the implied |
14 |
|
|
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
15 |
|
|
# PURPOSE. See the GNU General Public License for more |
16 |
|
|
# details. |
17 |
|
|
|
18 |
|
|
# This should get run out of cron like: |
19 |
|
|
# 0,5,10,15,20,25,30,35,40,45,50,55 * * * * $HOME/crossfire/var/www/bin/scores.pl > /dev/null 2>&1 |
20 |
|
|
# As a note, if you have a lot of players, you may want to run this less often. This |
21 |
|
|
# reads through all the player files on the server to generate this information. |
22 |
|
|
# |
23 |
|
|
|
24 |
|
|
use File::Basename; |
25 |
|
|
|
26 |
|
|
|
27 |
|
|
#the name of the server admin |
28 |
|
|
my $admin_name="Some Admin"; |
29 |
|
|
|
30 |
|
|
#the email of the server admin |
31 |
|
|
my $admin_email="Some.Admin@Some.Where"; |
32 |
|
|
|
33 |
|
|
#html output file |
34 |
|
|
my $outfile="/var/www/html/cscores.html"; |
35 |
|
|
|
36 |
|
|
#complete url to the output |
37 |
|
|
my $scoreurl="/cscores.html"; |
38 |
|
|
|
39 |
|
|
my $timezone=`date +%Z`; |
40 |
|
|
|
41 |
|
|
#Your Crossfire folder |
42 |
|
|
my $crossfire_home="@prefix@"; |
43 |
|
|
|
44 |
|
|
#background color of the webpage |
45 |
|
|
my $bgcolor="#eeeeee"; |
46 |
|
|
|
47 |
|
|
#background color of the outer table |
48 |
|
|
my $outertablebgcolor="#dddddd"; |
49 |
|
|
|
50 |
|
|
#background color of the inner table |
51 |
|
|
my $innertablebgcolor="#dddddd"; |
52 |
|
|
|
53 |
|
|
#background color for <tr> |
54 |
|
|
my $tabletrcolor="#a9b4f2"; |
55 |
|
|
|
56 |
|
|
#the title of your score webpage |
57 |
|
|
my $title="Crossfire scores"; |
58 |
|
|
|
59 |
|
|
|
60 |
|
|
#the levels =) |
61 |
|
|
# MSW Note - we should really be clever and read the exp_table |
62 |
|
|
# file to dynamically generate this. |
63 |
|
|
|
64 |
|
|
my @levels=(0,2000,4000, 8000, |
65 |
|
|
16000,32000,64000,125000,250000, |
66 |
|
|
500000,900000,1400000,2000000,2600000, |
67 |
|
|
3300000,4100000,4900000,5700000,6600000, |
68 |
|
|
7500000,8400000,9300000,10300000,11300000, |
69 |
|
|
12300000,13300000,14400000,15500000,16600000, |
70 |
|
|
17700000,18800000,19900000,21100000,22300000, |
71 |
|
|
23500000,24700000,25900000,27100000,28300000, |
72 |
|
|
29500000,30800000,32100000,33400000,34700000, |
73 |
|
|
36000000,37300000,38600000,39900000,41200000, |
74 |
|
|
42600000,44000000,45400000,46800000,48200000, |
75 |
|
|
49600000,51000000,52400000,53800000,55200000, |
76 |
|
|
56600000,58000000,59400000,60800000,62200000, |
77 |
|
|
63700000,65200000,66700000,68200000,69700000, |
78 |
|
|
71200000,72700000,74200000,75700000,77200000, |
79 |
|
|
78700000,80200000,81700000,83200000,84700000, |
80 |
|
|
86200000,87700000,89300000,90900000,92500000, |
81 |
|
|
94100000,95700000,97300000,98900000,100500000, |
82 |
|
|
102100000,103700000,105300000,106900000,108500000, |
83 |
|
|
110100000,111700000,113300000,114900000,116500000, |
84 |
|
|
118100000,119700000,121300000,122900000,124500000, |
85 |
|
|
126100000,127700000,129300000,130900000,785400000, |
86 |
|
|
1570800000); |
87 |
|
|
|
88 |
|
|
|
89 |
|
|
my $DEBUG=0; |
90 |
|
|
|
91 |
|
|
#prototypes |
92 |
|
|
sub parse_file($); |
93 |
|
|
sub html_print_player($@); |
94 |
|
|
sub html_print_table_header(); |
95 |
|
|
sub html_print_header(); |
96 |
|
|
sub html_print_footer(); |
97 |
|
|
sub read_dms(); |
98 |
|
|
|
99 |
|
|
my @files= glob("$crossfire_home/var/crossfire/players/*/*.pl"); |
100 |
|
|
foreach(sort @files) { |
101 |
|
|
print "$_\n" if $DEBUG; |
102 |
|
|
parse_file($_); |
103 |
|
|
} |
104 |
|
|
for($i=0;$i<$#scores+1;$i++) { |
105 |
|
|
my $exp=$scores[$i][6]; |
106 |
|
|
my $name=$scores[$i][0]; |
107 |
|
|
$score_hash{$name}=$exp; |
108 |
|
|
$ranking{$name}=$i; |
109 |
|
|
} |
110 |
|
|
my %dms; |
111 |
|
|
read_dms(); |
112 |
|
|
|
113 |
|
|
my $rank=1; |
114 |
|
|
$saved_exp=-1; |
115 |
|
|
$saved_rank=-1; |
116 |
|
|
open(OUT,">$outfile") or die("Couldn't open outputfile $outfile: $!\n"); |
117 |
|
|
my $ofh=select(OUT); |
118 |
|
|
$|=1; |
119 |
|
|
html_print_header(); |
120 |
|
|
html_print_table_header(); |
121 |
|
|
foreach(sort {$score_hash{$b} <=> $score_hash{$a}} keys %ranking) { |
122 |
|
|
my $i=$ranking{$_}; |
123 |
|
|
my @tmp; |
124 |
|
|
print "$scores[$i][0]\t$scores[$i][6]\n" if $DEBUG; |
125 |
|
|
for($j=0;$j<12;$j++) { |
126 |
|
|
$tmp[$j]=$scores[$i][$j]; |
127 |
|
|
} |
128 |
|
|
html_print_player($rank++,@tmp); |
129 |
|
|
} |
130 |
|
|
print "</table>\n"; |
131 |
|
|
html_print_footer(); |
132 |
|
|
close(OUT); |
133 |
|
|
select($ofh); |
134 |
|
|
exit 0; |
135 |
|
|
|
136 |
|
|
sub parse_file($) { |
137 |
|
|
my $player_file=shift; |
138 |
|
|
my($name,$title,$race,$class,$killer,$exp,$map,$maxhp,$maxsp,$maxgrace,$level,$god); |
139 |
|
|
my $state=0; |
140 |
|
|
my $count=0; |
141 |
|
|
my $no_class=0; |
142 |
|
|
$killer="left"; |
143 |
|
|
$god=" "; |
144 |
|
|
open(PLAYER_FILE,"$player_file") or die("autch $!"); |
145 |
|
|
while(<PLAYER_FILE>) { |
146 |
|
|
if(/no_class_face_change/) { |
147 |
|
|
$no_class=1; |
148 |
|
|
} |
149 |
|
|
if($state==0) { |
150 |
|
|
if(/^title/) { |
151 |
|
|
/^title\s*(.*)$/; |
152 |
|
|
$title=$1; |
153 |
|
|
$count++; |
154 |
|
|
next; |
155 |
|
|
} elsif(/^map/) { |
156 |
|
|
chomp; |
157 |
|
|
$map=basename($_); |
158 |
|
|
$count++; |
159 |
|
|
next; |
160 |
|
|
} |
161 |
|
|
$state=2 if($count==2); |
162 |
|
|
$state=2 if(/^arch.*_player/ || /^arch.*pl_.*/); |
163 |
|
|
next unless($state==2); |
164 |
|
|
} |
165 |
|
|
if($state==2||$state==3) { |
166 |
|
|
next unless($state==3||/^arch.*_player/ || /^arch.*pl_.*/); |
167 |
|
|
next if(/^name_pl/); |
168 |
|
|
if($state==2&&/^arch.*_player/) { |
169 |
|
|
/^arch\s*(.*?)_player/; |
170 |
|
|
$race=$1; |
171 |
|
|
$count++; |
172 |
|
|
$state=3; |
173 |
|
|
next; |
174 |
|
|
} |
175 |
|
|
if($state==2&&/^arch.*pl_.*/) { |
176 |
|
|
/^arch.*pl_(\S*)/; |
177 |
|
|
$race=$1; |
178 |
|
|
$race =~ s/_/ /g; |
179 |
|
|
$count++; |
180 |
|
|
$state=3; |
181 |
|
|
next; |
182 |
|
|
} |
183 |
|
|
if(/^title/) { |
184 |
|
|
/^title\s*(.*)$/; |
185 |
|
|
$title=$1; |
186 |
|
|
$count++; |
187 |
|
|
next; |
188 |
|
|
} |
189 |
|
|
if(/^name/) { |
190 |
|
|
/^name\s*(.*)$/; |
191 |
|
|
$name=$1; |
192 |
|
|
$count++; |
193 |
|
|
next; |
194 |
|
|
} |
195 |
|
|
if(/^face/) { |
196 |
|
|
/^face\s*([^_]*).*\.\d+/; |
197 |
|
|
$class=$1; |
198 |
|
|
$count++; |
199 |
|
|
next; |
200 |
|
|
} |
201 |
|
|
if(/^maxhp/) { |
202 |
|
|
/^maxhp\s*(\d*)/; |
203 |
|
|
$maxhp=$1; |
204 |
|
|
$count++; |
205 |
|
|
next; |
206 |
|
|
} |
207 |
|
|
if(/^maxsp/) { |
208 |
|
|
/^maxsp\s*(\d*)/; |
209 |
|
|
$maxsp=$1; |
210 |
|
|
$count++; |
211 |
|
|
next; |
212 |
|
|
} |
213 |
|
|
if(/^maxgrace/) { |
214 |
|
|
/^maxgrace\s*(\d*)/; |
215 |
|
|
$maxgrace=$1; |
216 |
|
|
$count++; |
217 |
|
|
next; |
218 |
|
|
} |
219 |
|
|
if(/^exp/) { |
220 |
|
|
/^exp\s*(\d*)/; |
221 |
|
|
$exp=$1; |
222 |
|
|
$count++; |
223 |
|
|
next; |
224 |
|
|
} |
225 |
|
|
if(/^level/) { |
226 |
|
|
/^level\s*(\d*)/; |
227 |
|
|
$level=$1; |
228 |
|
|
$count++; |
229 |
|
|
next; |
230 |
|
|
} |
231 |
|
|
# $state=4 if($count==8); |
232 |
|
|
$state=4 if(/^arch/ || /^end/); |
233 |
|
|
next; |
234 |
|
|
} elsif($state==4) { |
235 |
|
|
next unless(/^arch skill_praying/); |
236 |
|
|
$state=5; |
237 |
|
|
next; |
238 |
|
|
} elsif($state==5) { |
239 |
|
|
$state=6 if(/^end/); |
240 |
|
|
next unless(/^title/); |
241 |
|
|
/^title\s*(.*)/; |
242 |
|
|
$god=$1; |
243 |
|
|
$state=6; |
244 |
|
|
} |
245 |
|
|
} |
246 |
|
|
close(PLAYER_FILE); |
247 |
|
|
$class=$race if($no_class); |
248 |
|
|
$title=$class unless defined $title; |
249 |
|
|
if(!defined $level) { |
250 |
|
|
for($level=0;$level<$#levels;$level++) { |
251 |
|
|
last if($exp<$levels[$level]); |
252 |
|
|
} |
253 |
|
|
} |
254 |
|
|
if(defined $exp) { |
255 |
|
|
my @tmp= ($name, $title ,$race,$class,$killer,$map,$exp,$level,$maxhp,$maxsp,$maxgrace,$god); |
256 |
|
|
push(@scores,\@tmp); |
257 |
|
|
print STDERR "$name the $title ($race $class) $killer the game on map $map with $exp points (level $level)" if $DEBUG; |
258 |
|
|
print STDERR " and maxhp of $maxhp, maxsp of $maxsp and maxgrace" if $DEBUG; |
259 |
|
|
print STDERR " (from $god)" if (defined $god && $DEBUG); |
260 |
|
|
print STDERR " of $maxgrace.\n" if $DEBUG; |
261 |
|
|
} |
262 |
|
|
|
263 |
|
|
} |
264 |
|
|
|
265 |
|
|
sub html_print_player($@) { |
266 |
|
|
my($rank,@table)=@_; |
267 |
|
|
my $name = $table[0]; |
268 |
|
|
my $title = $table[1]; |
269 |
|
|
my $race = $table[2]; |
270 |
|
|
my $class = $table[3]; |
271 |
|
|
my $killer = $table[4]; |
272 |
|
|
my $map = $table[5]; |
273 |
|
|
my $exp = $table[6]; |
274 |
|
|
my $level = $table[7]; |
275 |
|
|
my $maxhp = $table[8]; |
276 |
|
|
my $maxsp = $table[9]; |
277 |
|
|
my $maxgrace = $table[10]; |
278 |
|
|
my $god = $table[11]; |
279 |
|
|
print "<tr bgcolor=\"$tabletrcolor\">\n"; |
280 |
|
|
if ($saved_exp!=$exp) { |
281 |
|
|
$saved_exp=$exp; |
282 |
|
|
$saved_rank=$rank; |
283 |
|
|
} |
284 |
|
|
if ($saved_rank<11) { |
285 |
|
|
print " <td align=right><b>$saved_rank.</b></td>\n"; |
286 |
|
|
} else { |
287 |
|
|
print " <td align=right>$saved_rank.</td>\n"; |
288 |
|
|
} |
289 |
|
|
if ($dms{$name}) { |
290 |
|
|
print " <td>$name the $title <font color=red size=-3>DM</font></td>\n"; |
291 |
|
|
} else { |
292 |
|
|
print " <td>$name the $title</td>\n"; |
293 |
|
|
} |
294 |
|
|
print " <td>$race</td>\n"; |
295 |
|
|
print " <td align=right>$exp</td>\n" unless($exp>=785400000); |
296 |
|
|
print " <td align=right><font color=red>$exp</font></td>\n" if($exp>=785400000); |
297 |
|
|
print " <td align=right>$level</td>\n"; |
298 |
|
|
print " <td align=right>$maxhp</td>\n"; |
299 |
|
|
print " <td align=right>$maxsp</td>\n"; |
300 |
|
|
print " <td align=right>$maxgrace</td>\n"; |
301 |
|
|
print " <td>$god</td>\n"; |
302 |
|
|
print " <td>$map</td>\n"; |
303 |
|
|
print "</tr>\n"; |
304 |
|
|
} |
305 |
|
|
|
306 |
|
|
sub html_print_table_header() { |
307 |
|
|
print "<table border=0 cellpadding=2 cellspacing=1 class=\"inner_table\">\n"; |
308 |
|
|
print "<tr bgcolor=\"$tabletrcolor\">\n"; |
309 |
|
|
print " <td align=\"center\">Rank</td>\n"; |
310 |
|
|
print " <td align=\"center\">Character</td>\n"; |
311 |
|
|
print " <td align=\"center\">Race</td>\n"; |
312 |
|
|
print " <td align=\"center\">Score</td>\n"; |
313 |
|
|
print " <td align=\"center\">Level</td>\n"; |
314 |
|
|
print " <td align=\"center\">MaxHP</td>\n"; |
315 |
|
|
print " <td align=\"center\">MaxSP</td>\n"; |
316 |
|
|
print " <td align=\"center\">MaxGP</td>\n"; |
317 |
|
|
print " <td align=\"center\">God</td>\n"; |
318 |
|
|
print " <td align=\"center\">Location</td>\n"; |
319 |
|
|
print "</tr>\n"; |
320 |
|
|
} |
321 |
|
|
sub html_print_header() { |
322 |
|
|
print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"; |
323 |
|
|
print "<html><head><title>$title</title>\n"; |
324 |
|
|
print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\n"; |
325 |
|
|
print "<meta http-equiv=\"refresh\" content=\"300; url=$scoreurl\">\n"; |
326 |
|
|
print << "EOF"; |
327 |
|
|
|
328 |
|
|
<STYLE TYPE="text/css"> |
329 |
|
|
<!-- |
330 |
|
|
.outer_table { |
331 |
|
|
background-color: $outertablebgcolor; |
332 |
|
|
border: 1px #4350b0 solid; |
333 |
|
|
} |
334 |
|
|
.inner_table { |
335 |
|
|
background-color: $innertablebgcolor; |
336 |
|
|
border: 2px #4350b0 solid; |
337 |
|
|
} |
338 |
|
|
--> |
339 |
|
|
</STYLE> |
340 |
|
|
|
341 |
|
|
EOF |
342 |
|
|
|
343 |
|
|
print "</head>\n"; |
344 |
|
|
print "<body bgcolor=\"$bgcolor\"><center>\n"; |
345 |
|
|
print "<table border=0 class=\"outer_table\" align=\"center\"><tr><td align=\"center\">\n"; |
346 |
|
|
print "<h1>$title</h1>\n"; |
347 |
|
|
} |
348 |
|
|
sub html_print_footer() |
349 |
|
|
{ |
350 |
|
|
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = |
351 |
|
|
localtime(time); |
352 |
|
|
$year+=1900; |
353 |
|
|
my @months=("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"); |
354 |
|
|
my @days=("Sun","Mon","Tue","Wed","Thu","Fri","Sat"); |
355 |
|
|
print "<a href=\"/\">Back</a>\n</center>\n"; |
356 |
|
|
print "<hr>\n<address><a href=\"mailto:$admin_email\">$admin_name</a></address>\n"; |
357 |
|
|
printf ("Last modified: $days[$wday] $months[$mon] $mday %2.2d:%2.2d:%2.2d $timezone $year\n",$hour,$min,$sec); |
358 |
|
|
print "</td></tr></table>\n"; |
359 |
|
|
print "</body></html>\n"; |
360 |
|
|
} |
361 |
|
|
|
362 |
|
|
sub read_dms() |
363 |
|
|
{ |
364 |
|
|
open(DMLIST, "$crossfire_home/etc/crossfire/dm_file"); |
365 |
|
|
while(<DMLIST>) { |
366 |
|
|
next if(/^\s*#/); |
367 |
|
|
chomp; |
368 |
|
|
/\s*([^\s:]+):/; |
369 |
|
|
$dms{$1}=1; |
370 |
|
|
} |
371 |
|
|
close(DMLIST); |
372 |
|
|
} |