ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/DC.pm
(Generate patch)

Comparing deliantra/Deliantra-Client/DC.pm (file contents):
Revision 1.124 by root, Wed Oct 11 23:34:24 2006 UTC vs.
Revision 1.135 by root, Thu Dec 7 15:57:13 2006 UTC

15package CFPlus; 15package CFPlus;
16 16
17use Carp (); 17use Carp ();
18 18
19BEGIN { 19BEGIN {
20 $VERSION = '0.52'; 20 $VERSION = '0.97';
21 21
22 use XSLoader; 22 use XSLoader;
23 XSLoader::load "CFPlus", $VERSION; 23 XSLoader::load "CFPlus", $VERSION;
24}
25
26BEGIN {
27 $SIG{__DIE__} = sub {
28 return if CFPlus::in_destruct;
29 #CFPlus::fatal $_[0];#d#
30 CFPlus::error Carp::longmess $_[0];#d#
31 die;#d#
32 };
33} 24}
34 25
35use utf8; 26use utf8;
36 27
37use AnyEvent (); 28use AnyEvent ();
38use BerkeleyDB; 29use BerkeleyDB;
39use Pod::POM (); 30use Pod::POM ();
40use Scalar::Util (); 31use Scalar::Util ();
32use File::Path ();
41use Storable (); # finally 33use Storable (); # finally
34
35BEGIN {
36 use Crossfire::Protocol::Base ();
37 *to_json = \&Crossfire::Protocol::Base::to_json;
38 *from_json = \&Crossfire::Protocol::Base::from_json;
39}
42 40
43=item guard { BLOCK } 41=item guard { BLOCK }
44 42
45Returns an object that executes the given block as soon as it is destroyed. 43Returns an object that executes the given block as soon as it is destroyed.
46 44
50 bless \(my $cb = $_[0]), "CFPlus::Guard" 48 bless \(my $cb = $_[0]), "CFPlus::Guard"
51} 49}
52 50
53sub CFPlus::Guard::DESTROY { 51sub CFPlus::Guard::DESTROY {
54 ${$_[0]}->() 52 ${$_[0]}->()
53}
54
55=item shorten $string[, $maxlength]
56
57=cut
58
59sub shorten($;$) {
60 my ($str, $len) = @_;
61 substr $str, $len, (length $str), "..." if $len + 3 <= length $str;
62 $str
55} 63}
56 64
57sub asxml($) { 65sub asxml($) {
58 local $_ = $_[0]; 66 local $_ = $_[0];
59 67
69 or die "cannot establish bidiretcional pipe: $!\n"; 77 or die "cannot establish bidiretcional pipe: $!\n";
70 78
71 ($fh1, $fh2) 79 ($fh1, $fh2)
72} 80}
73 81
74sub background(&) { 82sub background(&;&) {
75 my ($cb) = @_; 83 my ($bg, $cb) = @_;
76 84
77 my ($fh_r, $fh_w) = CFPlus::socketpipe; 85 my ($fh_r, $fh_w) = CFPlus::socketpipe;
78 86
79 my $pid = fork; 87 my $pid = fork;
80 88
86 close $fh_r; 94 close $fh_r;
87 close $fh_w; 95 close $fh_w;
88 96
89 $| = 1; 97 $| = 1;
90 98
91 eval { $cb->() }; 99 eval { $bg->() };
92 100
93 if ($@) { 101 if ($@) {
94 my $msg = $@; 102 my $msg = $@;
95 $msg =~ s/\n+/\n/; 103 $msg =~ s/\n+/\n/;
96 warn "FATAL: $msg"; 104 warn "FATAL: $msg";
105 113
106 close $fh_w; 114 close $fh_w;
107 115
108 my $buffer; 116 my $buffer;
109 117
110 Event->io (fd => $fh_r, poll => 'r', cb => sub { 118 my $w; $w = AnyEvent->io (fh => $fh_r, poll => 'r', cb => sub {
111 unless (sysread $fh_r, $buffer, 4096, length $buffer) { 119 unless (sysread $fh_r, $buffer, 4096, length $buffer) {
112 $_[0]->w->cancel; 120 undef $w;
113 $buffer .= "done\n"; 121 $cb->();
122 return;
114 } 123 }
115 124
116 while ($buffer =~ s/^(.*)\n//) { 125 while ($buffer =~ s/^(.*)\n//) {
117 my $line = $1; 126 my $line = $1;
118 $line =~ s/\s+$//; 127 $line =~ s/\s+$//;
119 utf8::decode $line; 128 utf8::decode $line;
129 if ($line =~ /^\x{e877}json_msg (.*)$/s) {
130 $cb->(from_json $1);
131 } else {
120 ::message ({ 132 ::message ({
121 markup => "editor($pid): " . CFPlus::asxml $line, 133 markup => "background($pid): " . CFPlus::asxml $line,
134 });
122 }); 135 }
123 } 136 }
124 }); 137 });
138}
139
140sub background_msg {
141 my ($msg) = @_;
142
143 $msg = "\x{e877}json_msg " . to_json $msg;
144 $msg =~ s/\n//g;
145 utf8::encode $msg;
146 print $msg, "\n";
125} 147}
126 148
127package CFPlus::Database; 149package CFPlus::Database;
128 150
129our @ISA = BerkeleyDB::Btree::; 151our @ISA = BerkeleyDB::Btree::;
160 $path = "$_/CFPlus/resources/$_[0]"; 182 $path = "$_/CFPlus/resources/$_[0]";
161 return $path if -r $path; 183 return $path if -r $path;
162 } 184 }
163 185
164 die "FATAL: can't find required file $_[0]\n"; 186 die "FATAL: can't find required file $_[0]\n";
165}
166
167BEGIN {
168 use Crossfire::Protocol::Base ();
169 *to_json = \&Crossfire::Protocol::Base::to_json;
170 *from_json = \&Crossfire::Protocol::Base::from_json;
171} 187}
172 188
173sub read_cfg { 189sub read_cfg {
174 my ($file) = @_; 190 my ($file) = @_;
175 191
217 or return; 233 or return;
218 234
219 $ENV{http_proxy} = $proxy; 235 $ENV{http_proxy} = $proxy;
220} 236}
221 237
238sub lwp_useragent {
239 require LWP::UserAgent;
240
241 CFPlus::set_proxy;
242
243 my $ua = LWP::UserAgent->new (
244 agent => "cfplus $VERSION",
245 keep_alive => 1,
246 env_proxy => 1,
247 timeout => 30,
248 );
249}
250
251sub lwp_check($) {
252 my ($res) = @_;
253
254 $res->is_error
255 and die $res->status_line;
256
257 $res
258}
259
222our $DB_ENV; 260our $DB_ENV;
223our $DB_STATE; 261our $DB_STATE;
224 262
225sub db_table($) { 263sub db_table($) {
226 my ($table) = @_; 264 my ($table) = @_;
235 -Property => DB_CHKSUM, 273 -Property => DB_CHKSUM,
236 -Flags => DB_CREATE | DB_UPGRADE, 274 -Flags => DB_CREATE | DB_UPGRADE,
237 or die "unable to create/open database table $_[0]: $BerkeleyDB::Error" 275 or die "unable to create/open database table $_[0]: $BerkeleyDB::Error"
238} 276}
239 277
240{ 278our $DB_HOME = "$Crossfire::VARDIR/cfplus";
279
280sub open_db {
241 use strict; 281 use strict;
242 282
243 mkdir "$Crossfire::VARDIR/cfplus", 0777; 283 mkdir $DB_HOME, 0777;
244 my $recover = $BerkeleyDB::db_version >= 4.4 284 my $recover = $BerkeleyDB::db_version >= 4.4
245 ? eval "DB_REGISTER | DB_RECOVER" 285 ? eval "DB_REGISTER | DB_RECOVER"
246 : 0; 286 : 0;
247 287
248 $DB_ENV = new BerkeleyDB::Env 288 $DB_ENV = new BerkeleyDB::Env
249 -Home => "$Crossfire::VARDIR/cfplus", 289 -Home => $DB_HOME,
250 -Cachesize => 1_000_000, 290 -Cachesize => 1_000_000,
251 -ErrFile => "$Crossfire::VARDIR/cfplus/errorlog.txt", 291 -ErrFile => "$DB_HOME/errorlog.txt",
252# -ErrPrefix => "DATABASE", 292# -ErrPrefix => "DATABASE",
253 -Verbose => 1, 293 -Verbose => 1,
254 -Flags => DB_CREATE | DB_RECOVER | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN | $recover, 294 -Flags => DB_CREATE | DB_RECOVER | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN | $recover,
255 -SetFlags => DB_AUTO_COMMIT | DB_LOG_AUTOREMOVE, 295 -SetFlags => DB_AUTO_COMMIT | DB_LOG_AUTOREMOVE,
256 or die "unable to create/open database home $Crossfire::VARDIR/cfplus: $BerkeleyDB::Error"; 296 or die "unable to create/open database home $DB_HOME: $BerkeleyDB::Error";
257 297
258 $DB_STATE = db_table "state"; 298 $DB_STATE = db_table "state";
299
300 1
301}
302
303unless (eval { open_db }) {
304 File::Path::rmtree $DB_HOME;
305 open_db;
259} 306}
260 307
261package CFPlus::Layout; 308package CFPlus::Layout;
262 309
263$CFPlus::OpenGL::SHUTDOWN_HOOK{"CFPlus::Layout"} = sub { 310$CFPlus::OpenGL::SHUTDOWN_HOOK{"CFPlus::Layout"} = sub {
361 } elsif ($ev->{button} == 3) { 408 } elsif ($ev->{button} == 3) {
362 my $move_prefix = $::CONN->{open_container} ? 'put' : 'drop'; 409 my $move_prefix = $::CONN->{open_container} ? 'put' : 'drop';
363 if ($self->{container} == $::CONN->{open_container}) { 410 if ($self->{container} == $::CONN->{open_container}) {
364 $move_prefix = "take"; 411 $move_prefix = "take";
365 } 412 }
413
414 my $shortname = CFPlus::shorten $self->{name}, 14;
366 415
367 my @menu_items = ( 416 my @menu_items = (
368 ["examine", sub { $::CONN->send ("examine $self->{tag}") }], 417 ["examine", sub { $::CONN->send ("examine $self->{tag}") }],
369 ["mark", sub { $::CONN->send ("mark ". pack "N", $self->{tag}) }], 418 ["mark", sub { $::CONN->send ("mark ". pack "N", $self->{tag}) }],
370 ["ignite/thaw", # first try of an easier use of flint&steel 419 ["ignite/thaw", # first try of an easier use of flint&steel
406 do_n_dialog (sub { $::CONN->send ("move $targ $self->{tag} $_[0]") }) 455 do_n_dialog (sub { $::CONN->send ("move $targ $self->{tag} $_[0]") })
407 } 456 }
408 ] 457 ]
409 ) 458 )
410 ), 459 ),
460 ["bind <i>apply $shortname</i> to a key" => sub { $::BIND_EDITOR->do_quick_binding (["apply $self->{name}"]) }],
411 ); 461 );
412 462
413 CFPlus::UI::Menu->new (items => \@menu_items)->popup ($ev); 463 CFPlus::UI::Menu->new (items => \@menu_items)->popup ($ev);
414 } 464 }
415 465

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines