ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/kgsueme/doc/doc2messages_pm.xsl
Revision: 1.12
Committed: Mon Jun 7 13:37:07 2004 UTC (19 years, 11 months ago) by root
Content type: application/xml
Branch: MAIN
Changes since 1.11: +14 -9 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 <!DOCTYPE xsl:stylesheet>
2     <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
3    
4     <xsl:output method="text" media-type="text/plain" encoding="utf-8"/>
5    
6     <xsl:template match="/"><![CDATA[
7     # This is an automatically generated file.
8     # This is an automatically generated file.
9     # This is an automatically generated file.
10     # This is an automatically generated file.
11     # This is an automatically generated file.
12    
13     # See doc/protocol.xml and doc/doc2messages_pm.xsl (and doc/Makefile)
14    
15     package KGS::Messages;
16    
17     use strict;
18    
19     our %type;
20    
21     our %dec_client; # decode messages send to server
22     our %enc_client; # encode messages send to server
23     our %dec_server; # decode messages received from server
24     our %enc_server; # encode messages received from server
25    
26     {
27    
28 root 1.12 use Gtk2::GoBoard::Constants; # for MARK_xyz
29     use Math::BigInt ();
30    
31 pcg 1.1 my $data; # stores currently processed decoding/encoding packet
32    
33 pcg 1.7 sub _set_data($) { $data = shift } # for debugging or special apps only
34 root 1.12 sub _get_data() { $data } # for debugging or special apps only
35 pcg 1.7
36 pcg 1.1 # primitive enc/decoders
37    
38     #############################################################################
39    
40     sub dec_U8 {
41     (my ($r), $data) = unpack "C a*", $data; $r;
42     }
43    
44     sub dec_U16 {
45     (my ($r), $data) = unpack "v a*", $data; $r;
46     }
47    
48     sub dec_U32 {
49     (my ($r), $data) = unpack "V a*", $data; $r;
50     }
51    
52     sub dec_U64 {
53 root 1.12 # do NOT use Math::BigInt here.
54 pcg 1.1 my ($lo, $hi) = (dec_U32, dec_U32);
55 root 1.12 $hi * 2**32 + $lo;
56 pcg 1.1 }
57    
58     sub dec_I8 {
59     (my ($r), $data) = unpack "c a*", $data;
60     $r;
61     }
62    
63     sub dec_I16 {
64     (my ($r), $data) = unpack "v a*", $data;
65     unpack "s", pack "S", $r;
66     }
67    
68     sub dec_I32 {
69     (my ($r), $data) = unpack "V a*", $data;
70     unpack "i", pack "I", $r;
71     }
72    
73     sub dec_DATA {
74     (my ($r), $data) = ($data, ""); $r;
75     }
76    
77 pcg 1.6 sub dec_ZSTRING {
78 pcg 1.1 $data =~ s/^((?:..)*?)(?:\x00\x00|\Z)//s;
79     # use Encode...
80     join "", map chr, unpack "v*", $1;
81     }
82    
83 pcg 1.6 BEGIN { *dec_STRING = \&dec_ZSTRING };
84    
85 pcg 1.1 sub dec_CONSTANT {
86     $_[0];
87     }
88    
89     sub dec_password {
90     dec_U64;
91     }
92    
93     sub dec_HEX { # for debugging
94     "HEX: " . unpack "H*", $data;#d#
95     }
96    
97     #############################################################################
98    
99     sub enc_U8 {
100     $data .= pack "C", $_[0];
101     }
102    
103     sub enc_U16 {
104     $data .= pack "v", $_[0];
105     }
106    
107     sub enc_U32 {
108     $data .= pack "V", $_[0];
109     }
110    
111     sub enc_U64 {
112 root 1.12 my $i = new Math::BigInt $_[0];
113    
114     enc_U32 $i & 0xffffffff;
115     enc_U32 $i >> 32;
116 pcg 1.1 }
117    
118     sub enc_I8 {
119     $data .= pack "c", $_[0];
120     }
121    
122     sub enc_I16 {
123     enc_U16 unpack "S", pack "s", $_[0];
124     }
125    
126     sub enc_I32 {
127     enc_U32 unpack "I", pack "i", $_[0];
128     }
129    
130     sub enc_DATA {
131     # a dream!
132     $data .= $_[0];
133     }
134    
135 pcg 1.6 sub enc_ZSTRING {
136     # should use encode for speed and clarity ;)
137     $data .= pack "v*", (map ord, split //, $_[0]), 0;
138     }
139    
140 pcg 1.1 sub enc_STRING {
141     # should use encode for speed and clarity ;)
142     $data .= pack "v*", map ord, split //, $_[0];
143     }
144    
145     sub enc_CONSTANT {
146     # nop
147     }
148    
149     sub enc_password {
150     # $hash must be 64 bit
151     my $hash = new Math::BigInt;
152     $hash = $hash * 1055 + ord for split //, $_[0];
153 root 1.12 enc_U64 $hash & new Math::BigInt "0xffffffffffffffff";
154 pcg 1.1 }
155    
156     sub enc_HEX {
157     die "enc_HEX not defined for good";
158     }
159    
160     ]]>
161    
162     #############################################################################
163     # types
164     <xsl:apply-templates select="descendant::type"/>
165    
166     #############################################################################
167     # structures
168     <xsl:apply-templates select="descendant::struct"/>
169    
170     #############################################################################
171     # "less" primitive types<![CDATA[
172    
173     # this was the most horrible thing to decode. still not everything is decoded correctly(?)
174     sub dec_TREE {
175     my @r;
176 pcg 1.8 my $old_data = $data;#d#
177 pcg 1.1 while (length $data) {
178     my $type = dec_U8;
179     my $add = $type < 128;
180    
181 pcg 1.8 my $ofs = (length $old_data) - (length $data);#d#
182    
183 pcg 1.1 $type &= 127;
184    
185     if ($type == 127) {
186     dec_U8; # unused?? *sigh*
187     push @r, [add_node => dec_I32];
188    
189     } elsif ($type == 126) {
190     push @r, [set_node => dec_I32];
191    
192     } elsif ($type == 125) {
193     push @r, [set_current => dec_I32];
194    
195     } elsif ($type == 34) {
196 root 1.12 push @r, [score => dec_U8, dec_score32_1000];
197 pcg 1.1
198     } elsif ($type == 29) {
199 pcg 1.6 push @r, [type_29 => dec_ZSTRING];
200 pcg 1.7 warn "UNKNOWN TREE TYPE 29 $r[-1][1]\007 PLEASE REPORT";#d#
201 pcg 1.1 die;
202    
203     } elsif ($type == 28) {
204     # move number, only in variations it seems. oh my.
205 pcg 1.6 push @r, [movenum => dec_ZSTRING];
206 pcg 1.1
207 pcg 1.7 } elsif ($type == 26) {
208     push @r, [type_26 => dec_U8]; # sets a flag (?)
209 pcg 1.11 warn "unknown tree node 26, please ignore\n";
210     # possibly marks moves done while editing, as opposed to game-moves(?)
211 pcg 1.7
212 pcg 1.1 } elsif ($type == 25) {
213     push @r, [result => dec_result];
214    
215     } elsif ($type == 23) {
216     push @r, [mark => $add, MARK_GRAYED, dec_U8, dec_U8];
217    
218     } elsif ($type == 22) {
219 pcg 1.6 push @r, [mark => $add, dec_U8() ? MARK_SMALL_W : MARK_SMALL_B, dec_U8, dec_U8];
220 pcg 1.1
221     } elsif ($type == 21) {
222 pcg 1.8 push @r, [mark => $add, MARK_SQUARE, dec_U8, dec_U8];
223 pcg 1.1
224     } elsif ($type == 20) {
225 pcg 1.8 push @r, [mark => $add, MARK_TRIANGLE, dec_U8, dec_U8];
226 pcg 1.1
227     } elsif ($type == 19) {
228 pcg 1.8 push @r, [mark => $add, MARK_LABEL, dec_U8, dec_U8, dec_ZSTRING];
229     #push @r, [unknown_18 => dec_U8, dec_U32, dec_U32, dec_U8, dec_U32, dec_U32, dec_U32];
230     #push @r, [set_timer => (dec_U8, dec_U32, dec_time)[0,2,1]];
231 pcg 1.1
232     } elsif ($type == 18) {
233 pcg 1.8 push @r, [set_timer => (dec_U8, dec_U32, dec_time)[0,2,1]];
234 pcg 1.1
235     } elsif ($type == 17) {
236 pcg 1.8 push @r, [set_stone => dec_U8, dec_U8, dec_U8];#d#?
237    
238     # } elsif ($type == 16) {
239     # push @r, [set_stone => dec_U8, dec_U8, dec_U8];#o#
240 pcg 1.1
241 pcg 1.8 } elsif ($type == 15) {
242     push @r, [mark => $add, MARK_CIRCLE, dec_U8, dec_U8];#d#?
243 pcg 1.1
244     } elsif ($type == 14) {
245 pcg 1.6 push @r, [move => dec_U8, dec_U8, dec_U8];
246 pcg 1.1
247     } elsif (($type >= 4 && $type <= 9)
248     || ($type >= 11 && $type <= 13)
249     || $type == 24) {
250    
251     push @r, [({
252     4 => "date",
253     5 => "unknown_comment5",
254 pcg 1.8 6 => "game_id", #?#
255 pcg 1.1 7 => "unknown_comment7",
256     8 => "unknown_comment8",
257     9 => "copyright", #?
258     11 => "unknown_comment11",
259     12 => "unknown_comment12",
260     13 => "unknown_comment13",
261     24 => "comment",
262 pcg 1.6 })->{$type} => dec_ZSTRING];
263 pcg 1.1
264     } elsif ($type == 3) {
265     push @r, [rank => dec_U8, dec_U32];
266    
267     } elsif ($type == 2) {
268 pcg 1.6 push @r, [player => dec_U8, dec_ZSTRING];
269 pcg 1.1
270 pcg 1.8 } elsif ($type == 1) {
271     push @r, [sgf_name => dec_ZSTRING];
272    
273 pcg 1.1 } elsif ($type == 0) {
274     # as usual, wms finds yet another way to duplicate code... oh well, what a mess.
275     # (no wonder he is so keen on keeping it a secret...)
276    
277     push @r, [rules => dec_rules];
278    
279     # OLD
280    
281     } else {
282 pcg 1.7 require KGS::Listener::Debug; # hack
283 pcg 1.1 print STDERR KGS::Listener::Debug::dumpval(\@r);
284 pcg 1.8 printf "offset: 0x%04x\n", $ofs;
285     open XTYPE, "|xtype"; print XTYPE $old_data; close XTYPE;
286     warn "unknown tree type $type, PLEASE REPORT and include the game you wanted to watch. thx.";
287 pcg 1.1
288     }
289 pcg 1.8
290 pcg 1.11 #push @{$r[-1]}, offset => sprintf "0x%x", $ofs;#d#
291 pcg 1.8
292 pcg 1.1 }
293 pcg 1.8 # print STDERR KGS::Listener::Debug::dumpval(\@r);#d#
294     # return [];#d#
295 pcg 1.1 \@r;
296     }
297    
298     sub enc_TREE {
299     for (@{$_[0]}) {
300     my ($type, @arg) = @$_;
301    
302     if ($type eq "add_node") {
303     enc_U8 127;
304     enc_U8 0; # unused?
305     enc_I32 $arg[0];
306    
307     } elsif ($type eq "set_node") {
308     enc_U8 126;
309     enc_I32 $arg[0];
310    
311     } elsif ($type eq "set_current") {
312     enc_U8 125;
313     enc_I32 $arg[0];
314    
315     } elsif ($type eq "movenum") {
316     enc_U8 28;
317 pcg 1.6 enc_ZSTRING $arg[0];
318 pcg 1.1
319     } elsif ($type eq "set_stone") {
320 pcg 1.6 enc_U8 16;
321     enc_U8 $arg[0];
322 pcg 1.1 enc_U8 $arg[1];
323     enc_U8 $arg[2];
324    
325     } elsif ($type eq "move") {
326 pcg 1.6 enc_U8 14;
327     enc_U8 $arg[0];
328 pcg 1.1 enc_U8 $arg[1];
329     enc_U8 $arg[2];
330    
331     } elsif ($type eq "comment") {
332     enc_U8 24;
333 pcg 1.6 enc_ZSTRING $arg[0];
334    
335     } elsif ($type eq "mark") {
336     my $op = ({
337     &MARK_GRAYED => 23,
338     &MARK_SMALL_B => 22,
339     &MARK_SMALL_W => 22,
340 pcg 1.10 &MARK_SQUARE => 21,
341     &MARK_TRIANGLE => 20,
342     &MARK_LABEL => 19,
343     &MARK_CIRCLE => 15,
344 pcg 1.6 })->{$arg[1]};
345    
346     enc_U8 $op + ($arg[0] ? 0 : 128);
347     enc_U8 $arg[1] == MARK_SMALL_W if $op == 22;
348     enc_U8 $arg[2];
349     enc_U8 $arg[3];
350    
351     enc_ZSTRING $arg[4] if $op == 18;
352 pcg 1.1
353 pcg 1.7 # unknown types
354     } elsif ($type eq "type_29") {
355     enc_U8 29;
356     enc_ZSTRING $arg[0];
357     } elsif ($type eq "type_26") {
358     enc_U8 26;
359     enc_U8 $arg[0];
360    
361 pcg 1.1 } else {
362     warn "unable to encode tree node type $type\n";
363     }
364     }
365 pcg 1.6 };
366    
367 pcg 1.1 ]]>
368    
369     #############################################################################
370     # messages
371     <xsl:apply-templates select="descendant::message"/>
372     }
373    
374     1;
375     </xsl:template>
376    
377     <xsl:template match="type[@type = 'S']">
378     sub dec_<xsl:value-of select="@name"/> {
379     my $res = "";
380     my @r = unpack "v<xsl:value-of select="@length"/> a*", $data;
381     $data = pop @r;
382     for (@r) {
383     last unless $_;
384     $res .= chr $_;
385     }
386     # dump extra data to file for later analysis
387 pcg 1.5 #my $x = pack "v*", @r; $x =~ s/^(..)*?\x00\x00//s; open DUMP, ">>/root/kgs-dump"; print DUMP $x; close DUMP;#d#
388 pcg 1.1 $res;
389     }
390    
391     sub enc_<xsl:value-of select="@name"/> {
392     $data .= pack "v<xsl:value-of select="@length"/>", map ord, split //, $_[0];
393     }
394     </xsl:template>
395    
396     <xsl:template match="type[@type = 'A']">
397     sub dec_<xsl:value-of select="@name"/> {
398     (my ($r), $data) = unpack "Z<xsl:value-of select="@length"/> a*", $data; $r;
399     }
400    
401     sub enc_<xsl:value-of select="@name"/> {
402 pcg 1.2 $data .= pack "a<xsl:value-of select="@length"/>", $_[0];
403 pcg 1.1 }
404     </xsl:template>
405    
406     <xsl:template match="type[@multiplier]">
407     sub dec_<xsl:value-of select="@name"/> {
408     (1 / <xsl:value-of select="@multiplier"/>) * dec_<xsl:value-of select="@type"/>;
409     }
410    
411     sub enc_<xsl:value-of select="@name"/> {
412     enc_<xsl:value-of select="@type"/> $_[0] * <xsl:value-of select="@multiplier"/>;
413     }
414     </xsl:template>
415    
416     <xsl:template match="member[@array = 'yes']" mode="dec">
417     $r->{<xsl:value-of select="@name"/>} = (my $array = []);
418     while (length $data) {
419     push @$array, dec_<xsl:value-of select="@type"/>
420 pcg 1.3 <xsl:text> </xsl:text>;
421 pcg 1.1 }
422     </xsl:template>
423    
424     <xsl:template match="member" mode="dec">
425     $r->{<xsl:value-of select="@name"/>} = dec_<xsl:value-of select="@type"/>
426     <xsl:text> </xsl:text>
427 pcg 1.3 <xsl:value-of select="concat('q|',@value,'|')"/>
428 pcg 1.1 <xsl:if test="@guard-cond">
429     if ($r->{<xsl:value-of select="@guard-member"/>} <xsl:value-of select="@guard-cond"/>)</xsl:if>
430     <xsl:text>;</xsl:text>
431     </xsl:template>
432    
433     <xsl:template match="member" mode="enc">
434     enc_<xsl:value-of select="@type"/> defined $_[0]{<xsl:value-of select="@name"/>} ? $_[0]{<xsl:value-of select="@name"/>
435     <xsl:text>} : (</xsl:text>
436 pcg 1.3 <xsl:value-of select="concat('q|',@value,'|')"/>
437 pcg 1.1 <xsl:text>);</xsl:text>
438     </xsl:template>
439    
440     <xsl:template match="struct">
441     sub dec_<xsl:value-of select="@name"/> {
442     my $r = {};
443     <xsl:apply-templates select="member" mode="dec"/>
444     <xsl:if test="@class">
445     bless $r, <xsl:value-of select="@class"/>::;
446     </xsl:if>
447     $r;
448     }
449    
450     sub enc_<xsl:value-of select="@name"/> {
451     <xsl:apply-templates select="member" mode="enc"/>
452     }
453     </xsl:template>
454    
455     <xsl:template match="message">
456     # <xsl:value-of select="@name"/>
457     $dec_<xsl:value-of select="@src"/>{0x<xsl:value-of select="@type"/>} = sub {
458     $data = $_[0];
459 root 1.12 my $r = { DATA => $data };
460 pcg 1.1 $r->{type} = "<xsl:value-of select="@name"/>";
461     <xsl:apply-templates select="member" mode="dec"/>
462 root 1.12 $r->{TRAILING_DATA} = $data if length $data;
463 pcg 1.1 $r;
464     };
465     $enc_<xsl:value-of select="@src"/>{<xsl:value-of select="@name"/>} = sub {
466     $data = "";
467     enc_U16 0x<xsl:value-of select="@type"/>;
468     <xsl:apply-templates select="member" mode="enc"/>
469     $data;
470     };
471     </xsl:template>
472    
473     <xsl:template match="text()">
474     </xsl:template>
475    
476     </xsl:stylesheet>
477