ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/lib/cf.pm
(Generate patch)

Comparing deliantra/server/lib/cf.pm (file contents):
Revision 1.419 by root, Sun Apr 13 01:34:09 2008 UTC vs.
Revision 1.428 by root, Thu May 1 06:33:19 2008 UTC

427 } 427 }
428 } 428 }
429}; 429};
430 430
431sub get_slot($;$$) { 431sub get_slot($;$$) {
432 return if tick_inhibit || $Coro::current == $Coro::main;
433
432 my ($time, $pri, $name) = @_; 434 my ($time, $pri, $name) = @_;
433 435
434 $time = $TICK * .6 if $time > $TICK * .6; 436 $time = $TICK * .6 if $time > $TICK * .6;
435 my $sig = new Coro::Signal; 437 my $sig = new Coro::Signal;
436 438
1139 utf8::decode (my $decname = $filename); 1141 utf8::decode (my $decname = $filename);
1140 warn sprintf "saving %s (%d,%d)\n", 1142 warn sprintf "saving %s (%d,%d)\n",
1141 $decname, length $$rdata, scalar @$objs; 1143 $decname, length $$rdata, scalar @$objs;
1142 1144
1143 if (my $fh = aio_open "$filename~", O_WRONLY | O_CREAT, 0600) { 1145 if (my $fh = aio_open "$filename~", O_WRONLY | O_CREAT, 0600) {
1144 chmod SAVE_MODE, $fh; 1146 aio_chmod $fh, SAVE_MODE;
1145 aio_write $fh, 0, (length $$rdata), $$rdata, 0; 1147 aio_write $fh, 0, (length $$rdata), $$rdata, 0;
1146 aio_fsync $fh if $cf::USE_FSYNC; 1148 aio_fsync $fh if $cf::USE_FSYNC;
1147 close $fh; 1149 aio_close $fh;
1148 1150
1149 if (@$objs) { 1151 if (@$objs) {
1150 if (my $fh = aio_open "$filename.pst~", O_WRONLY | O_CREAT, 0600) { 1152 if (my $fh = aio_open "$filename.pst~", O_WRONLY | O_CREAT, 0600) {
1151 chmod SAVE_MODE, $fh; 1153 aio_chmod $fh, SAVE_MODE;
1152 my $data = Coro::Storable::nfreeze { version => 1, objs => $objs }; 1154 my $data = Coro::Storable::nfreeze { version => 1, objs => $objs };
1153 aio_write $fh, 0, (length $data), $data, 0; 1155 aio_write $fh, 0, (length $data), $data, 0;
1154 aio_fsync $fh if $cf::USE_FSYNC; 1156 aio_fsync $fh if $cf::USE_FSYNC;
1155 close $fh; 1157 aio_close $fh;
1156 aio_rename "$filename.pst~", "$filename.pst"; 1158 aio_rename "$filename.pst~", "$filename.pst";
1157 } 1159 }
1158 } else { 1160 } else {
1159 aio_unlink "$filename.pst"; 1161 aio_unlink "$filename.pst";
1160 } 1162 }
1454 my $f = new_from_file cf::object::thawer path $login 1456 my $f = new_from_file cf::object::thawer path $login
1455 or return; 1457 or return;
1456 1458
1457 my $pl = cf::player::load_pl $f 1459 my $pl = cf::player::load_pl $f
1458 or return; 1460 or return;
1461
1459 local $cf::PLAYER_LOADING{$login} = $pl; 1462 local $cf::PLAYER_LOADING{$login} = $pl;
1460 $f->resolve_delayed_derefs; 1463 $f->resolve_delayed_derefs;
1461 $cf::PLAYER{$login} = $pl 1464 $cf::PLAYER{$login} = $pl
1462 } 1465 }
1463 } 1466 }
1473 1476
1474 return if $pl->{deny_save}; 1477 return if $pl->{deny_save};
1475 1478
1476 aio_mkdir playerdir $pl, 0770; 1479 aio_mkdir playerdir $pl, 0770;
1477 $pl->{last_save} = $cf::RUNTIME; 1480 $pl->{last_save} = $cf::RUNTIME;
1481
1482 cf::get_slot 0.01;
1478 1483
1479 $pl->save_pl ($path); 1484 $pl->save_pl ($path);
1480 cf::cede_to_tick; 1485 cf::cede_to_tick;
1481} 1486}
1482 1487
1566 1571
1567 for my $login (@$dirs) { 1572 for my $login (@$dirs) {
1568 my $path = path $login; 1573 my $path = path $login;
1569 1574
1570 # a .pst is a dead give-away for a valid player 1575 # a .pst is a dead give-away for a valid player
1571 unless (-e "$path.pst") { 1576 # if no pst file found, open and chekc for blocked users
1577 if (aio_stat "$path.pst") {
1572 my $fh = aio_open $path, Fcntl::O_RDONLY, 0 or next; 1578 my $fh = aio_open $path, Fcntl::O_RDONLY, 0 or next;
1573 aio_read $fh, 0, 512, my $buf, 0 or next; 1579 aio_read $fh, 0, 512, my $buf, 0 or next;
1574 $buf !~ /^password -------------$/m or next; # official not-valid tag 1580 $buf !~ /^password -------------$/m or next; # official not-valid tag
1575 } 1581 }
1576 1582
2113 } 2119 }
2114 2120
2115 $self->{last_save} = $cf::RUNTIME; 2121 $self->{last_save} = $cf::RUNTIME;
2116 $self->last_access ($cf::RUNTIME); 2122 $self->last_access ($cf::RUNTIME);
2117 2123
2118 $self->in_memory (cf::MAP_IN_MEMORY); 2124 $self->in_memory (cf::MAP_ACTIVE);
2119 } 2125 }
2120 2126
2121 $self->post_load; 2127 $self->post_load;
2122} 2128}
2123 2129
2181 my ($path, $origin, $load) = @_; 2187 my ($path, $origin, $load) = @_;
2182 2188
2183 $path = normalise $path, $origin && $origin->{path}; 2189 $path = normalise $path, $origin && $origin->{path};
2184 2190
2185 if (my $map = $cf::MAP{$path}) { 2191 if (my $map = $cf::MAP{$path}) {
2186 return $map if !$load || $map->in_memory == cf::MAP_IN_MEMORY; 2192 return $map if !$load || $map->in_memory == cf::MAP_ACTIVE;
2187 } 2193 }
2188 2194
2189 $MAP_PREFETCH{$path} |= $load; 2195 $MAP_PREFETCH{$path} |= $load;
2190 2196
2191 $MAP_PREFETCHER ||= cf::async { 2197 $MAP_PREFETCHER ||= cf::async {
2228 cf::async { 2234 cf::async {
2229 $Coro::current->{desc} = "map player save"; 2235 $Coro::current->{desc} = "map player save";
2230 $_->contr->save for $self->players; 2236 $_->contr->save for $self->players;
2231 }; 2237 };
2232 2238
2239 cf::get_slot 0.02;
2240
2233 if ($uniq) { 2241 if ($uniq) {
2234 $self->_save_objects ($save, cf::IO_HEADER | cf::IO_OBJECTS); 2242 $self->_save_objects ($save, cf::IO_HEADER | cf::IO_OBJECTS);
2235 $self->_save_objects ($uniq, cf::IO_UNIQUES); 2243 $self->_save_objects ($uniq, cf::IO_UNIQUES);
2236 } else { 2244 } else {
2237 $self->_save_objects ($save, cf::IO_HEADER | cf::IO_OBJECTS | cf::IO_UNIQUES); 2245 $self->_save_objects ($save, cf::IO_HEADER | cf::IO_OBJECTS | cf::IO_UNIQUES);
2245 $self->save; 2253 $self->save;
2246 2254
2247 my $lock = cf::lock_acquire "map_data:$self->{path}"; 2255 my $lock = cf::lock_acquire "map_data:$self->{path}";
2248 2256
2249 return if $self->players; 2257 return if $self->players;
2250 return if $self->in_memory != cf::MAP_IN_MEMORY; 2258 return if $self->in_memory != cf::MAP_ACTIVE;
2251 return if $self->{deny_save}; 2259 return if $self->{deny_save};
2252 2260
2253 $self->in_memory (cf::MAP_SWAPPED); 2261 $self->in_memory (cf::MAP_SWAPPED);
2254 2262
2255 $self->deactivate; 2263 $self->deactivate;
2451can be C<undef>. Does the right thing when the player is currently in a 2459can be C<undef>. Does the right thing when the player is currently in a
2452dialogue with the given NPC character. 2460dialogue with the given NPC character.
2453 2461
2454=cut 2462=cut
2455 2463
2464our $SAY_CHANNEL = {
2465 id => "say",
2466 title => "Map",
2467 reply => "say ",
2468 tooltip => "Things said to and replied from npcs near you and other players on the same map only.",
2469};
2470
2471our $CHAT_CHANNEL = {
2472 id => "chat",
2473 title => "Chat",
2474 reply => "chat ",
2475 tooltip => "Player chat and shouts, global to the server.",
2476};
2477
2456# rough implementation of a future "reply" method that works 2478# rough implementation of a future "reply" method that works
2457# with dialog boxes. 2479# with dialog boxes.
2458#TODO: the first argument must go, split into a $npc->reply_to ( method 2480#TODO: the first argument must go, split into a $npc->reply_to ( method
2459sub cf::object::player::reply($$$;$) { 2481sub cf::object::player::reply($$$;$) {
2460 my ($self, $npc, $msg, $flags) = @_; 2482 my ($self, $npc, $msg, $flags) = @_;
2471 my $dialog = $pl->{npc_dialog}; 2493 my $dialog = $pl->{npc_dialog};
2472 $dialog->{pl}->ext_msg ($dialog->{id}, update => msg => $dialog->{pl}->expand_cfpod ($msg)); 2494 $dialog->{pl}->ext_msg ($dialog->{id}, update => msg => $dialog->{pl}->expand_cfpod ($msg));
2473 2495
2474 } else { 2496 } else {
2475 $msg = $npc->name . " says: $msg" if $npc; 2497 $msg = $npc->name . " says: $msg" if $npc;
2476 $self->message ($msg, $flags); 2498 $self->send_msg ($SAY_CHANNEL => $msg, $flags);
2477 } 2499 }
2478 } 2500 }
2479} 2501}
2480 2502
2481=item $object->send_msg ($channel, $msg, $color, [extra...]) 2503=item $object->send_msg ($channel, $msg, $color, [extra...])
2693 $rmp->{origin_y} = $exit->y; 2715 $rmp->{origin_y} = $exit->y;
2694 } 2716 }
2695 2717
2696 $rmp->{random_seed} ||= $exit->random_seed; 2718 $rmp->{random_seed} ||= $exit->random_seed;
2697 2719
2698 my $data = cf::encode_json $rmp; 2720 my $data = JSON::XS->new->utf8->pretty->canonical->encode ($rmp);
2699 my $md5 = Digest::MD5::md5_hex $data; 2721 my $md5 = Digest::MD5::md5_hex $data;
2700 my $meta = "$RANDOMDIR/$md5.meta"; 2722 my $meta = "$RANDOMDIR/$md5.meta";
2701 2723
2702 if (my $fh = aio_open "$meta~", O_WRONLY | O_CREAT, 0666) { 2724 if (my $fh = aio_open "$meta~", O_WRONLY | O_CREAT, 0666) {
2703 aio_write $fh, 0, (length $data), $data, 0; 2725 aio_write $fh, 0, (length $data), $data, 0;
2826 id => "infobox", 2848 id => "infobox",
2827 title => "Map Info", 2849 title => "Map Info",
2828 reply => undef, 2850 reply => undef,
2829 tooltip => "Information related to the maps", 2851 tooltip => "Information related to the maps",
2830 }, 2852 },
2853 "c/party" => {
2854 id => "party",
2855 title => "Party",
2856 reply => "gsay ",
2857 tooltip => "Messages and chat related to your party",
2858 },
2831); 2859);
2832 2860
2833sub cf::client::send_msg { 2861sub cf::client::send_msg {
2834 my ($self, $channel, $msg, $color, @extra) = @_; 2862 my ($self, $channel, $msg, $color, @extra) = @_;
2835 2863
3072 3100
3073The following functions and methods are available within a safe environment: 3101The following functions and methods are available within a safe environment:
3074 3102
3075 cf::object 3103 cf::object
3076 contr pay_amount pay_player map x y force_find force_add destroy 3104 contr pay_amount pay_player map x y force_find force_add destroy
3077 insert remove name archname title slaying race decrease_ob_nr 3105 insert remove name archname title slaying race decrease split
3078 3106
3079 cf::object::player 3107 cf::object::player
3080 player 3108 player
3081 3109
3082 cf::player 3110 cf::player
3088=cut 3116=cut
3089 3117
3090for ( 3118for (
3091 ["cf::object" => qw(contr pay_amount pay_player map force_find force_add x y 3119 ["cf::object" => qw(contr pay_amount pay_player map force_find force_add x y
3092 insert remove inv name archname title slaying race 3120 insert remove inv name archname title slaying race
3093 decrease_ob_nr destroy)], 3121 decrease split destroy)],
3094 ["cf::object::player" => qw(player)], 3122 ["cf::object::player" => qw(player)],
3095 ["cf::player" => qw(peaceful)], 3123 ["cf::player" => qw(peaceful)],
3096 ["cf::map" => qw(trigger)], 3124 ["cf::map" => qw(trigger)],
3097) { 3125) {
3098 no strict 'refs'; 3126 no strict 'refs';
3306 while (my ($k, $v) = each %$want) { 3334 while (my ($k, $v) = each %$want) {
3307 $ns->fx_want ($k, $v); 3335 $ns->fx_want ($k, $v);
3308 } 3336 }
3309}; 3337};
3310 3338
3339sub load_resource_file($) {
3340 my $guard = lock_acquire "load_resource_file";
3341
3342 my $status = load_resource_file_ $_[0];
3343 get_slot 0.1, 100;
3344 cf::arch::commit_load;
3345
3346 $status
3347}
3348
3311sub reload_regions { 3349sub reload_regions {
3312 # HACK to clear player env face cache, we need some signal framework 3350 # HACK to clear player env face cache, we need some signal framework
3313 # for this (global event?) 3351 # for this (global event?)
3314 %ext::player_env::MUSIC_FACE_CACHE = (); 3352 %ext::player_env::MUSIC_FACE_CACHE = ();
3315 3353
3328} 3366}
3329 3367
3330sub reload_archetypes { 3368sub reload_archetypes {
3331 load_resource_file "$DATADIR/archetypes" 3369 load_resource_file "$DATADIR/archetypes"
3332 or die "unable to load archetypes\n"; 3370 or die "unable to load archetypes\n";
3333 #d# NEED to laod twice to resolve forward references
3334 # this really needs to be done in an extra post-pass
3335 # (which needs to be synchronous, so solve it differently)
3336 load_resource_file "$DATADIR/archetypes"
3337 or die "unable to load archetypes\n";
3338} 3371}
3339 3372
3340sub reload_treasures { 3373sub reload_treasures {
3341 load_resource_file "$DATADIR/treasures" 3374 load_resource_file "$DATADIR/treasures"
3342 or die "unable to load treasurelists\n"; 3375 or die "unable to load treasurelists\n";
3343} 3376}
3344 3377
3345sub reload_resources { 3378sub reload_resources {
3346 warn "reloading resource files...\n"; 3379 warn "reloading resource files...\n";
3347 3380
3381 reload_facedata;
3382 reload_archetypes;
3348 reload_regions; 3383 reload_regions;
3349 reload_facedata;
3350 #reload_archetypes;#d#
3351 reload_archetypes;
3352 reload_treasures; 3384 reload_treasures;
3353 3385
3354 warn "finished reloading resource files\n"; 3386 warn "finished reloading resource files\n";
3355} 3387}
3356 3388
3357sub init { 3389sub init {
3390 my $guard = freeze_mainloop;
3391
3358 reload_resources; 3392 reload_resources;
3359} 3393}
3360 3394
3361sub reload_config { 3395sub reload_config {
3362 open my $fh, "<:utf8", "$CONFDIR/config" 3396 open my $fh, "<:utf8", "$CONFDIR/config"
3387 $Coro::current->{desc} = "IDLE BUG HANDLER"; 3421 $Coro::current->{desc} = "IDLE BUG HANDLER";
3388 EV::loop EV::LOOP_ONESHOT; 3422 EV::loop EV::LOOP_ONESHOT;
3389 })->prio (Coro::PRIO_MAX); 3423 })->prio (Coro::PRIO_MAX);
3390 }; 3424 };
3391 3425
3426 {
3427 my $guard = freeze_mainloop;
3392 reload_config; 3428 reload_config;
3393 db_init; 3429 db_init;
3394 load_extensions; 3430 load_extensions;
3395 3431
3396 $Coro::current->prio (Coro::PRIO_MAX); # give the main loop max. priority 3432 $Coro::current->prio (Coro::PRIO_MAX); # give the main loop max. priority
3397 evthread_start IO::AIO::poll_fileno; 3433 evthread_start IO::AIO::poll_fileno;
3434 }
3435
3398 EV::loop; 3436 EV::loop;
3399} 3437}
3400 3438
3401############################################################################# 3439#############################################################################
3402# initialisation and cleanup 3440# initialisation and cleanup
3684 3722
3685our @WAIT_FOR_TICK; 3723our @WAIT_FOR_TICK;
3686our @WAIT_FOR_TICK_BEGIN; 3724our @WAIT_FOR_TICK_BEGIN;
3687 3725
3688sub wait_for_tick { 3726sub wait_for_tick {
3689 return if tick_inhibit;
3690 return if $Coro::current == $Coro::main; 3727 return if tick_inhibit || $Coro::current == $Coro::main;
3691 3728
3692 my $signal = new Coro::Signal; 3729 my $signal = new Coro::Signal;
3693 push @WAIT_FOR_TICK, $signal; 3730 push @WAIT_FOR_TICK, $signal;
3694 $signal->wait; 3731 $signal->wait;
3695} 3732}
3696 3733
3697sub wait_for_tick_begin { 3734sub wait_for_tick_begin {
3698 return if tick_inhibit;
3699 return if $Coro::current == $Coro::main; 3735 return if tick_inhibit || $Coro::current == $Coro::main;
3700 3736
3701 my $signal = new Coro::Signal; 3737 my $signal = new Coro::Signal;
3702 push @WAIT_FOR_TICK_BEGIN, $signal; 3738 push @WAIT_FOR_TICK_BEGIN, $signal;
3703 $signal->wait; 3739 $signal->wait;
3704} 3740}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines