#! perl # mandatory # the setup command use JSON::XS (); use List::Util qw(min max); sub do_setup { my ($ns, $setup) = @_; my %orig = %$setup; while (my ($k, $v) = each %$setup) { if ($k eq "sound") { $ns->sound ($v); } elsif ($k eq "spellmon") { $ns->monitor_spells ($v); } elsif ($k eq "mapinfocmd") { $ns->mapinfocmd ($v); } elsif ($k eq "extcmd") { $ns->extcmd (min 2, $v); } elsif ($k eq "faceset") { $ns->faceset (0); $setup->{$k} = 0; # $ns->image2 (1) } elsif ($k eq "tileset") { $setup->{$k} = $ns->faceset (int cf::clamp $v, 0, 2); } elsif ($k eq "itemcmd") { # Version of the item protocol command to use. Currently, # only supported versions are 1 and 2. Using a numeric # value will make it very easy to extend this in the future. $ns->itemcmd ($v) if $v >= 1 && $v <= 2; $setup->{$k} = $ns->itemcmd; } elsif ($k eq "mapsize") { my ($x, $y) = split /x/, $v; # we *need* to make sure we use an odd map size, as the remaining # code relies on this. $ns->mapx ($x = max 9, min +(cf::MAP_CLIENT_X - 1) | 1, ($x - 1) | 1); $ns->mapy ($y = max 9, min +(cf::MAP_CLIENT_Y - 1) | 1, ($y - 1) | 1); $setup->{$k} = "${x}x${y}"; } elsif ($k eq "extendedTextInfos") { $ns->has_readable_type ($v); } elsif ($k eq "smoothing") { # cfplus-style smoothing $ns->smoothing ($v); } elsif ($k eq "widget") { # server-side widgets $v = $v > 1; $ns->{can_widget} = $v; $ns->fx_want (6 => 1); # need support for RSRC $setup->{$k} = $v ? 2 : 0; } elsif ($k eq "lzf") { # the lzf packet simply contains an lzf-compressed packet as argument $ns->{can_lzf} = $v == 1; } elsif ($k eq "frag") { # the frag packet contains data which gets appended to the existing packet buffer. # empty frag packet means end of packet. $ns->{can_frag} = $v == 1; } elsif ($k eq "excmd") { # we support it } else { # other commands: # sexp: no idea, probably for oudated servers # tick: more stupidity, server should send a tick per tick $setup->{$k} = "FALSE"; } } # force some mandatory protocol options, most of these # are for obsolete clients only # $setup->{darkness} = 1; # $setup->{exp64} = 1; $setup->{extmap} = 1; # $setup->{facecache} = 1; $setup->{fxix} = 3; $setup->{map1acmd} = 1; $setup->{map1cmd} = 0; $setup->{msg} = 1; cf::datalog setup => request => \%orig, reply => $setup, ; } cf::client->attach (on_setup => sub { my ($ns, $args) = @_; # run through the cmds of setup # syntax is setup ... # or setup json-object # # we send the status of the cmd back, or a FALSE is the cmd if the server unknown # the client then must sort this out if ($args =~ /^\s*\{/) { my $setup = eval { JSON::XS::decode_json $args } || {}; do_setup $ns, $setup; $ns->send_packet ("setup " . JSON::XS::encode_json $setup); } else { my %setup = split / +/, $args; do_setup $ns, \%setup; $ns->send_packet (join " ", setup => %setup); } });