-
-
Save YoOoster/8ea3644bb24c531271188fa40c90879b to your computer and use it in GitHub Desktop.
use 5.012; | |
use strict; | |
use warnings; | |
use File::Temp qw(tempfile); | |
use IPC::System::Simple qw(capture system); | |
use LWP::UserAgent; | |
use URI::QueryParam; | |
use Win32::GUI; | |
use Data::Dumper; | |
use integer; | |
use constant false => 0; | |
use constant true => 1; | |
my $PicJigsaw = Win32::GUI::Bitmap->new("jigsaw.bmp"); | |
my $PicSudoku = Win32::GUI::Bitmap->new("sudoku.bmp"); | |
my @board; | |
my $solveCount = 0; | |
my $Window_Main; | |
my $Window_Jigsaw; | |
my $Window_Sudoku; | |
######################################################### | |
# Main Window # | |
######################################################### | |
sub Create_Window_Main { | |
my $W1 = Win32::GUI::Window->new( | |
-name => "WindowMain", | |
-title => "Depuzzlefy", | |
-size => [ 800, 475 ], | |
-pos => [ Win32::GUI::Width(Win32::GUI::GetDesktopWindow())/2-400, Win32::GUI::Height(Win32::GUI::GetDesktopWindow())/2-237.50 ], | |
-sizable => 0, | |
-hasmaximize => 0, | |
-maximizebox => 0, | |
-hasminimize => 0, | |
-minimizebox => 0, | |
); | |
$W1->AddButton( | |
-name => "ButtonMainJigsaw", | |
-text => "Jigsaw puzzles", | |
-align => "center", | |
-valign => "center", | |
-picture=> $PicJigsaw, | |
-pos => [ 25, 60 ], | |
-size => [ 350, 350], | |
); | |
$W1->AddButton( | |
-name => "ButtonMainSudoku", | |
-text => "Sudoku", | |
-align => "center", | |
-valign => "center", | |
-picture=> $PicSudoku, | |
-pos => [ 400, 60 ], | |
-size => [ 350, 350], | |
); | |
$W1->AddLabel( | |
-name => "LabelMainJigsaw", | |
-text => "Jigsaw Puzzles", | |
-pos => [175, 45], | |
-size => [350, 15], | |
); | |
$W1->AddLabel( | |
-name => "LabelMainSudoku", | |
-text => "Sudoku", | |
-pos => [550, 45], | |
-size => [350, 15], | |
); | |
return $W1; | |
} | |
sub WindowMain_Terminate { | |
return -1; | |
} | |
sub ButtonMainJigsaw_Click { | |
$Window_Main->Hide(); | |
$Window_Jigsaw->DoModal(); | |
} | |
sub ButtonMainSudoku_Click { | |
$Window_Main->Hide(); | |
$Window_Sudoku->DoModal(); | |
} | |
######################################################### | |
# Jigsaw Window # | |
######################################################### | |
sub Create_Window_Jigsaw { | |
my $W1 = Win32::GUI::Window->new( | |
-name => "WindowJigsaw", | |
-title => "Depuzzlefy - Jigsaw", | |
-size => [ 300, 150 ], | |
-pos => [ Win32::GUI::Width(Win32::GUI::GetDesktopWindow())/2-150, Win32::GUI::Height(Win32::GUI::GetDesktopWindow())/2-75 ], | |
-sizable=> 0, | |
-parent => $Window_Main, | |
-hasmaximize => 0, | |
-maximizebox => 0, | |
-hasminimize => 0, | |
-minimizebox => 0, | |
); | |
$W1->AddButton( | |
-name => "ButtonWJDepuzzlefy", | |
-text => "Depuzzlefy", | |
-pos => [ 20, 60 ], | |
-size => [ 250, 30], | |
); | |
$W1->AddLabel( | |
-name => "LabelWJUrl", | |
-text => "Insert URL", | |
-pos => [20, 20], | |
-size => [250, 20], | |
); | |
$W1->AddTextfield( | |
-name => "TextfieldWJUrl", | |
-pos => [20,40], | |
-size => [250, 20], | |
); | |
return $W1; | |
} | |
sub WindowJigsaw_Terminate { | |
$Window_Main->Show(); | |
return -1; | |
} | |
sub ButtonWJDepuzzlefy_Click { | |
my $url = $Window_Jigsaw->TextfieldWJUrl->Text(); | |
if ($url =~ m[flash-gear.com]gi) { | |
FlashGearRequest(); | |
} elsif ($url =~ m[jigidi.com]gi) { | |
JigidiRequest(); | |
} else { | |
$Window_Jigsaw->TextfieldWJUrl->SelectAll(); | |
$Window_Jigsaw->TextfieldWJUrl->Clear(); | |
print "Website isn't supported.'\n\n"; | |
return; | |
} | |
} | |
######################################################### | |
# Sudoku Window # | |
######################################################### | |
sub Create_Window_Sudoku { | |
my $W1 = Win32::GUI::Window->new( | |
-name => "WindowSudoku", | |
-title => "Depuzzlefy - Sudoku", | |
-size => [ 315, 370 ], | |
-pos => [ Win32::GUI::Width(Win32::GUI::GetDesktopWindow())/2-157.5, Win32::GUI::Height(Win32::GUI::GetDesktopWindow())/2-185 ], | |
-sizable => 0, | |
-parent => $Window_Main, | |
-hasmaximize => 0, | |
-maximizebox => 0, | |
-hasminimize => 0, | |
-minimizebox => 0, | |
); | |
for (my $i = 0; $i < 9; $i++) { | |
for (my $j = 0; $j <9; $j++) { | |
my $tf = $W1->AddTextfield( | |
-name => "TextFieldSudoku$i$j", | |
-pos => [($j*30)+20, ($i*30)+30], | |
-size => [25,25], | |
-align => "center", | |
-number => 1, | |
); | |
$tf->MaxLength(1); | |
} | |
} | |
$W1->AddButton( | |
-name => "ButtonSudokuSolve", | |
-text => "Solve", | |
-pos => [ 120, 295 ], | |
-size => [ 85, 30 ], | |
); | |
return $W1; | |
} | |
sub WindowSudoku_Terminate { | |
$Window_Main->Show(); | |
return -1; | |
} | |
sub ButtonSudokuSolve_Click { | |
undef @board; | |
$solveCount = 0; | |
for (my $i = 0; $i < 9; $i++) { | |
for (my $j = 0; $j < 9; $j++) { | |
my $method = "TextFieldSudoku$i$j"; | |
if (($Window_Sudoku->$method->Text() + 0) != "") { | |
push @board, (($Window_Sudoku->$method->Text()) + 0); | |
} else { | |
push @board, 0; | |
} | |
} | |
} | |
SolveSudoku(); | |
} | |
######################################################### | |
sub SolveSudoku { | |
printf "Trying to solve Sudoku. Count:%s\n", $solveCount++; | |
my $i; | |
foreach $i ( 0 .. 80 ) { | |
next if $board[$i]; | |
my %t = map { | |
$_ / 9 == $i / 9 || | |
$_ % 9 == $i % 9 || | |
$_ / 27 == $i / 27 && $_ % 9 / 3 == $i % 9 / 3 | |
? $board[$_] : 0, | |
1; | |
} 0 .. 80; | |
SolveSudoku( $board[$i] = $_ ) for grep !$t{$_}, 1 .. 9; | |
return $board[$i] = 0; | |
} | |
# $i = 0; | |
# foreach (@board) { | |
# print "-----+-----+-----\n" if !($i%27) && $i; | |
# print !($i%9) ? '': $i%3 ? ' ' : '|', $_; | |
# print "\n" unless ++$i%9; | |
# } | |
for (my $i = 0; $i < 9; $i++) { | |
for (my $j = 0; $j < 9; $j++) { | |
my $method = "TextFieldSudoku$i$j"; | |
my $value = $board[($i * 9) + $j]; | |
$Window_Sudoku->$method->SelectAll(); | |
$Window_Sudoku->$method->Clear(); | |
$Window_Sudoku->$method->Append("$value"); | |
} | |
} | |
} | |
sub ClearHideJigsaw { | |
$Window_Jigsaw->TextfieldWJUrl->SelectAll(); | |
$Window_Jigsaw->TextfieldWJUrl->Clear(); | |
$Window_Jigsaw->Hide(); | |
} | |
sub SetUserAgent { | |
my $ua = LWP::UserAgent->new(); | |
$ua->agent('Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0'); | |
$ua->cookie_jar({}); | |
$ua->protocols_allowed(['http','https']); | |
$ua->ssl_opts(verify_hostname => 0); | |
$ua->default_header('Accept-Encoding' => scalar HTTP::Message::decodable()); | |
return $ua; | |
} | |
# TODO: Find a way to make use of the normal temp map. using c:/dpf but this map is getting deleted at the end. Might be troublesome if someone made a own map. | |
# Using c:/dpf because otherwise large puzzles were getting errors because of too long commandprompt commands. | |
# This may still happen on really large puzzles but I haven't encountered them yet. | |
sub FlashGearRequest { | |
my $url = $Window_Jigsaw->TextfieldWJUrl->Text(); | |
ClearHideJigsaw(); | |
print "Requesting URL data\n\n"; | |
my $ua = SetUserAgent(); | |
my $res = $ua->get($url); | |
if(!$res->is_success) { | |
printf "%s\n\n", $res->status_line; | |
$Window_Jigsaw->Show(); | |
return; | |
} | |
my $content = $res->decoded_content // $res->content // die 'no content'; | |
my @url = $content =~ m[<embed(?: [^>]*?)? src="([^"]+)"]gi; | |
if(!@url) { | |
print "No Flash file found. Please insert a correct URL\n\n"; | |
$Window_Jigsaw->Show(); | |
return; | |
} | |
print "Found Flash file\n\n"; | |
print "Extracting pictures from the Flash file\n"; | |
print "This may take a while depending on the size of the puzzle\n\n"; | |
my $dir = "C:\\dpf"; | |
my $img = ''; | |
$url = $url[1]; | |
my $uri = URI->new($url); | |
my ($h, $w, $id) = map $uri->query_param($_), qw(h w id); | |
next unless $h and $w and $id; | |
$uri->query_param(c => 'z'); | |
my $swf = File::Temp->new(suffix => '.swf'); | |
$res = $ua->get($uri, ':content_file' => $swf->filename); | |
my $out = capture swfextract => $swf; | |
my ($ids) = $out =~ /^\s*\[-j\] \d+ JPEGs: ID\(s\) (\d+,.*)/m; | |
my @ids = split(", ", $ids); | |
mkdir $dir, 0666; | |
foreach my $id (@ids) { | |
system swfextract => '-j', $id, '--outputformat', "$dir/%05d.%s", $swf; | |
} | |
# FIX: Other jpgs will crash it. | |
my @jpg = glob "$dir/*.jpg"; | |
$out = capture identify => $jpg[0]; | |
my ($x, $y) = $out =~ / JPEG (\d+)x(\d+)/; | |
next unless $x and $y and $x == $y; | |
$_ = int $_ / $x * 2 for $w, $h; | |
# The edges of each puzzle piece image need to be overlapped. | |
$_ = int $_ / 4 for $x, $y; | |
$img = "$id.jpg"; | |
system montage => '-tile', "${w}x$h", '-geometry', "-$x-$y", @jpg, $img; | |
unlink @jpg; | |
system "cmd /c start $img"; | |
print "Done\n\n"; | |
$Window_Jigsaw->Show(); | |
} | |
sub JigidiRequest { | |
my $url = $Window_Jigsaw->TextfieldWJUrl->Text(); | |
ClearHideJigsaw(); | |
my @id = $url =~ m[\?id=([^"]+)]; | |
print "Requesting URL data\n\n"; | |
my $ua = SetUserAgent(); | |
my $res = $ua->get($url); | |
if(!$res->is_success) { | |
printf "%s\n\n", $res->status_line; | |
$Window_Jigsaw->Show(); | |
return; | |
} | |
my $content = $res->decoded_content // $res->content // die 'no content\n'; | |
my @token = $content =~ m[token:\"([^"]+)]; | |
printf "%s\n\n", "Found token"; | |
$res = $ua->get("https://www.jigidi.com/ajax/api/2/game_lookup.php?token=$token[0]"); | |
if(!$res->is_success) { | |
printf "%s\n\n", $res->status_line; | |
$Window_Jigsaw->Show(); | |
return; | |
} | |
$content = $res->decoded_content // $res->content // die 'no content\n'; | |
my @pic = $content =~ m[image\":\"([^"]+)]; | |
$pic[0] =~ s/[\\]//g ; | |
$pic[0] =~ s/.{5}$//; | |
print "Saving picture\n\n"; | |
unlink "$id[0].jpg"; | |
$res = $ua->mirror($pic[0], "$id[0].jpg"); | |
unless($res->is_success) { | |
printf "%s\n\n", $res->status_line; | |
$Window_Jigsaw->Show(); | |
return; | |
} | |
system "cmd /c start $id[0].jpg"; | |
print "Done\n\n"; | |
$Window_Jigsaw->Show(); | |
} | |
$Window_Main = Create_Window_Main(); | |
$Window_Jigsaw = Create_Window_Jigsaw(); | |
$Window_Sudoku = Create_Window_Sudoku(); | |
$Window_Main->Show(); | |
Win32::GUI::Dialog(); |
I have the same problems as Rhoenbussard.
The puzzles always split in two files xxxx-0 and xxxx-1.
Followed by the error code that it can#T find the file withe the name xxxx.
Thanks for your help!
Kai
@kaischmitt
Which puzzle?
This:
http://four.flash-gear.com/npuz/puz.php?c=v&id=4103396&k=7328868
gives theese files:
I have the same problem with this URL: http://six.flash-gear.com/npuz/puz.php?c=v&id=3544876&k=77212470.
I've installed the latest version on the latest version of Windows10. Maybe that helps a little.
Super Tool! I am also interested in a completion message. Is there any posibility?
Super Tool! I am also interested in a completion message. Is there any posibility?
Ditto!
Apart from the completion message which many people have already asked for, I'd very much like a non-windows option.
I tried the new version, but there is no difference. My pictures look like this
What can I do?