ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/kgsueme/kgsueme/game.pl
(Generate patch)

Comparing kgsueme/kgsueme/game.pl (file contents):
Revision 1.84 by pcg, Thu May 20 23:09:53 2004 UTC vs.
Revision 1.98 by pcg, Sun May 30 02:22:24 2004 UTC

18 my $self = shift; 18 my $self = shift;
19 19
20 $self->signal_connect (destroy => sub { $_[0]->stop }); 20 $self->signal_connect (destroy => sub { $_[0]->stop });
21 21
22 $self->{set} = sub { }; 22 $self->{set} = sub { };
23 $self->{format} = sub { "ERROR" }; 23 $self->{format} = sub { "???" };
24} 24}
25 25
26sub configure { 26sub configure {
27 my ($self, $timesys, $main, $interval, $count) = @_; 27 my ($self, $timesys, $main, $interval, $count) = @_;
28 28
185 185
186use KGS::Constants; 186use KGS::Constants;
187use KGS::Game::Board; 187use KGS::Game::Board;
188 188
189use Gtk2::GoBoard; 189use Gtk2::GoBoard;
190use Gtk2::GoBoard::Constants;
190 191
191use Glib::Object::Subclass 192use Glib::Object::Subclass
192 Gtk2::Window; 193 Gtk2::Window;
193 194
194use base KGS::Listener::Game; 195use base KGS::Listener::Game;
196 197
197use POSIX qw(ceil); 198use POSIX qw(ceil);
198 199
199sub new { 200sub new {
200 my ($self, %arg) = @_; 201 my ($self, %arg) = @_;
201
202 $self = $self->Glib::Object::new; 202 $self = $self->Glib::Object::new;
203 $self->{$_} = delete $arg{$_} for keys %arg; 203 $self->{$_} = delete $arg{$_} for keys %arg;
204 204
205 $self->listen ($self->{conn});
206
207 gtk::state $self, "game::window", undef, window_size => [600, 500]; 205 gtk::state $self, "game::window", undef, window_size => [600, 500];
208 206
209 $self->signal_connect (delete_event => sub { $self->part; 1 });
210 $self->signal_connect (destroy => sub { %{$_[0]} = () }); 207 $self->signal_connect (destroy => sub {
208 $self->unlisten;
209 delete $self->{app}{game}{$self->{channel}};
210 %{$_[0]} = ();
211 });#d#
211 212
212 $self->add (my $hpane = new Gtk2::HPaned); 213 $self->add (my $hpane = new Gtk2::HPaned);
213 gtk::state $hpane, "game::hpane", undef, position => 500; 214 gtk::state $hpane, "game::hpane", undef, position => 500;
214 215
215 # LEFT PANE 216 # LEFT PANE
218 219
219 $self->{boardbox} = new Gtk2::VBox; 220 $self->{boardbox} = new Gtk2::VBox;
220 221
221 $hpane->pack1((my $vbox = new Gtk2::VBox), 1, 1); 222 $hpane->pack1((my $vbox = new Gtk2::VBox), 1, 1);
222 223
223 # challenge
224
225 $self->{challenge} = new challenge channel => $self->{channel};
226
227 # board box (aspect/canvas) 224 # board box (aspect/canvas)
228 225
229 $self->{boardbox}->pack_start((my $frame = new Gtk2::Frame), 0, 1, 0); 226 #$self->{boardbox}->pack_start((my $frame = new Gtk2::Frame), 0, 1, 0);
227
228 # RIGHT PANE
229
230 $hpane->pack2 ((my $vbox = new Gtk2::VBox), 1, 1);
231 $hpane->set (position_set => 1);
232
233 $vbox->pack_start ((my $frame = new Gtk2::Frame), 0, 1, 0);
230 234
231 { 235 {
232 $frame->add (my $vbox = new Gtk2::VBox); 236 $frame->add (my $vbox = new Gtk2::VBox);
233 $vbox->add ($self->{title} = new Gtk2::Label $title); 237 $vbox->add ($self->{title} = new Gtk2::Label $title);
234 238
243 $scale->set_digits (0); 247 $scale->set_digits (0);
244 248
245 $self->{moveadj}->signal_connect (value_changed => sub { $self->update_board }); 249 $self->{moveadj}->signal_connect (value_changed => sub { $self->update_board });
246 } 250 }
247 251
248 $self->{boardbox}->add ($self->{board} = new Gtk2::GoBoard size => $self->{size});
249
250 # RIGHT PANE
251
252 $hpane->pack2 (($self->{vpane} = new Gtk2::VPaned), 1, 1);
253 $hpane->set (position_set => 1);
254 gtk::state $self->{vpane}, "game::vpane", $self->{name}, position => 80;
255
256 $self->{vpane}->add (my $sw = new Gtk2::ScrolledWindow);
257 $sw->set_policy ("automatic", "always");
258
259 $sw->add ($self->{userlist} = new userlist);
260
261 $self->{vpane}->add (my $vbox = new Gtk2::VBox);
262
263 $vbox->pack_start ((my $hbox = new Gtk2::HBox 1), 0, 1, 0); 252 $vbox->pack_start ((my $hbox = new Gtk2::HBox 1), 0, 1, 0);
264 253
265 $hbox->add ($self->{userpanel}[$_] = new game::userpanel colour => $_) 254 $hbox->add ($self->{userpanel}[$_] = new game::userpanel colour => $_)
266 for COLOUR_WHITE, COLOUR_BLACK; 255 for COLOUR_WHITE, COLOUR_BLACK;
267 256
268 $vbox->pack_start (($self->{chat} = new chat), 1, 1, 0); 257 $vbox->pack_start (($self->{chat} = new superchat), 1, 1, 0);
269 weaken $self->{chat};
270 258
271 $self->{chat}->signal_connect (command => sub { 259 $self->set_channel ($self->{channel});
272 my ($chat, $cmd, $arg) = @_; 260
273 if ($cmd eq "rsave") { 261 $self->show_all;
274 Storable::nstore { tree => $self->{tree}, curnode => $self->{curnode}, move => $self->{move} }, $arg;#d#
275 } else {
276 $self->{app}->do_command ($chat, $cmd, $arg, userlist => $self->{userlist}, game => $self);
277 }
278 });
279 262
280 $self; 263 $self;
264}
265
266sub set_channel {
267 my ($self, $channel) = @_;
268
269 $self->{channel} = $channel;
270
271 if ($self->{channel} > 0) {
272 $self->listen ($self->{conn});
273
274 $self->{rules_inlay} = $self->{chat}->new_switchable_inlay ("Game Setup:", sub { $self->draw_setup (@_) }, 1);
275 $self->{users_inlay} = $self->{chat}->new_switchable_inlay ("Users:", sub { $self->draw_users (@_) }, 1);
276
277 $self->signal_connect (delete_event => sub { $self->part; 1 });
278 $self->{chat}->signal_connect (command => sub {
279 my ($chat, $cmd, $arg) = @_;
280 if ($cmd eq "rsave") {
281 Storable::nstore { tree => $self->{tree}, curnode => $self->{curnode}, move => $self->{move} }, $arg;#d#
282 } else {
283 $self->{app}->do_command ($chat, $cmd, $arg, userlist => $self->{userlist}, game => $self);
284 }
285 });
286 }
281} 287}
282 288
283sub event_update_users { 289sub event_update_users {
284 my ($self, $add, $update, $remove) = @_; 290 my ($self, $add, $update, $remove) = @_;
285 291
286 return unless $self->{userlist};
287
288 $self->{userlist}->update ($add, $update, $remove); 292# $self->{userlist}->update ($add, $update, $remove);
293
294 $self->{challenge}{$_->{name}} && (delete $self->{challenge}{$_->{name}})->{inlay}->destroy
295 for @$remove;
296
297 $self->{users_inlay}->refresh;
289 298
290 my %important; 299 my %important;
300 $important{$self->{black}{name}}++;
301 $important{$self->{white}{name}}++;
291 $important{$self->{user1}{name}}++; 302 $important{$self->{owner}{name}}++;
292 $important{$self->{user2}{name}}++;
293 $important{$self->{user3}{name}}++;
294 303
295 if (my @users = grep $important{$_->{name}}, @$add) { 304 if (my @users = grep $important{$_->{name}}, @$add) {
296 $self->{chat}->append_text ("\n<header>Joins:</header>"); 305 $self->{chat}->append_text ("\n<header>Joins:</header>");
297 $self->{chat}->append_text (" <user>" . $_->as_string . "</user>") for @users; 306 $self->{chat}->append_text (" <user>" . $_->as_string . "</user>") for @users;
298 } 307 }
299 if (my @users = grep $important{$_->{name}}, @$remove) { 308 if (my @users = grep $important{$_->{name}}, @$remove) {
300 $self->{chat}->append_text ("\n<header>Parts:</header>"); 309 $self->{chat}->append_text ("\n<header>Parts:</header>");
301 $self->{chat}->append_text (" <user>" . $_->as_string . "</user>") for @users; 310 $self->{chat}->append_text (" <user>" . $_->as_string . "</user>") for @users;
302 } 311 }
303
304} 312}
305 313
306sub join { 314sub join {
307 my ($self) = @_; 315 my ($self) = @_;
308 return if $self->{joined}; 316 return if $self->{joined};
309 317
310 $self->SUPER::join; 318 $self->SUPER::join;
319}
311 320
312 $self->show_all; 321sub update_cursor {
322 my ($self) = @_;
323
324 my $move = int $self->{moveadj}->get_value;
325 my $cb;
326
327 my $running = $move == @{$self->{path}}
328 && $self->is_active;
329
330 warn "plaiyng $self->{playing} running $running teach $self->{teacher}\n";
331 warn !($self->{playing} && $running);
332 warn $self->{teacher} ne $self->{app}{conn};
333 if (!($self->{playing} && $running) && $self->{teacher} ne $self->{app}{conn}) {
334 warn "A\n";
335 $self->{board}->set (cursor_mask => 0, cursor_value => 0);
336 } elsif ($self->{black}{name} eq $self->{conn}{name}) {
337 warn "B\n";
338 $self->{board}->set (cursor_mask => MARK_B | MARK_W, cursor_value => MARK_B | MARK_GRAYED);
339 $cb = sub {
340 $self->send (upd_tree =>
341 channel => $self->{channel},
342 tree => $self->gen_move_tree (COLOUR_BLACK, $_[0], $_[1]),
343 );
344 };
345 } elsif ($self->{white}{name} eq $self->{conn}{name}) {
346 warn "C\n";
347 $self->{board}->set (cursor_mask => MARK_B | MARK_W, cursor_value => MARK_W | MARK_GRAYED);
348 $cb = sub {
349 $self->send (upd_tree =>
350 channel => $self->{channel},
351 tree => $self->gen_move_tree (COLOUR_WHITE, $_[0], $_[1]),
352 );
353 };
354 }
355
356 $self->{board_click} = $cb;
313} 357}
314 358
315sub update_board { 359sub update_board {
316 my ($self) = @_; 360 my ($self) = @_;
317 return unless $self->{path}; 361 return unless $self->{path};
318 362
319 my $move = int $self->{moveadj}->get_value; 363 my $move = int $self->{moveadj}->get_value;
320 364
321 my $running = $move == @{$self->{path}}; 365 my $running = $move == @{$self->{path}}
366 && !$self->{teacher}
367 && $self->is_active;
322 368
323 $self->{board_label}->set_text ("Move " . ($move - 1)); 369 $self->{board_label}->set_text ("Move " . ($move - 1));
324 370
325 $self->{cur_board} = new KGS::Game::Board $self->{size}; 371 $self->{cur_board} = new KGS::Game::Board $self->{size};
326 $self->{cur_board}->interpret_path ([@{$self->{path}}[0 .. $move - 1]]); 372 $self->{cur_board}->interpret_path ([@{$self->{path}}[0 .. $move - 1]]);
333 ? $self->{lastmove_time} : 0 379 ? $self->{lastmove_time} : 0
334 ); 380 );
335 } 381 }
336 382
337 $self->{board}->set_board ($self->{cur_board}); 383 $self->{board}->set_board ($self->{cur_board});
384
385 $self->update_cursor;
338} 386}
339 387
340sub event_update_tree { 388sub event_update_tree {
341 my ($self) = @_; 389 my ($self) = @_;
342 390
396 444
397sub event_join { 445sub event_join {
398 my ($self) = @_; 446 my ($self) = @_;
399 447
400 $self->SUPER::event_join (@_); 448 $self->SUPER::event_join (@_);
449 $self->init_tree;
401 $self->event_update_game; 450 $self->event_update_game;
402} 451}
403 452
404sub event_part { 453sub event_part {
405 my ($self) = @_; 454 my ($self) = @_;
409} 458}
410 459
411sub event_move { 460sub event_move {
412 my ($self, $pass) = @_; 461 my ($self, $pass) = @_;
413 sound::play 1, $pass ? "pass" : "move"; 462 sound::play 1, $pass ? "pass" : "move";
463
464 if ($self->{undo_inlay}) {
465 (delete $self->{undo_inlay})->clear;
466 }
414} 467}
415 468
416sub event_update_game { 469sub event_update_game {
417 my ($self) = @_; 470 my ($self) = @_;
471
418 $self->SUPER::event_update_game; 472 $self->SUPER::event_update_game;
419 473
420 return unless $self->{joined}; 474 return unless $self->{joined};
421 475
476 $self->{playing} = $self->{teacher} eq $self->{conn}{name}
477 || $self->is_playing ($self->{conn}{name});
478
422 my $title = defined $self->{channel} 479 my $title = defined $self->{channel}
423 ? $self->owner->as_string . " " . $self->opponent_string 480 ? $self->owner->as_string . " " . $self->opponent_string
424 : "Game Window"; 481 : "Game Window";
425 $self->set_title("KGS Game $title"); 482 $self->set_title("KGS Game $title");
426 $self->{title}->set_text ($title); 483 $self->{title}->set_text ($title);
427 484
428 $self->{user}[COLOUR_BLACK] = $self->{user1}; 485 $self->{user}[COLOUR_BLACK] = $self->{black};
429 $self->{user}[COLOUR_WHITE] = $self->{user2}; 486 $self->{user}[COLOUR_WHITE] = $self->{white};
430 487
431 # show board 488 # show board
489 if ($self->is_inprogress) {
490 if (!$self->{boardbox}->parent) {
491 $self->{boardbox}->add ($self->{board} = new Gtk2::GoBoard size => $self->{size});
492 $self->{left}->add ($self->{boardbox});
493 $self->{board}->signal_connect (button_release => sub {
494 warn "XXX @_\n";#d#
495 if ($_[1] == 1) {
496 $self->{board_click}->($_[2], $_[3]) if $self->{board_click};
497 }
498 });
499 }
500 if (my $ch = delete $self->{challenge}) {
501 $_->{inlay}->destroy for values %$ch;
502 }
503 $self->update_cursor;
504 }
505
506 $self->{left}->show_all;
507
508 $self->{rules_inlay}->refresh;
432 509
510}
511
512sub draw_setup {
513 my ($self, $inlay) = @_;
514
515 return unless $self->{joined};
516
517 my $rules = $self->{rules};
518
519 my $text = "";
520
521 $text .= "\nTeacher: <user>" . (util::toxml $self->{teacher}) . "</user>"
522 if $self->{teacher};
523
524 $text .= "\nOwner: <user>" . (util::toxml $self->{owner}->as_string) . "</user>"
525 if $self->{owner}->is_valid;
526
433 if ($self->is_inprogress) { 527 if ($self->is_inprogress) {
434 $self->{left}->remove ($self->{challenge}->widget) if $self->{challenge} && $self->{boardbox}->parent;
435 $self->{left}->add ($self->{boardbox}) unless $self->{boardbox}->parent;
436 } else {
437 $self->{left}->remove ($self->{boardbox}) if $self->{boardbox}->parent;
438 $self->{left}->add ($self->{challenge}->widget) unless $self->{challenge}->widget->parent;
439 }
440 $self->{left}->show_all;
441
442 # view text
443
444 eval { #d#
445 my @ga;
446 $ga[0] = "\nType: " . (util::toxml $gametype{$self->type})
447 . " (" . (util::toxml $gameopt{$self->option}) . ")";
448 $ga[1] = "\nFlags:";
449 $ga[1] .= " started" if $self->is_inprogress;
450 $ga[1] .= " adjourned" if $self->is_adjourned;
451 $ga[1] .= " scored" if $self->is_scored;
452 $ga[1] .= " saved" if $self->is_saved;
453
454 $ga[2] = "\nOwner: <user>" . (util::toxml $self->{user3}->as_string) . "</user>"
455 if $self->{user3}->is_inprogress;
456
457 $ga[3] = "\nPlayers: <user>" . (util::toxml $self->{user2}->as_string) . "</user>" 528 $text .= "\nPlayers: <user>" . (util::toxml $self->{white}->as_string) . "</user>"
458 . " vs. <user>" . (util::toxml $self->{user1}->as_string) . "</user>" 529 . " vs. <user>" . (util::toxml $self->{black}->as_string) . "</user>";
459 if $self->is_inprogress;
460
461 if ($self->is_inprogress) {
462 $ga[4] = "\nHandicap: " . $self->{handicap};
463 $ga[5] = "\nKomi: " . $self->{komi};
464 $ga[6] = "\nSize: " . $self->size_string;
465 }
466
467 if ($self->is_scored) {
468 $ga[7] = "\nResult: " . $self->score_string;
469 }
470
471 $text = "\n<infoblock><header>Game Update</header>";
472 for (0..7) {
473 if ($self->{gatext}[$_] ne $ga[$_]) {
474 $text .= $ga[$_];
475 }
476 }
477 $text .= "</infoblock>";
478
479 $self->{gatext} = \@ga;
480 }; 530 }
481 531 $text .= "\nType: " . util::toxml $gametype{$self->type};
482 $self->{chat}->append_text ($text);
483}
484
485sub event_update_rules {
486 my ($self, $rules) = @_;
487
488 if ($self->{user}) {
489 $self->{userpanel}[$_]->configure ($self->{app}, $self->{user}[$_], $rules)
490 for COLOUR_BLACK, COLOUR_WHITE;
491 }
492
493 sound::play 3, "gamestart";
494
495 my $text = "\n<header>Game Rules</header>";
496 532
497 $text .= "\nRuleset: " . $ruleset{$rules->{ruleset}}; 533 $text .= "\nRuleset: " . $ruleset{$rules->{ruleset}};
498 534
499 $text .= "\nTime: "; 535 $text .= "\nTime: ";
500 536
509 } elsif ($rules->{timesys} == TIMESYS_CANADIAN) { 545 } elsif ($rules->{timesys} == TIMESYS_CANADIAN) {
510 $text .= util::format_time $rules->{time}; 546 $text .= util::format_time $rules->{time};
511 $text .= sprintf " + %s/%d CAN", util::format_time $rules->{interval}, $rules->{count}; 547 $text .= sprintf " + %s/%d CAN", util::format_time $rules->{interval}, $rules->{count};
512 } 548 }
513 549
550 $text .= "\nFlags:";
551 $text .= " private" if $self->is_private;
552 $text .= " started" if $self->is_inprogress;
553 $text .= " adjourned" if $self->is_adjourned;
554 $text .= " scored" if $self->is_scored;
555 $text .= " saved" if $self->is_saved;
556
557 if ($self->is_inprogress) {
558 $text .= "\nHandicap: " . $self->{handicap};
559 $text .= "\nKomi: " . $self->{komi};
560 $text .= "\nSize: " . $self->size_string;
561 }
562
563 if ($self->is_scored) {
564 $text .= "\nResult: " . $self->score_string;
565 }
566
514 $self->{chat}->append_text ("<infoblock>$text</infoblock>"); 567 $inlay->append_text ("<infoblock>$text</infoblock>");
568
569}
570
571sub event_update_rules {
572 my ($self, $rules) = @_;
573
574 $self->{rules} = $rules;
575
576 if ($self->{user}) {
577 $self->{userpanel}[$_]->configure ($self->{app}, $self->{user}[$_], $rules)
578 for COLOUR_BLACK, COLOUR_WHITE;
579 }
580
581 sound::play 3, "gamestart";
582
583 $self->{rules_inlay}->refresh;
515} 584}
516 585
517sub inject_resign_game { 586sub inject_resign_game {
518 my ($self, $msg) = @_; 587 my ($self, $msg) = @_;
519 588
533 . "\nBlack Score " . (util::toxml $msg->{blackscore}->as_string) 602 . "\nBlack Score " . (util::toxml $msg->{blackscore}->as_string)
534 . "</infoblock>" 603 . "</infoblock>"
535 ); 604 );
536} 605}
537 606
607sub inject_req_undo {
608 my ($self, $msg) = @_;
609
610 my $inlay = $self->{undo_inlay} ||= $self->{chat}->new_inlay;
611 return if $inlay->{ignore};
612
613 $inlay->{count}++;
614 $inlay->clear;
615 $inlay->append_text ("\n<undo>Undo requested ($inlay->{count} times)</undo>\n");
616 $inlay->append_button ("Grant", sub {
617 $inlay->clear;
618 $self->send (grant_undo => channel => $self->{channel});
619 });
620 $inlay->append_button ("Ignore", sub {
621 $inlay->clear;
622 $inlay->{ignore} = 1;
623 # but leave inlay, so further undo requests get counted
624 });
625
626}
627
628sub inject_new_game {
629 my ($self, $msg) = @_;
630
631 $self->{chat}->append_text ("\n<header>ACK from server ($msg->{cid} == $self->{cid})</header>");
632 delete $self->{cid};
633}
634
635sub draw_challenge {
636 my ($self, $id) = @_;
637
638 my $info = $self->{challenge}{$id};
639 my $inlay = $info->{inlay};
640 my $rules = $info->{rules};
641 warn "drawchal $id\n";#d#
642# use PApp::Util; warn PApp::Util::dumpval $challenge;#d#
643
644 my $as_black = $info->{black}{name} eq $self->{conn}{name} ? 1 : 0;;
645 my $opponent = $as_black ? $info->{white} : $info->{black};
646
647 my ($size, $time, $interval, $count);
648
649 if (!$self->{channel}) {
650 $inlay->append_text ("\nNotes: ");
651 $inlay->append_entry (\$info->{notes}, 20, "");
652 $inlay->append_text ("\nGlobal Offer: ");
653 $inlay->append_optionmenu (\$info->{flags},
654 0 => "No",
655 2 => "Yes",
656 );
657 } else {
658 $inlay->append_text ("\nNotes: " . util::toxml $info->{notes});
659 }
660
661 $inlay->append_text ("\nType: ");
662 $inlay->append_optionmenu (
663 \$info->{gametype},
664 GAMETYPE_DEMONSTRATION , "Demonstration",
665 GAMETYPE_DEMONSTRATION | GAMETYPE_PRIVATE, "Demonstration (P)",
666 GAMETYPE_TEACHING , "Teaching",
667 GAMETYPE_TEACHING | GAMETYPE_PRIVATE, "Teaching (P)",
668 GAMETYPE_SIMUL , "Simul (not yet!)",
669 GAMETYPE_FREE , "Free",
670 GAMETYPE_RATED , "Rated",
671 sub {
672 $size->set_history (2) if $_[0] eq GAMETYPE_RATED;
673 },
674 );
675
676 if ($self->{channel}) {
677 $inlay->append_text ("\nMy Colour: ");
678 $inlay->append_optionmenu (
679 \$as_black,
680 0 => "White",
681 1 => "Black",
682 sub {
683 if ($info->{$_[0] ? "black" : "white"}{name} ne $self->{conn}{name}) {
684 ($info->{black}, $info->{white}) = ($info->{white}, $info->{black});
685 }
686 }
687 );
688 }
689
690 $inlay->append_text ("\nRuleset: ");
691 $inlay->append_optionmenu (
692 \$info->{rules}{ruleset},
693 RULESET_JAPANESE , "Japanese",
694 RULESET_CHINESE , "Chinese",
695 RULESET_AGA , "AGA",
696 RULESET_NEW_ZEALAND, "New Zealand",
697 );
698
699 $inlay->append_text ("\nSize: ");
700 $size = $inlay->append_optionmenu (
701 \$info->{rules}{size}, 9 => 9, 13 => 13, 19 => 19, map +($_, $_), 2..38
702 );
703
704 if ($self->{channel}) {
705 $inlay->append_text ("\nHandicap: ");
706 $inlay->append_optionmenu (\$info->{rules}{handicap}, map +($_, $_), 0..9);
707
708 $inlay->append_text ("\nKomi: ");
709 $inlay->append_entry (\$info->{rules}{komi}, 5);
710 }
711
712 $inlay->append_text ("\nTimesys: ");
713 $inlay->append_optionmenu (
714 \$info->{rules}{timesys},
715 &TIMESYS_NONE => "None",
716 &TIMESYS_ABSOLUTE => "Absolute",
717 &TIMESYS_BYO_YOMI => "Byo Yomi",
718 &TIMESYS_CANADIAN => "Canadian",
719 sub {
720 my ($new) = @_;
721
722 if ($new eq TIMESYS_NONE) {
723 $time->hide;
724 $interval->hide;
725 $count->hide;
726 } else {
727 $time->show;
728 $time->set_text ($self->{app}{defaults}{time});
729 if ($new eq TIMESYS_ABSOLUTE) {
730 $interval->hide;
731 $count->hide;
732 } else {
733 $interval->show;
734 $count->show;
735 if ($new eq TIMESYS_BYO_YOMI) {
736 $interval->set_text ($self->{app}{defaults}{byo_time});
737 $count->set_text ($self->{app}{defaults}{byo_period});
738 } elsif ($new eq TIMESYS_CANADIAN) {
739 $interval->set_text ($self->{app}{defaults}{can_time});
740 $count->set_text ($self->{app}{defaults}{can_period});
741 }
742 }
743 }
744 }
745 );
746
747 $inlay->append_text ("\nMain Time: ");
748 $time = $inlay->append_entry (\$info->{rules}{time}, 5);
749 $inlay->append_text ("\nInterval: ");
750 $interval = $inlay->append_entry (\$info->{rules}{interval}, 3);
751 $inlay->append_text ("\nPeriods/Stones: ");
752 $count = $inlay->append_entry (\$info->{rules}{count}, 2);
753
754 $inlay->append_text ("\n");
755
756 if (!$self->{channel}) {
757 $inlay->append_button ("Create Challenge", sub {
758 $inlay->clear;
759 $self->{cid} = $self->{conn}->alloc_clientid;
760 $self->send (new_game =>
761 channel => delete $self->{roomid},
762 gametype => $info->{gametype},
763 cid => $self->{cid},
764 flags => $info->{flags},
765 rules => $info->{rules},
766 notes => $info->{notes},
767 );
768 });
769 } else {
770 $inlay->append_button ("OK", sub {
771 $inlay->clear;
772 $self->send (challenge =>
773 channel => $self->{channel},
774 black => $info->{black},
775 white => $info->{white},
776 gametype => $info->{gametype},
777 cid => $info->{cid},
778 rules => $info->{rules},
779 );
780 });
781 if (exists $self->{challenge}{""}) {
782 $inlay->append_button ("Reject", sub {
783 $inlay->clear;
784 $self->send (reject_challenge =>
785 channel => $self->{channel},
786 name => $opponent->{name},
787 gametype => $info->{gametype},
788 cid => $info->{cid},
789 rules => $info->{rules},
790 );
791 });
792 }
793 }
794}
795
796sub draw_users {
797 my ($self, $inlay) = @_;
798
799 for (sort keys %{$self->{users}}) {
800 $inlay->append_text (" <user>" . $self->{users}{$_}->as_string . "</user>");
801 }
802}
803
538sub event_challenge { 804sub event_challenge {
539 my ($self, $challenge) = @_; 805 my ($self, $info) = @_;
540 806
541 use KGS::Listener::Debug; 807 my $as_black = $info->{black}->{name} eq $self->{conn}{name};
542 $self->{chat}->append_text ("\n".KGS::Listener::Debug::dumpval($challenge)); 808 my $opponent = $as_black ? $info->{white} : $info->{black};
809
810 my $id = $opponent->{name};
811
812 warn "challenge from $opponent->{name}\n";#d#
813
814 $self->{challenge}{$id} = $info;
815 $self->{challenge}{$id}{inlay} = $self->{chat}->new_switchable_inlay (
816 exists $self->{challenge}{""}
817 ? "Challenge from $opponent->{name}"
818 : "Challenge to $opponent->{name}",
819 sub {
820 $self->{challenge}{$id}{inlay} = $_[0];
821 $self->draw_challenge ($id);
822 },
823 1 || !exists $self->{challenge}{""} # only open when not offerer
824 );
543} 825}
544 826
5451; 8271;
546 828

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines