ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/kgsueme/doc/doc2messages_pm.xsl
Revision: 1.9
Committed: Tue May 25 15:54:02 2004 UTC (20 years ago) by pcg
Content type: application/xml
Branch: MAIN
Changes since 1.8: +0 -1 lines
Log Message:
*** empty log message ***

File Contents

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