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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (hide 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 sysadm 1.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