chiark / gitweb /
Merge branch 'master' of chiark.greenend.org.uk:things/Yarrgweb/ypp-sc-tools.test
[ypp-sc-tools.main.git] / yarrg / decode-pctb-marketdata
1 #!/usr/bin/perl -w
2
3 # This specific file is hereby placed in the public domain, or nearest
4 # equivalent in law, by me, Ian Jackson.  5th July 2009.
5
6 BEGIN { unshift @INC, qw(.) }
7
8 use IO::File;
9 use strict (qw(vars));
10
11 use Commods;
12
13 our ($debug)= 0;
14
15 $debug=1 if @ARGV;
16
17 parse_pctb_commodmap();
18
19 our %stallkinds= qw(A Apothecary
20                     D Distilling
21                     F Furnishing
22                     I Ironworking
23                     S Shipbuilding
24                     T Tailor
25                     W Weaving);
26
27 sub getline ($) {
28     my ($w)= @_;
29     $!=0; my $l= <STDIN>; die $! unless defined $l;
30     die $! if STDIN->error;
31     die unless chomp $l;
32     print "GOT FOR $w LINE [$l]\n"
33         if $debug;
34     return $l;
35 }
36
37 sub getint ($) {
38     my ($w)= @_;
39     my $b;
40     my $t= tell STDIN; $t>=0 or die $!;
41     my $r= read STDIN,$b,2; die $! if STDIN->error;
42     die unless $r==2;
43     my $v= scalar unpack "v", $b;
44     printf "GOT AT 0x%x INT FOR %s VALUE %d 0x%x\n", $t, $w, $v, $v
45         if $debug;
46     return $v;
47 }
48
49 sub inmap($\@$) {
50     my ($what,$ary,$ix) = @_;
51     my $got= $ary->[$ix];
52     return $got if defined $got;
53     die "$what $ix ?";
54 }
55     
56
57 printf "# Version: \"%s\"\n", getline("version");
58 our $nstalls= getline("nstalls")+0;
59 our @stalls;
60
61 while (@stalls < $nstalls) {
62     $_= getline("stall name ".(@stalls+1));
63     if (s/\^([A-Z])$//) {
64         my $kind= $1;
65         my $sk= $stallkinds{$kind};
66         die "kind $kind in $_ ?" unless defined $sk;
67         $_ .= "'s $sk Stall";
68     }
69     push @stalls, $_;
70 }
71 unshift @stalls, undef;
72
73 $|=1;
74
75 sub chk_ascending ($$$) {
76     my ($this,$lastref,$desc) = @_;
77     printf "# WARNING - $desc $this < $$lastref\n"
78         if defined($$lastref) and $this < $$lastref;
79     $$lastref= $this;
80 }
81
82 foreach my $bs qw(Buy Sell) {
83     my $alloffers_want= getint("Buy ncommods");
84     my $alloffers_done=0;
85     my $commodix_last;
86     my $price_last;
87     while ($alloffers_done < $alloffers_want)  {
88         my $commodix= getint("Buy $alloffers_done/$alloffers_want commodix");
89         $price_last=undef unless
90             defined($commodix_last) && $commodix == $commodix_last;
91         my $offers= getint("Buy $commodix offers");
92         my $offernum;
93         for ($offernum=0; $offernum<$offers; $offernum++) {
94             my $stallix= getint("Buy $commodix $offernum stallix");
95             my $price= getint("Buy $commodix $offernum price");
96             my $qty= getint("Buy $commodix $offernum qty");
97             printf("%s\t%s\t%s",
98                    $bs,
99                    inmap('commod',@pctb_commodmap,$commodix),
100                    inmap('stall',@stalls,$stallix)) or die $!;
101             my $chk_asc_price_neg;
102             my $pricesort;
103             if ($bs eq 'Sell') { $pricesort=1; print "\t\t" or die $!; }
104             printf("\t%d\t%d", $price, $qty) or die $!;
105             if ($bs eq 'Buy') { $pricesort=-1; print "\t\t" or die $!; }
106             print "\n" or die $!;
107             chk_ascending($commodix,\$commodix_last,'commodix');
108             chk_ascending($pricesort*$price,\$price_last,'price');
109             $alloffers_done++;
110             die if $alloffers_done > $alloffers_want;
111         }
112     }
113 }
114
115 my $r= read STDIN,$b,1;
116 STDIN->error and die $!;
117 STDIN->eof or die;
118 $b and die;
119
120
121
122
123 #
124 #
125 #Version number (3 ascii digits) followed
126 #by LF (i.e. 0x0A).  Current version is\
127 # 005
128 #
129 #  0000   30 30 35 0a                                        005.
130 #
131 ## of shops/stalls (in ascii)  + LF
132 #  0000               31 0a                                      1.           
133 #
134 #list of shop names in ascii (without the
135 #possessive part and by specifying the \
136 #shop type in an abbreviated way which is
137 #mentioned below).  The shop names are
138 #separated \ by line feeds (0x0A).  To
139 #specify the shop type append the "^"
140 #character and then \ one of the
141 #following characters depending upon the
142 #shop type:
143 #   Apothecary = A
144 #   Distillery = D
145 #   Furnisher = F
146 #   Iron Monger = I
147 #   Shipyard = S
148 #   Tailor = T
149 #   Weavery = W
150 #
151 #  0000                     4f 6c  64 20 49 72 6f 6e 73 69         Ol d Ironsi
152 #  0010   64 65 73 0a                                        des.              
153 #
154 ## of buy offers (in binary)
155 #  0010               05 00                                 
156 #
157 #commodIndex offerCount                                       buy 0/5
158 #  0010                     0a 00  01 00                      Grog x 1
159 #[shopIndex val amt]                   
160 #  0010                                  01 00 1d 00 75 00    OI 29 qty 75
161 #
162 #commodIndex offerCount                                       buy 1/5
163 #  0020   0b 00 01 00                                         Fine x 1
164 #[shopIndex val amt]... (all in binar\ y)
165 #  0020               01 00 33 00  e9 03                      OI 51 qty 0x3e9
166 #
167 #commodIndex offerCount                                       buy 2/5
168 #  0020                                  0c 00 01 00          Small shot x 1
169 #[shopIndex val amt]
170 #  0020                                              01 00    OI
171 #  0030   0f 00 e9 03                                         15 qty 0x3e9
172 #
173 #commodIndex offerCount                                       buy 3/5
174 #  0030               0d 00 01 00                             Medium shot x 1
175 #[shopIndex val amt]
176 #  0030                            01 00 1c 00 e9 03          OI 28 qty 0x3e9
177 #
178 #commodIndex offerCount                                       buy 4/5
179 #  0030                                              0e 00    Large shot
180 #  0040   01 00                                                          x 1
181 #[shopIndex val amt]
182 #  0040         01 00 26 00 e9 03                             OI 38 0x3e9
183 #
184 #
185 ## of sell offers (in binary)
186 #  0040                            04 00
187 #
188 #commodIndex offerCount                                       sell 0/4
189 #  0040                                  09 00 01 00          Swill x 1
190 #[shopIndex val amt]
191 #  0040                                              01 00    OI 
192 #  0050   17 00 e8 03                                         23 0x3e8
193 #commodIndex offerCount                                       sell 1/4
194 #  0050               0a 00 01 00                             Grog x 1
195 #[shopIndex val amt]
196 #  0050                            01 00 1e 00 73 03          OI 30 qty 0x373
197 #commodIndex offerCount                                       sell 2/4
198 #  0050                                              0c 00    Small shot
199 #  0060   01 00                                               x 1
200 #[shopIndex val amt]
201 #  0060         01 00 10 00 07 00                             OI 16 qty 7
202 #commodIndex offerCount                                       sell 3/4
203 #  0060                            0d 00 01 00                Medium shot x 1
204 #[shopIndex val amt]
205 #  0060                                        01 00 1e 00    OI 30
206 #  0070   02 00                                               qty 2
207 #
208 # buy offers need to be sorted first by commodity index, then by
209 # prices (prices ascending)
210 # sell offers need to be sorted first by commodity index, then by
211 # prices (prices descending)
212 # [ however, it seems that this is wrong and the price sort order is
213 #   supposed to be descending for buy and ascending for sell ]