/[LeafOK_CVS]/pvpgn-1.7.4/scripts/ladder.py
ViewVC logotype

Contents of /pvpgn-1.7.4/scripts/ladder.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Tue Jun 6 03:41:37 2006 UTC (19 years, 9 months ago) by sysadm
Branch: GNU, MAIN
CVS Tags: arelease, HEAD
Changes since 1.1: +0 -0 lines
Content type: text/x-python
no message

1 #!/usr/bin/env python
2 # -*- Mode: Python; tab-width: 4 -*-
3 #
4 # Copyright (C) 2001 Gianluigi Tiesi <sherpya@netfarm.it>
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by the
8 # Free Software Foundation; either version 2, or (at your option) any later
9 # version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
13 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 # for more details.
15 #
16 # Ranking patch by <JEBs@shbe.net> 20020503
17 # Small "unsigned int" fix by <JEBs@shbe.net> 20020818
18 #
19 # ==========================================================================
20 __version__ = "0.9"
21
22
23 ### Only if CGI_MODE = 1
24 CGI_MODE=0
25 FILE="/opt/bnetd/var/ladders/ladder.D2DV"
26 MAX=100
27
28 from struct import unpack,calcsize
29 from string import find,split,join
30 from os import stat
31 from sys import argv,exit,stdout
32 from getopt import getopt
33
34
35 #### Templates
36 modes = [ 'html', 'ansi', 'ascii', 'python' ]
37 templates = {}
38 for m in modes:
39 templates[m] = {}
40
41
42 ### html ###
43
44 #
45 templates['html']['header']="""<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
46 <html>
47 <head>
48 <title>D2 Closed Realm Ladder</title>
49 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
50 </head>
51 <body bgcolor="#000000" text="#ffff00">
52 <h2 style="color: lightgreen;" align="center">D2 Closed Realm Ladder</h2>
53 <table style="border: solid lightblue; border-width: 1px;" align="center" border="0" width="80%" summary="">
54 """
55
56 #
57 templates['html']['footer']=""" </table>
58 <p style="color: lightblue;" align="center">Generated by ladder.py v %s - &copy; 2001 <a style="color: lightgreen;" href="mailto:sherpya@netfarm.it">Sherpya</a></p>
59 </body>
60 </html>
61 """ % __version__
62
63 # %s for description of ladder type
64 templates['html']['summary'] = """ <tr style="color: lightblue" bgcolor="#666666"><th colspan="5">Ladder for %s</th></tr>
65 """
66
67 #
68 templates['html']['tbheader'] = """<tr style="color: lightgreen;"><th align="center">#</th><th align="left">Charname</th><th align="right">level</th><th align="center">class</th><th align="right">exp</th></tr>
69 """
70 # %s for charname
71 templates['html']['normal'] = """%s"""
72 templates['html']['hardcore'] = { 0 : """<span style="color: red;">%s</span>""",
73 1 : """<span style="color: orange;">%s</span>""" }
74
75 # %s charname - %d level - %s class - %d experience
76 templates['html']['entry'] = """<tr bgcolor="#222222"><td align="right">%d</td><td align="left">%s</td><td align="right">%d</td><td align="center">%s</td><td align="right">%d</td></tr>
77 """
78
79 #
80 templates['html']['separator'] = """<tr><td colspan="5">&nbsp;</td></tr>
81 """
82
83 #### html
84
85 #### ascii / ansi
86 line = '-' * 59 + '\n'
87 s10 = ' ' * 10
88 s14 = ' ' * 14
89 s5 = ' ' * 5
90 text = 'D2 Closed Ladder'
91 esc = '\033'
92 off = esc + '[0m'
93
94 colors = {
95 'grey': esc + '[1;30m',
96 'red': esc + '[1;31m',
97 'green': esc + '[1;32m',
98 'yellow': esc + '[1;33m',
99 'blue': esc + '[1;34m',
100 'purple': esc + '[1;35m',
101 'magenta': esc + '[1;36m',
102 'white': esc + '[1;37m',
103 'green': esc + '[1;32m'
104 }
105
106 templates['ascii']['header'] = line + (int((len(line) - len(text))/ 2)) * ' ' + text + '\n' + line
107 templates['ascii']['footer'] = 'generated by ladder.py (c) Sherpya [sherpya@netfarm.it]\n'
108 templates['ascii']['summary'] = 'Ladder for %s\n\n'
109 templates['ascii']['tbheader'] = ' # charname' + s14 + 'level' + s10 + 'class' + s10 + 'exp' + '\n\n'
110 templates['ascii']['normal'] = '%s'
111 templates['ascii']['hardcore'] = { 0 : '*%s', 1: '^%s' }
112 templates['ascii']['entry'] = '%3d %-23s %2d %16s %10d\n'
113 templates['ascii']['separator'] = line + '\n'
114
115 line = colors['blue'] + ( '-' * 59) + off + '\n'
116 templates['ansi']['header'] = line + (int((len(line) - len(text) - 10)/ 2)) * ' ' + colors['green'] + text + off + '\n' + line
117 templates['ansi']['footer'] = colors['green'] + 'generated by ' + colors['blue'] + 'ladder.py' + colors['green'] + ' (c) Sherpya [sherpya@netfarm.it]' + off + '\n'
118 templates['ansi']['summary'] = colors['white'] + 'Ladder for %s' + off + '\n\n'
119 templates['ansi']['tbheader'] = colors['green'] + ' # charname' + s14 + 'level' + s10 + 'class' + s10 + 'exp' + off + '\n\n'
120 templates['ansi']['normal'] = colors['yellow'] + '%s'
121 templates['ansi']['hardcore'] = { 0 : colors['red'] + '%s', 1: colors['grey'] + '%s' }
122 templates['ansi']['entry'] = colors['yellow'] + '%3d %-30s %2d %16s %10d' + off + '\n'
123 templates['ansi']['separator'] = line + '\n'
124
125
126 del text
127 #### ascii / ansi
128
129
130
131 ### Some struct from d2cs/d2dbs source
132 #
133 # ladder header (4 + 4 = 8):
134 # bn_int maxtype
135 # bn_int checksum
136 LD_HEAD="<2i"
137 szLD_HEAD = calcsize(LD_HEAD)
138
139 #
140 # ladder info (4 + 2 + 1 + 1 + 16 = 24):
141 # bn_int experience
142 # bn_short status
143 # bn_byte level
144 # bn_byte class;
145 # char charname[16];
146 LD_INFO="<Ihbb16s"
147 szLD_INFO = calcsize(LD_INFO)
148
149 #
150 # ladder index (4 + 4 + 4 = 12):
151 # bn_int type
152 # bn_int offset
153 # bn_int number
154 LD_INDEX="<3i"
155 szLD_INDEX = calcsize(LD_INDEX)
156
157 ## Status flags
158 S_INIT = 0x1
159 S_EXP = 0x20
160 S_HC = 0x04
161 S_DEAD = 0x08
162
163
164 classes = {
165 0x00 : ['Amazon', 'f'],
166 0x01 : ['Sorceress', 'f'],
167 0x02 : ['Necromancer', 'm'],
168 0x03 : ['Paladin', 'm'],
169 0x04 : ['Barbarian', 'm'],
170 0x05 : ['Druid', 'm'],
171 0x06 : ['Assassin', 'f']
172 }
173
174 desc = {
175 'nor': 'Diablo II',
176 'exp': 'Lord of Desctruction'
177 }
178
179
180 diff = {
181 'nor': {
182 0x1: { 0 : { 'm': 'Sir', 'f': 'Dame' },
183 1 : { 'm': 'Count', 'f': 'Countess' }
184 },
185
186 0x2: { 0 : { 'm': 'Lord', 'f': 'Lady' },
187 1 : { 'm': 'Duke', 'f': 'Duchess' }
188 },
189
190 0x3: { 0 : { 'm': 'Baron', 'f': 'Baroness' },
191 1 : { 'm': 'King', 'f': 'Queen' }
192 }
193 },
194
195 'exp': {
196 0x1: { 0 : { 'm': 'Slayer', 'f': 'Slayer' },
197 1 : { 'm': 'Destroyer', 'f': 'Destroyer' }
198 },
199
200 0x2: { 0 : { 'm': 'Champion', 'f': 'Champion' },
201 1 : { 'm': 'Conqueror', 'f': 'Conqueror' }
202 },
203
204 0x3: { 0 : { 'm': 'Patriarch', 'f': 'Matriarch' },
205 1 : { 'm': 'Guardian', 'f': 'Guardian' }
206 }
207 }
208 }
209
210 ## Utils
211
212
213 def remove_null(text):
214 return split(text, chr(0))[0]
215
216
217 def get_ladder(file):
218 try:
219 size = stat(file)[6]
220 data = open(file, "rb")
221 except:
222 print "Error opening %s for read" % file
223 exit()
224
225 maxtype, checksum = unpack(LD_HEAD, data.read(szLD_HEAD))
226
227 size = size - szLD_HEAD
228
229 head = []
230
231 for i in range(maxtype):
232 type, offset, number = unpack(LD_INDEX, data.read(szLD_INDEX))
233 size = size - szLD_INDEX
234 head.append(
235 {
236 'type': type,
237 'offset': offset,
238 'number': number
239 })
240
241
242 ladder = {}
243 ladder['nor'] = []
244 ladder['exp'] = []
245
246 temp = {}
247 temp['nor'] = []
248 temp['exp'] = []
249
250
251 while size > 0:
252 try:
253 experience, status, level, _class, charname = unpack(LD_INFO, data.read(szLD_INFO))
254 except:
255 ### Bad data
256 size = size - szLD_INFO
257 continue
258
259 size = size - szLD_INFO
260
261 ## Avoid null chars
262 if not experience:
263 continue
264
265 charname = remove_null(charname)
266 died = 0
267
268 if status & S_EXP:
269 _type = 'exp'
270 difficulty = ((status >> 0x08) & 0x0f) / 5
271 else:
272 _type = 'nor'
273 difficulty = ((status >> 0x08) & 0x0f) / 5
274
275 if status & S_HC:
276 hc = 1
277 if status & S_DEAD:
278 died = 1
279 else:
280 hc = 0
281
282 c_class = classes[_class]
283
284 if difficulty and diff[_type].has_key(difficulty):
285 prefix = diff[_type][difficulty][hc][c_class[1]]
286 else:
287 prefix = None
288
289 char = (experience, {
290 'charname' : charname,
291 'prefix' : prefix,
292 'experience' : experience,
293 'class' : c_class[0],
294 'sex' : c_class[0],
295 'level' : level,
296 'type' : _type,
297 'difficulty' : difficulty,
298 'hc' : hc,
299 'died' : died
300 })
301 ## Dupe char? why?
302 if char not in temp[_type]:
303 temp[_type].append(char)
304
305 data.close()
306
307 ## Sorting by exp
308 temp['nor'].sort()
309 temp['nor'].reverse()
310 temp['exp'].sort()
311 temp['exp'].reverse()
312
313 for _type in temp.keys():
314 for ch in temp[_type]:
315 ladder[_type].append(ch[1])
316 del temp
317
318 return ladder
319
320 def generate(ladder, mode, output, max):
321
322 output.write(templates[mode]['header'])
323
324 for _type in ladder.keys():
325 count = 1
326 output.write(templates[mode]['summary'] % desc[_type])
327 output.write(templates[mode]['tbheader'])
328
329 for ch in ladder[_type]:
330 if ch['prefix']:
331 charname = "%s %s" % (ch['prefix'], ch['charname'])
332 else:
333 charname = ch['charname']
334
335 if ch['hc']:
336 charname = templates[mode]['hardcore'][ch['died']] % charname
337 else:
338 charname = templates[mode]['normal'] % charname
339
340 output.write(templates[mode]['entry'] % (count, charname, ch['level'], ch['class'], ch['experience']))
341 count = count + 1
342 if count > max:
343 break
344
345 output.write(templates[mode]['separator'])
346
347 output.write(templates[mode]['footer'])
348
349
350 def pickle_to(ladder, output):
351 try:
352 from cPickle import dump
353 except:
354 from pickle import dump
355
356 try:
357 out = open(output, "wb")
358 except:
359 print "Cannot open %s for pickle dump" % output
360 exit()
361
362 dump(ladder, out)
363 out.close()
364
365
366 ### Main
367
368 ### CGI MODE
369 if CGI_MODE:
370 print "Content-Type: text/html"
371 print
372 ladder = get_ladder(FILE)
373 generate(ladder, 'html', stdout, MAX)
374 exit()
375
376 args = argv[1:]
377 optlist, args = getopt(args, "hi:o:m:n:")
378 if len(args):
379 for bad in args:
380 print "%s: Unrecognized option %s" % (argv[0], bad)
381 exit()
382
383 ### defaults
384 file = None
385 output = None # stdout
386 mode = modes[0]
387 real_max = 1000
388 max = 100
389
390 def show_help():
391 print
392 print "ladder.py v%s - (c) 2001 Sherpya <sherpya@netfarm.it>" % __version__
393 print "Usage: ladder.py -i ladder_file [-o outputfile] [-m mode] [-n max ladder chars]"
394 print
395 print " -i ladder_file, is the ladder file like ladder.D2DV"
396 print " -o output file, if omitted defaults to stdout"
397 print " -m mode, avaiables mode are: %s, defaults to %s" % (join(modes,', '), modes[0])
398 print " -n max_char, max char to display in each ladder, defaults to %d" % max
399 print
400 print " note: python output mode creates a python object usable by pickle module"
401 print
402
403 for opt in optlist:
404
405 # Help
406 if opt[0] == '-h':
407 show_help()
408 exit()
409
410 # Input file
411 if opt[0] == '-i':
412 file = opt[1]
413 continue
414
415 # Output file
416 if opt[0] == '-o':
417 output = opt[1]
418 continue
419
420 # Output mode (html, ansi, ascii, python)
421 if opt[0] == '-m':
422 if opt[1] in modes:
423 mode = opt[1]
424 continue
425 else:
426 print "Invalid mode %s, valid modes are %s" % (opt[1], join(modes, ', '))
427 exit()
428
429 # Max chars in ladder
430 if opt[0] == '-n':
431 try:
432 max = int(opt[1])
433 except:
434 max = 0
435
436 if (max < 2) or max > real_max:
437 print "Invalid value for max char in ladder must be > 1 and < %d" % real_max
438 exit()
439 continue
440
441 if not file:
442 show_help()
443 exit()
444
445 ladder = get_ladder(file)
446 if mode == 'python':
447 if output:
448 pickle_to(ladder, output)
449 else:
450 print "Cannot dump python object to stdout"
451 exit()
452
453 if output:
454 try:
455 output = open(output, "wb")
456 except:
457 print "Cannot open %s for writing" % output
458 exit()
459 else:
460 output = stdout
461
462 generate(ladder, mode, output, max)
463
464

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1