ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/kgsueme/doc/doc2messages_pm.xsl
Revision: 1.13
Committed: Sat Jul 2 00:46:24 2005 UTC (18 years, 11 months ago) by root
Content type: application/xml
Branch: MAIN
CVS Tags: HEAD
Changes since 1.12: +1 -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 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 use Games::Go::SimpleBoard; # for MARK_xyz
29 use Math::BigInt ();
30
31 my $data; # stores currently processed decoding/encoding packet
32
33 sub _set_data($) { $data = shift } # for debugging or special apps only
34 sub _get_data() { $data } # for debugging or special apps only
35
36 # 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 # do NOT use Math::BigInt here.
54 my ($lo, $hi) = (dec_U32, dec_U32);
55 $hi * 2**32 + $lo;
56 }
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 sub dec_ZSTRING {
78 $data =~ s/^((?:..)*?)(?:\x00\x00|\Z)//s;
79 # use Encode...
80 join "", map chr, unpack "v*", $1;
81 }
82
83 BEGIN { *dec_STRING = \&dec_ZSTRING };
84
85 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 my $i = new Math::BigInt $_[0];
113
114 enc_U32 $i & 0xffffffff;
115 enc_U32 $i >> 32;
116 }
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 sub enc_ZSTRING {
136 # should use encode for speed and clarity ;)
137 $data .= pack "v*", (map ord, split //, $_[0]), 0;
138 }
139
140 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 enc_U64 $hash & new Math::BigInt "0xffffffffffffffff";
154 }
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 my $old_data = $data;#d#
177 while (length $data) {
178 my $type = dec_U8;
179 my $add = $type < 128;
180
181 my $ofs = (length $old_data) - (length $data);#d#
182
183 $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 push @r, [score => dec_U8, dec_score32_1000];
197
198 } elsif ($type == 29) {
199 push @r, [type_29 => dec_ZSTRING];
200 warn "UNKNOWN TREE TYPE 29 $r[-1][1]\007 PLEASE REPORT";#d#
201 die;
202
203 } elsif ($type == 28) {
204 # move number, only in variations it seems. oh my.
205 push @r, [movenum => dec_ZSTRING];
206
207 } elsif ($type == 26) {
208 push @r, [type_26 => dec_U8]; # sets a flag (?)
209 warn "unknown tree node 26, please ignore\n";
210 # possibly marks moves done while editing, as opposed to game-moves(?)
211
212 } 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 push @r, [mark => $add, dec_U8() ? MARK_SMALL_W : MARK_SMALL_B, dec_U8, dec_U8];
220
221 } elsif ($type == 21) {
222 push @r, [mark => $add, MARK_SQUARE, dec_U8, dec_U8];
223
224 } elsif ($type == 20) {
225 push @r, [mark => $add, MARK_TRIANGLE, dec_U8, dec_U8];
226
227 } elsif ($type == 19) {
228 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
232 } elsif ($type == 18) {
233 push @r, [set_timer => (dec_U8, dec_U32, dec_time)[0,2,1]];
234
235 } elsif ($type == 17) {
236 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
241 } elsif ($type == 15) {
242 push @r, [mark => $add, MARK_CIRCLE, dec_U8, dec_U8];#d#?
243
244 } elsif ($type == 14) {
245 push @r, [move => dec_U8, dec_U8, dec_U8];
246
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 6 => "game_id", #?#
255 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 })->{$type} => dec_ZSTRING];
263
264 } elsif ($type == 3) {
265 push @r, [rank => dec_U8, dec_U32];
266
267 } elsif ($type == 2) {
268 push @r, [player => dec_U8, dec_ZSTRING];
269
270 } elsif ($type == 1) {
271 push @r, [sgf_name => dec_ZSTRING];
272
273 } 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 require KGS::Listener::Debug; # hack
283 print STDERR KGS::Listener::Debug::dumpval(\@r);
284 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
288 }
289
290 #push @{$r[-1]}, offset => sprintf "0x%x", $ofs;#d#
291
292 }
293 # print STDERR KGS::Listener::Debug::dumpval(\@r);#d#
294 # return [];#d#
295 \@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 enc_ZSTRING $arg[0];
318
319 } elsif ($type eq "set_stone") {
320 enc_U8 16;
321 enc_U8 $arg[0];
322 enc_U8 $arg[1];
323 enc_U8 $arg[2];
324
325 } elsif ($type eq "move") {
326 enc_U8 14;
327 enc_U8 $arg[0];
328 enc_U8 $arg[1];
329 enc_U8 $arg[2];
330
331 } elsif ($type eq "comment") {
332 enc_U8 24;
333 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 &MARK_SQUARE => 21,
341 &MARK_TRIANGLE => 20,
342 &MARK_LABEL => 19,
343 &MARK_CIRCLE => 15,
344 })->{$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
353 # 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 } else {
362 warn "unable to encode tree node type $type\n";
363 }
364 }
365 };
366
367 ]]>
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 #my $x = pack "v*", @r; $x =~ s/^(..)*?\x00\x00//s; open DUMP, ">>/root/kgs-dump"; print DUMP $x; close DUMP;#d#
388 $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 $data .= pack "a<xsl:value-of select="@length"/>", $_[0];
403 }
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 <xsl:text> </xsl:text>;
421 }
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 <xsl:value-of select="concat('q|',@value,'|')"/>
428 <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 <xsl:value-of select="concat('q|',@value,'|')"/>
437 <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 my $r = { DATA => $data };
460 $r->{type} = "<xsl:value-of select="@name"/>";
461 <xsl:apply-templates select="member" mode="dec"/>
462 $r->{TRAILING_DATA} = $data if length $data;
463 $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