--- deliantra/Deliantra-Client/DC/Main.pm 2012/01/04 11:23:23 1.8 +++ deliantra/Deliantra-Client/DC/Main.pm 2012/01/18 13:42:19 1.17 @@ -20,6 +20,7 @@ use common::sense; use Carp 'verbose'; use Cwd (); +use Digest::MD5 (); use EV; BEGIN { *time = \&EV::time } @@ -58,6 +59,7 @@ } use DC::OpenGL (); +use DC::Audio (); use DC::Protocol; use DC::DB; use DC::UI; @@ -197,7 +199,7 @@ $msg =~ s/\s+$//; # backtrace as second step, in case it crashes, too - crash Carp::longmess "$msg\nbacktrace, for client version $DC::VERSION, generated" + crash Carp::longmess "$msg\nbacktrace, for client version $DC::VERSION$Urlader::EXE_VER, generated" if $backtrace; }; @@ -209,7 +211,7 @@ return unless $CONN; $CONN->send_exti_msg (clientlog => $msg); - $CONN->send_exti_msg (clientlog => Carp::longmess "$msg\nbacktrace, for client version $DC::VERSION, generated") if $backtrace; + $CONN->send_exti_msg (clientlog => Carp::longmess "$msg\nbacktrace, for client version $DC::VERSION$Urlader::EXE_VER, generated") if $backtrace; } ############################################################################# @@ -474,25 +476,9 @@ sub audio_init { if ($CFG->{audio_enable}) { - if (length $CFG->{audio_driver}) { - local $ENV{SDL_AUDIODRIVER} = $CFG->{audio_driver}; - DC::SDL_Init DC::SDL_INIT_AUDIO - and die "SDL::Init failed!\n"; - } else { - DC::SDL_Init DC::SDL_INIT_AUDIO - and die "SDL::Init failed!\n"; - } - - $ENV{MIX_EFFECTSMAXSPEED} = 1; - $SDL_MIXER = !DC::Mix_OpenAudio - $CFG->{audio_hw_frequency}, - DC::MIX_DEFAULT_FORMAT, - $CFG->{audio_hw_channels}, - $CFG->{audio_hw_chunksize}; + DC::Audio::init $CFG->{audio_driver}; if ($SDL_MIXER) { - DC::Mix_AllocateChannels $CFG->{audio_mix_channels}; - audio_music_finished; } else { status "Unable to open sound device: there will be no sound"; @@ -529,15 +515,8 @@ ############################################################################# # Over-the-air updates -sub ota_update_finish { - $MESSAGE_DIST->message ({ type => "ota_update", markup => $_[0] }); -} - -sub ota_update_status { -} - sub ota_update { - my ($face, $size) = @_; + my ($face, $size, $md5) = @_; my $coro = Coro::async_pool { my $override = "$Urlader::EXE_DIR/override"; @@ -553,7 +532,7 @@ my $fh = Coro::AIO::aio_open "$override.tmp", IO::AIO::O_WRONLY | IO::AIO::O_CREAT | IO::AIO::O_TRUNC, 0777; unless ($fh) { - ota_update_finish "unable to write software update:\n$Urlader::EXE_DIR/override.tmp:\n$!"; + $MESSAGE_DIST->message ({ type => "ota_update", markup => (DC::asxml "unable to write software update:\n$Urlader::EXE_DIR/override.tmp:\n$!") }); return; } @@ -563,7 +542,6 @@ my $error; $cv->begin (Coro::rouse_cb); - $CONN->ask_face ( $face, -1000, @@ -598,6 +576,30 @@ return; } + { + $MESSAGE_DIST->message ({ type => "ota_update", markup => "verifying update file..." }); + + my $fh = Coro::AIO::aio_open "$override.tmp", IO::AIO::O_RDONLY, 0; + + if ($fh) { + $error ||= Coro::AIO::aio_stat "$override.tmp"; + $error ||= -s _ != $size; + Coro::AIO::aio_readahead $fh, 0, $size; + + my $f_md5 = new Digest::MD5; + binmode $fh; # ugh :( + $f_md5->addfile ($fh); + $f_md5 = $f_md5->hexdigest; + $error ||= $md5 ne $f_md5; + } + } + + if ($error) { + $MESSAGE_DIST->message ({ type => "ota_update", markup => "verification failed, update aborted." }); + Coro::AIO::aio_unlink "$override.tmp"; + return; + } + $MESSAGE_DIST->message ({ type => "ota_update", markup => "replacing override file..." }); if (Coro::AIO::aio_rename "$override.tmp", $override) { @@ -605,7 +607,7 @@ Coro::AIO::aio_unlink "$override.tmp"; } - $MESSAGE_DIST->message ({ type => "ota_update", markup => "update successfull, changes become active at next start." }); + $MESSAGE_DIST->message ({ type => "ota_update", markup => "success - update becomes active after restarting." }); }; $CONN->{ota_update} = Guard::guard { @@ -614,15 +616,16 @@ } sub ota_update_ask { - my ($ok, $face, $ver, $size, $changes) = @_; + my ($ok, $face, $ver, $size, $md5, $changes) = @_; $CONN->{w}{ota_dialog} = my $dialog = new DC::UI::Toplevel - x => "center", - y => "center", - max_w => $::WIDTH * 0.7, - max_h => $::WIDTH * 0.7, - title => "Software update available", - child => my $vbox = new DC::UI::VBox, + x => "center", + y => "center", + z => 55, + force_w => $::WIDTH * 0.7, + force_h => $::HEIGHT * 0.7, + title => "Software update available", + child => my $vbox = new DC::UI::VBox, ; $vbox->add (new DC::UI::Label @@ -633,13 +636,14 @@ $vbox->add (new DC::UI::FancyFrame expand => 1, - label => "Changes", + label => "Details", child => (new DC::UI::TextScroller expand => 1, fontsize => 0.8, padding_x => 4, padding_y => 4, par => [{ markup => "Old revision: $Urlader::EXE_VER\n" . "New revision: $ver\n" . "Download size: $size bytes\n\n" + . "Changes:\n\n" . DC::asxml $changes }], ), @@ -660,7 +664,7 @@ text => "Yes, start downloading", on_activate => sub { $dialog->destroy; - ota_update $face, $size; + ota_update $face, $size, $md5; 0 }, ); @@ -674,7 +678,7 @@ ::message { markup => "Checking for software update..." }; $CONN->send_exti_req (ota_update => $Urlader::URLADER_VERSION, $Urlader::EXE_ID, $Urlader::EXE_VER, sub { - my ($ok, $face, $ver, $size, $changes) = @_; + my ($ok, $face, $ver, $size, $md5, $changes) = @_; if ($ok) { if (defined $ver) { @@ -948,7 +952,7 @@ c_version => { client => "deliantra", - clientver => $DC::VERSION, + clientver => "$DC::VERSION$Urlader::EXE_VER", gl_vendor => DC::OpenGL::gl_vendor, gl_version => DC::OpenGL::gl_version, }, @@ -2012,7 +2016,7 @@ tooltip => "Use this to manually save configuration and UI layout when " . "autosave is disabled.", on_activate => sub { - DC::write_cfg; + DC::save_cfg; 0 } ); @@ -2455,7 +2459,7 @@ $QUIT_DIALOG = new DC::UI::Toplevel x => "center", y => "center", - z => 50, + z => 60, title => "Really Quit?", on_key_down => sub { my ($dialog, $ev) = @_; @@ -2682,6 +2686,8 @@ $FULLSCREEN = $CFG->{fullscreen}; $FAST = $CFG->{fast}; + DC::SDL_WM_SetCaption "Deliantra MORPG Client $DC::VERSION$Urlader::EXE_VER", "Deliantra"; # must be after SDL_Init + # due to mac os x braindamage, we simply retry with !fullscreen in case of an error DC::SDL_SetVideoMode $WIDTH, $HEIGHT, $rgb, $alpha, $FULLSCREEN or DC::SDL_SetVideoMode $WIDTH, $HEIGHT, $rgb, $alpha, !$FULLSCREEN @@ -2952,13 +2958,7 @@ { DC::Pod::load_docwiki DC::find_rcfile "docwiki.pst"; - if (-e "$Deliantra::VARDIR/client.cf") { - DC::read_cfg "$Deliantra::VARDIR/client.cf"; - } else { - #TODO: compatibility cruft - DC::read_cfg "$Deliantra::OLDDIR/cfplusrc"; - print STDERR "INFO: used old configuration file\n"; - } + DC::load_cfg; DC::DB::Server::run; @@ -2966,59 +2966,15 @@ warn "INFO: upgrading database schema from 0 to 1, mapcache and tilecache will be lost\n"; DC::DB::nuke_db; $CFG->{db_schema} = 1; - DC::write_cfg; + DC::save_cfg; } + DC::upgrade_cfg; + DC::DB::open_db; DC::UI::set_layout ($::CFG->{layout}); - my %DEF_CFG = ( - config_autosave => 1, - sdl_mode => undef, - fullscreen => 1, - fast => 0, - force_opengl11 => undef, - disable_alpha => 0, - smooth_movement => 1, - smooth_transitions => 1, - texture_compression => 1, - map_scale => 1, - fow_enable => 1, - fow_intensity => 0, - fow_texture => 0, - map_smoothing => 1, - gui_fontsize => 1, - log_fontsize => 0.7, - gauge_fontsize => 1, - gauge_size => 0.35, - stat_fontsize => 0.7, - mapsize => 100, - audio_enable => 1, - audio_hw_channels => 0, - audio_hw_frequency => 0, - audio_hw_chunksize => 0, - audio_mix_channels => 8, - effects_enable => 1, - effects_volume => 1, - bgm_enable => 1, - bgm_volume => 0.5, - output_rate => "", - pickup => PICKUP_SPELLBOOK | PICKUP_SKILLSCROLL | PICKUP_VALUABLES, - inv_sort => "mtime", - default => "profile", # default profile - show_tips => 1, - logview_max_par => 1000, - shift_fire_stop => 0, - uitheme => "wood", - map_shift_x => -24, # arbitrary - map_shift_y => +24, # arbitrary - ); - - while (my ($k, $v) = each %DEF_CFG) { - $CFG->{$k} = $v unless exists $CFG->{$k}; - } - my @args = @ARGV; # OS X passes some process serial number of other shit. they @@ -3118,7 +3074,7 @@ delete $SIG{__DIE__}; EV::loop; - DC::write_cfg if $CFG->{config_autosave}; + DC::save_cfg if $CFG->{config_autosave}; #video_shutdown; #audio_shutdown;