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.564 by elmex, Thu Apr 28 14:58:08 2011 UTC vs.
Revision 1.570 by root, Wed May 4 07:41:14 2011 UTC

1816 for (@$files) { 1816 for (@$files) {
1817 utf8::decode $_; 1817 utf8::decode $_;
1818 next if /\.(?:pl|pst)$/; 1818 next if /\.(?:pl|pst)$/;
1819 next unless /^$PATH_SEP/o; 1819 next unless /^$PATH_SEP/o;
1820 1820
1821 push @paths, cf::map::normalise "~$pl/$_", $pl->map; 1821 push @paths, cf::map::normalise "~$pl/$_";
1822 } 1822 }
1823 1823
1824 \@paths 1824 \@paths
1825} 1825}
1826 1826
1954 # {... are special paths that are not being touched 1954 # {... are special paths that are not being touched
1955 # ?xxx/... are special absolute paths 1955 # ?xxx/... are special absolute paths
1956 # ?random/... random maps 1956 # ?random/... random maps
1957 # /... normal maps 1957 # /... normal maps
1958 # ~user/... per-player map of a specific user 1958 # ~user/... per-player map of a specific user
1959 # !up !down for quad maps, or other maps with up/down layers
1960 1959
1961 $path =~ s/$PATH_SEP/\//go; 1960 $path =~ s/$PATH_SEP/\//go;
1962 1961
1963 # treat it as relative path if it starts with 1962 # treat it as relative path if it starts with
1964 # something that looks reasonable 1963 # something that looks reasonable
1965 if ($path =~ m{^(?:\./|\.\./|\w)}) { 1964 if ($path =~ m{^(?:\./|\.\./|\w)}) {
1966 $base or Carp::carp "normalise called with relative path and no base: '$path'"; 1965 $base or Carp::carp "normalise called with relative path and no base: '$path'";
1967 1966
1968 $base =~ s{[^/]+/?$}{}; 1967 $base =~ s{[^/]+/?$}{};
1969 $path = "$base/$path"; 1968 $path = "$base/$path";
1970
1971 } elsif ($path eq '!up') {
1972 $base && ref $base
1973 or Carp::carp "normalise called with relative tile path and no base: '$path'";
1974
1975 my $uppth = $base->tile_path (cf::TILE_UP);
1976 $path = $uppth if $uppth;
1977
1978 } elsif ($path eq '!down') {
1979 $base && ref $base
1980 or Carp::carp "normalise called with relative tile path and no base: '$path'";
1981
1982 my $dpth = $base->tile_path (cf::TILE_DOWN);
1983 $path = $dpth if $dpth;
1984 } 1969 }
1985 1970
1986 for ($path) { 1971 for ($path) {
1987 redo if s{/\.?/}{/}; 1972 redo if s{/\.?/}{/};
1988 redo if s{/[^/]+/\.\./}{/}; 1973 redo if s{/[^/]+/\.\./}{/};
2084 $self->{load_path} = $path; 2069 $self->{load_path} = $path;
2085 2070
2086 1 2071 1
2087} 2072}
2088 2073
2074# used to laod the header of an original map
2089sub load_header_orig { 2075sub load_header_orig {
2090 my ($self) = @_; 2076 my ($self) = @_;
2091 2077
2092 $self->load_header_from ($self->load_path) 2078 $self->load_header_from ($self->load_path)
2093} 2079}
2094 2080
2081# used to laod the header of an instantiated map
2095sub load_header_temp { 2082sub load_header_temp {
2096 my ($self) = @_; 2083 my ($self) = @_;
2097 2084
2098 $self->load_header_from ($self->save_path) 2085 $self->load_header_from ($self->save_path)
2099} 2086}
2100 2087
2088# called after loading the header from an instantiated map
2101sub prepare_temp { 2089sub prepare_temp {
2102 my ($self) = @_; 2090 my ($self) = @_;
2103 2091
2104 $self->last_access ((delete $self->{last_access}) 2092 $self->last_access ((delete $self->{last_access})
2105 || $cf::RUNTIME); #d# 2093 || $cf::RUNTIME); #d#
2106 # safety 2094 # safety
2107 $self->{instantiate_time} = $cf::RUNTIME 2095 $self->{instantiate_time} = $cf::RUNTIME
2108 if $self->{instantiate_time} > $cf::RUNTIME; 2096 if $self->{instantiate_time} > $cf::RUNTIME;
2109} 2097}
2110 2098
2099# called after loading the header from an original map
2111sub prepare_orig { 2100sub prepare_orig {
2112 my ($self) = @_; 2101 my ($self) = @_;
2113 2102
2114 $self->{load_original} = 1; 2103 $self->{load_original} = 1;
2115 $self->{instantiate_time} = $cf::RUNTIME; 2104 $self->{instantiate_time} = $cf::RUNTIME;
2182 2171
2183 { 2172 {
2184 my $guard = cf::lock_acquire "map_data:$path"; 2173 my $guard = cf::lock_acquire "map_data:$path";
2185 2174
2186 return unless $self->valid; 2175 return unless $self->valid;
2187 return unless $self->in_memory == cf::MAP_SWAPPED; 2176 return unless $self->state == cf::MAP_SWAPPED;
2188
2189 $self->in_memory (cf::MAP_LOADING);
2190 2177
2191 $self->alloc; 2178 $self->alloc;
2192 2179
2193 $self->pre_load; 2180 $self->pre_load;
2194 cf::cede_to_tick; 2181 cf::cede_to_tick;
2212 } 2199 }
2213 } 2200 }
2214 } 2201 }
2215 2202
2216 $f->resolve_delayed_derefs; 2203 $f->resolve_delayed_derefs;
2204 } else {
2205 $self->post_load_original
2206 if delete $self->{load_original};
2217 } 2207 }
2208
2209 $self->state (cf::MAP_INACTIVE);
2218 2210
2219 cf::cede_to_tick; 2211 cf::cede_to_tick;
2220 # now do the right thing for maps 2212 # now do the right thing for maps
2221 $self->link_multipart_objects; 2213 $self->link_multipart_objects;
2222 $self->difficulty ($self->estimate_difficulty) 2214 $self->difficulty ($self->estimate_difficulty)
2226 unless ($self->{deny_activate}) { 2218 unless ($self->{deny_activate}) {
2227 $self->decay_objects; 2219 $self->decay_objects;
2228 $self->fix_auto_apply; 2220 $self->fix_auto_apply;
2229 $self->update_buttons; 2221 $self->update_buttons;
2230 cf::cede_to_tick; 2222 cf::cede_to_tick;
2231 $self->activate; 2223 #$self->activate; # no longer activate maps automatically
2232 } 2224 }
2233 2225
2234 $self->{last_save} = $cf::RUNTIME; 2226 $self->{last_save} = $cf::RUNTIME;
2235 $self->last_access ($cf::RUNTIME); 2227 $self->last_access ($cf::RUNTIME);
2236
2237 $self->in_memory (cf::MAP_ACTIVE);
2238 } 2228 }
2239 2229
2240 $self->post_load; 2230 $self->post_load;
2241 2231
2242 1 2232 1
2285} 2275}
2286 2276
2287sub find_sync { 2277sub find_sync {
2288 my ($path, $origin) = @_; 2278 my ($path, $origin) = @_;
2289 2279
2280 # it's a bug to call this from the main context
2290 return cf::LOG cf::llevError | cf::logBacktrace, "do_find_sync" 2281 return cf::LOG cf::llevError | cf::logBacktrace, "do_find_sync"
2291 if $Coro::current == $Coro::main; 2282 if $Coro::current == $Coro::main;
2292 2283
2293 find $path, $origin 2284 find $path, $origin
2294} 2285}
2295 2286
2296sub do_load_sync { 2287sub do_load_sync {
2297 my ($map) = @_; 2288 my ($map) = @_;
2298 2289
2290 # it's a bug to call this from the main context
2299 return cf::LOG cf::llevError | cf::logBacktrace, "do_load_sync" 2291 return cf::LOG cf::llevError | cf::logBacktrace, "do_load_sync"
2300 if $Coro::current == $Coro::main; 2292 if $Coro::current == $Coro::main;
2301 2293
2302 $map->load; 2294 $map->load;
2303} 2295}
2307 2299
2308sub find_async { 2300sub find_async {
2309 my ($path, $origin, $load) = @_; 2301 my ($path, $origin, $load) = @_;
2310 2302
2311 $path = normalise $path, $origin; 2303 $path = normalise $path, $origin;
2312 2304
2313 if (my $map = $cf::MAP{$path}) { 2305 if (my $map = $cf::MAP{$path}) {
2314 return $map if !$load || $map->in_memory == cf::MAP_ACTIVE; 2306 return $map if !$load || $map->linkable;
2315 } 2307 }
2316 2308
2317 $MAP_PREFETCH{$path} |= $load; 2309 $MAP_PREFETCH{$path} |= $load;
2318 2310
2319 $MAP_PREFETCHER ||= cf::async { 2311 $MAP_PREFETCHER ||= cf::async {
2378sub swap_out { 2370sub swap_out {
2379 my ($self) = @_; 2371 my ($self) = @_;
2380 2372
2381 my $lock = cf::lock_acquire "map_data:$self->{path}"; 2373 my $lock = cf::lock_acquire "map_data:$self->{path}";
2382 2374
2383 return if $self->in_memory != cf::MAP_ACTIVE; 2375 return if !$self->linkable;
2384 return if $self->{deny_save}; 2376 return if $self->{deny_save};
2385 return if $self->players; 2377 return if $self->players;
2386 2378
2387 # first deactivate the map and "unlink" it from the core 2379 # first deactivate the map and "unlink" it from the core
2388 $self->deactivate; 2380 $self->deactivate;
2389 $_->clear_links_to ($self) for values %cf::MAP; 2381 $_->clear_links_to ($self) for values %cf::MAP;
2390 $self->in_memory (cf::MAP_SWAPPED); 2382 $self->state (cf::MAP_SWAPPED);
2391 2383
2392 # then atomically save 2384 # then atomically save
2393 $self->_save; 2385 $self->_save;
2394 2386
2395 # then free the map 2387 # then free the map
2421 2413
2422 return if $self->players; 2414 return if $self->players;
2423 2415
2424 cf::trace "resetting map ", $self->path, "\n"; 2416 cf::trace "resetting map ", $self->path, "\n";
2425 2417
2426 $self->in_memory (cf::MAP_SWAPPED); 2418 $self->state (cf::MAP_SWAPPED);
2427 2419
2428 # need to save uniques path 2420 # need to save uniques path
2429 unless ($self->{deny_save}) { 2421 unless ($self->{deny_save}) {
2430 my $uniq = $self->uniq_path; utf8::encode $uniq; 2422 my $uniq = $self->uniq_path; utf8::encode $uniq;
2431 2423
2927 $Coro::current->{desc} = "enter_exit"; 2919 $Coro::current->{desc} = "enter_exit";
2928 2920
2929 unless (eval { 2921 unless (eval {
2930 $self->deactivate_recursive; # just to be sure 2922 $self->deactivate_recursive; # just to be sure
2931 2923
2932 # random map handling
2933 {
2934 my $guard = cf::lock_acquire "exit_prepare:$exit";
2935
2936 prepare_random_map $exit
2937 if $exit->slaying eq "/!";
2938 }
2939
2940 my $map = cf::map::normalise $exit->slaying, $exit->map; 2924 my $map = cf::map::normalise $exit->slaying, $exit->map;
2941 my $x = $exit->stats->hp; 2925 my $x = $exit->stats->hp;
2942 my $y = $exit->stats->sp; 2926 my $y = $exit->stats->sp;
2927
2928 # special map handling
2929 my $slaying = $exit->slaying;
2930
2931 # special map handling
2932 if ($slaying eq "/!") {
2933 my $guard = cf::lock_acquire "exit_prepare:$exit";
2934
2935 prepare_random_map $exit
2936 if $exit->slaying eq "/!"; # need to re-check after getting the lock
2937
2938 $map = $exit->slaying;
2939
2940 } elsif ($slaying eq '!up') {
2941 $map = $exit->map->tile_path (cf::TILE_UP);
2942 $x = $exit->x;
2943 $y = $exit->y;
2944
2945 } elsif ($slaying eq '!down') {
2946 $map = $exit->map->tile_path (cf::TILE_DOWN);
2947 $x = $exit->x;
2948 $y = $exit->y;
2949 }
2943 2950
2944 $self->goto ($map, $x, $y); 2951 $self->goto ($map, $x, $y);
2945 2952
2946 # if exit is damned, update players death & WoR home-position 2953 # if exit is damned, update players death & WoR home-position
2947 $self->contr->savebed ($map, $x, $y) 2954 $self->contr->savebed ($map, $x, $y)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines