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.167 by root, Wed Dec 26 19:11:09 2007 UTC vs.
Revision 1.200 by root, Sun Jan 4 10:22:19 2009 UTC

1=head1 NAME 1=head1 NAME
2 2
3CFPlus - undocumented utility garbage for our crossfire client 3DC - undocumented utility garbage for our deliantra client
4 4
5=head1 SYNOPSIS 5=head1 SYNOPSIS
6 6
7 use CFPlus; 7 use DC;
8 8
9=head1 DESCRIPTION 9=head1 DESCRIPTION
10 10
11=over 4 11=over 4
12 12
13=cut 13=cut
14 14
15package CFPlus; 15package DC;
16 16
17use Carp (); 17use Carp ();
18 18
19our $VERSION;
20
19BEGIN { 21BEGIN {
20 $VERSION = '0.9962'; 22 $VERSION = '2.02';
21 23
22 use XSLoader; 24 use XSLoader;
23 XSLoader::load "CFPlus", $VERSION; 25 XSLoader::load "Deliantra::Client", $VERSION;
24} 26}
25 27
26use utf8; 28use utf8;
29use strict qw(vars subs);
27 30
31use Socket ();
28use AnyEvent (); 32use AnyEvent ();
33use AnyEvent::Util ();
29use Pod::POM (); 34use Pod::POM ();
30use File::Path (); 35use File::Path ();
31use Storable (); # finally 36use Storable (); # finally
32use Fcntl (); 37use Fcntl ();
33use JSON::XS qw(encode_json decode_json); 38use JSON::XS qw(encode_json decode_json);
37Returns an object that executes the given block as soon as it is destroyed. 42Returns an object that executes the given block as soon as it is destroyed.
38 43
39=cut 44=cut
40 45
41sub guard(&) { 46sub guard(&) {
42 bless \(my $cb = $_[0]), "CFPlus::Guard" 47 bless \(my $cb = $_[0]), "DC::Guard"
43} 48}
44 49
45sub CFPlus::Guard::DESTROY { 50sub DC::Guard::DESTROY {
46 ${$_[0]}->() 51 ${$_[0]}->()
47} 52}
48 53
49=item shorten $string[, $maxlength] 54=item shorten $string[, $maxlength]
50 55
64 s/</&lt;/g; 69 s/</&lt;/g;
65 70
66 $_ 71 $_
67} 72}
68 73
69sub socketpipe() {
70 socketpair my $fh1, my $fh2, Socket::AF_UNIX, Socket::SOCK_STREAM, Socket::PF_UNSPEC
71 or die "cannot establish bidirectional pipe: $!\n";
72
73 ($fh1, $fh2)
74}
75
76sub background(&;&) { 74sub background(&;&) {
77 my ($bg, $cb) = @_; 75 my ($bg, $cb) = @_;
78 76
79 my ($fh_r, $fh_w) = CFPlus::socketpipe; 77 my ($fh_r, $fh_w) = AnyEvent::Util::portable_socketpair
78 or die "unable to create background socketpair: $!";
80 79
81 my $pid = fork; 80 my $pid = fork;
82 81
83 if (defined $pid && !$pid) { 82 if (defined $pid && !$pid) {
84 local $SIG{__DIE__}; 83 local $SIG{__DIE__};
94 93
95 if ($@) { 94 if ($@) {
96 my $msg = $@; 95 my $msg = $@;
97 $msg =~ s/\n+/\n/; 96 $msg =~ s/\n+/\n/;
98 warn "FATAL: $msg"; 97 warn "FATAL: $msg";
99 CFPlus::_exit 1; 98 DC::_exit 1;
100 } 99 }
101 100
102 # win32 is fucked up, of course. exit will clean stuff up, 101 # win32 is fucked up, of course. exit will clean stuff up,
103 # which destroys our database etc. _exit will exit ALL 102 # which destroys our database etc. _exit will exit ALL
104 # forked processes, because of the dreaded fork emulation. 103 # forked processes, because of the dreaded fork emulation.
105 CFPlus::_exit 0; 104 DC::_exit 0;
106 } 105 }
107 106
108 close $fh_w; 107 close $fh_w;
109 108
110 my $buffer; 109 my $buffer;
122 utf8::decode $line; 121 utf8::decode $line;
123 if ($line =~ /^\x{e877}json_msg (.*)$/s) { 122 if ($line =~ /^\x{e877}json_msg (.*)$/s) {
124 $cb->(JSON::XS->new->allow_nonref->decode ($1)); 123 $cb->(JSON::XS->new->allow_nonref->decode ($1));
125 } else { 124 } else {
126 ::message ({ 125 ::message ({
127 markup => "background($pid): " . CFPlus::asxml $line, 126 markup => "background($pid): " . DC::asxml $line,
128 }); 127 });
129 } 128 }
130 } 129 }
131 }); 130 });
132} 131}
138 $msg =~ s/\n//g; 137 $msg =~ s/\n//g;
139 utf8::encode $msg; 138 utf8::encode $msg;
140 print $msg, "\n"; 139 print $msg, "\n";
141} 140}
142 141
143package CFPlus; 142package DC;
143
144our $RC_THEME;
145our %THEME;
146our @RC_PATH;
147our $RC_BASE;
148
149for (grep !ref, @INC) {
150 $RC_BASE = "$_/Deliantra/Client/private/resources";
151 last if -d $RC_BASE;
152}
144 153
145sub find_rcfile($) { 154sub find_rcfile($) {
146 my $path; 155 my $path;
147 156
148 for (grep !ref, @INC) { 157 for (@RC_PATH, "") {
149 $path = "$_/CFPlus/resources/$_[0]"; 158 $path = "$RC_BASE/$_/$_[0]";
150 return $path if -r $path; 159 return $path if -r $path;
151 } 160 }
152 161
153 die "FATAL: can't find required file $_[0]\n"; 162 die "FATAL: can't find required file \"$_[0]\" in \"$RC_BASE\"\n";
163}
164
165sub load_json($) {
166 my ($file) = @_;
167
168 open my $fh, $file
169 or return;
170
171 local $/;
172 JSON::XS->new->utf8->relaxed->decode (<$fh>)
173}
174
175sub set_theme($) {
176 return if $RC_THEME eq $_[0];
177 $RC_THEME = $_[0];
178
179 # kind of hacky, find the main theme file, then load all theme files and merge them
180
181 %THEME = ();
182 @RC_PATH = "theme-$RC_THEME";
183
184 my $theme = load_json find_rcfile "theme.json"
185 or die "FATAL: theme resource file not found";
186
187 @RC_PATH = @{ $theme->{path} } if $theme->{path};
188
189 for (@RC_PATH, "") {
190 my $theme = load_json "$RC_BASE/$_/theme.json"
191 or next;
192
193 %THEME = ( %$theme, %THEME );
194 }
154} 195}
155 196
156sub read_cfg { 197sub read_cfg {
157 my ($file) = @_; 198 my ($file) = @_;
158 199
159 open my $fh, $file 200 $::CFG = load_json $file;
160 or return;
161
162 local $/;
163 my $CFG = <$fh>;
164
165 $::CFG = decode_json $CFG;
166} 201}
167 202
168sub write_cfg { 203sub write_cfg {
169 my ($file) = @_; 204 my $file = "$Deliantra::VARDIR/client.cf";
170 205
171 $::CFG->{VERSION} = $::VERSION; 206 $::CFG->{VERSION} = $::VERSION;
172 207
173 open my $fh, ">:utf8", $file 208 open my $fh, ">:utf8", $file
174 or return; 209 or return;
175 print $fh encode_json $::CFG; 210 print $fh JSON::XS->new->utf8->pretty->encode ($::CFG);
176} 211}
177 212
178sub http_proxy { 213sub http_proxy {
179 my @proxy = win32_proxy_info; 214 my @proxy = win32_proxy_info;
180 215
195} 230}
196 231
197sub lwp_useragent { 232sub lwp_useragent {
198 require LWP::UserAgent; 233 require LWP::UserAgent;
199 234
200 CFPlus::set_proxy; 235 DC::set_proxy;
201 236
202 my $ua = LWP::UserAgent->new ( 237 my $ua = LWP::UserAgent->new (
203 agent => "cfplus $VERSION", 238 agent => "deliantra $VERSION",
204 keep_alive => 1, 239 keep_alive => 1,
205 env_proxy => 1, 240 env_proxy => 1,
206 timeout => 30, 241 timeout => 30,
207 ); 242 );
208} 243}
223 $nb = (! ! $nb) + 0; 258 $nb = (! ! $nb) + 0;
224 ioctl $fh, 0x8004667e, \$nb; # FIONBIO 259 ioctl $fh, 0x8004667e, \$nb; # FIONBIO
225 } else { 260 } else {
226 fcntl $fh, &Fcntl::F_SETFL, $nb ? &Fcntl::O_NONBLOCK : 0; 261 fcntl $fh, &Fcntl::F_SETFL, $nb ? &Fcntl::O_NONBLOCK : 0;
227 } 262 }
228
229} 263}
230 264
231package CFPlus::Layout; 265package DC::Layout;
232 266
233$CFPlus::OpenGL::INIT_HOOK{"CFPlus::Layout"} = sub { 267$DC::OpenGL::INIT_HOOK{"DC::Layout"} = sub {
234 glyph_cache_restore; 268 glyph_cache_restore;
235}; 269};
236 270
237$CFPlus::OpenGL::SHUTDOWN_HOOK{"CFPlus::Layout"} = sub { 271$DC::OpenGL::SHUTDOWN_HOOK{"DC::Layout"} = sub {
238 glyph_cache_backup; 272 glyph_cache_backup;
239}; 273};
240 274
2411; 2751;
242 276

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines