| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Acme::Shotgun; |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# ABSTRACT: Shoots holes in files |
|
4
|
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
359654
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
41
|
|
|
6
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
1556
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our $VERSION = '0.03'; |
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
sub new { |
|
11
|
23
|
|
|
23
|
1
|
141492
|
my ($class, %args) = @_; |
|
12
|
|
|
|
|
|
|
|
|
13
|
23
|
|
|
|
|
352
|
my $self = { |
|
14
|
|
|
|
|
|
|
type => 'double', |
|
15
|
|
|
|
|
|
|
load => 'bird', |
|
16
|
|
|
|
|
|
|
shots => undef, |
|
17
|
|
|
|
|
|
|
quiet => 0, |
|
18
|
|
|
|
|
|
|
debug => 0, |
|
19
|
|
|
|
|
|
|
verbose => 1, |
|
20
|
|
|
|
|
|
|
num_rounds => 0, |
|
21
|
|
|
|
|
|
|
%args, |
|
22
|
|
|
|
|
|
|
}; |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
die "Invalid shotgun type '$self->{type}'! Must be 'double' or 'pump'.\n" |
|
25
|
23
|
100
|
|
|
|
271
|
unless $self->{type} =~ /^(?:double|pump)$/; |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
die "Invalid ammo type '$self->{load}'! Must be 'bird', 'buck', or 'slug'.\n" |
|
28
|
22
|
100
|
|
|
|
151
|
unless $self->{load} =~ /^(?:bird|buck|slug)$/; |
|
29
|
|
|
|
|
|
|
|
|
30
|
21
|
100
|
|
|
|
78
|
$self->{verbose}++ if $self->{debug}; |
|
31
|
21
|
50
|
|
|
|
85
|
$self->{verbose} = 0 if $self->{quiet}; |
|
32
|
|
|
|
|
|
|
|
|
33
|
21
|
|
|
|
|
56
|
bless $self, $class; |
|
34
|
21
|
|
|
|
|
84
|
$self->reload(); |
|
35
|
|
|
|
|
|
|
|
|
36
|
21
|
|
|
|
|
106
|
return $self; |
|
37
|
|
|
|
|
|
|
} |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
sub reload { |
|
40
|
28
|
|
|
28
|
1
|
1675
|
my $self = shift; |
|
41
|
|
|
|
|
|
|
|
|
42
|
28
|
100
|
|
|
|
101
|
my $num_rounds = $self->{type} eq 'pump' ? 5 : 2; |
|
43
|
|
|
|
|
|
|
$num_rounds = $self->{shots} |
|
44
|
28
|
100
|
100
|
|
|
118
|
if $self->{shots} && $self->{shots} < $num_rounds; |
|
45
|
|
|
|
|
|
|
|
|
46
|
28
|
|
|
|
|
56
|
$self->{num_rounds} = $num_rounds; |
|
47
|
|
|
|
|
|
|
|
|
48
|
28
|
50
|
|
|
|
78
|
print "Loading $num_rounds round(s)...\n" if $self->{verbose}; |
|
49
|
28
|
|
|
|
|
1761
|
print "Shotgun reloaded!\n"; |
|
50
|
28
|
50
|
|
|
|
99
|
$self->check() if $self->{verbose}; |
|
51
|
|
|
|
|
|
|
|
|
52
|
28
|
|
|
|
|
67
|
return $self; |
|
53
|
|
|
|
|
|
|
} |
|
54
|
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
sub check { |
|
56
|
1
|
|
|
1
|
1
|
6
|
my $self = shift; |
|
57
|
|
|
|
|
|
|
printf "type: %s load: %s rounds: %d\n", |
|
58
|
1
|
|
|
|
|
12
|
$self->{type}, $self->{load}, $self->{num_rounds}; |
|
59
|
1
|
|
|
|
|
4
|
return $self; |
|
60
|
|
|
|
|
|
|
} |
|
61
|
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
sub fire { |
|
63
|
16
|
|
|
16
|
1
|
23141
|
my ($self, %args) = @_; |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
my $target = $args{target} |
|
66
|
16
|
100
|
|
|
|
105
|
or die "No target specified!\n"; |
|
67
|
|
|
|
|
|
|
|
|
68
|
15
|
100
|
|
|
|
489
|
die "Target file does not exist: $target\n" unless -e $target; |
|
69
|
14
|
50
|
|
|
|
128
|
die "Target file must be a plain file: $target\n" unless -f $target; |
|
70
|
14
|
50
|
|
|
|
474
|
die "Target file must be under 1 GB: $target\n" |
|
71
|
|
|
|
|
|
|
if -s $target > (1024 * 1024); |
|
72
|
|
|
|
|
|
|
|
|
73
|
14
|
100
|
|
|
|
93
|
if ($self->{num_rounds} == 0) { |
|
74
|
1
|
|
|
|
|
9
|
print "Mag empty, you'll need to reload!\n"; |
|
75
|
1
|
|
|
|
|
8
|
return $self; |
|
76
|
|
|
|
|
|
|
} |
|
77
|
|
|
|
|
|
|
|
|
78
|
13
|
|
|
|
|
77
|
while ($self->{num_rounds} > 0) { |
|
79
|
44
|
|
|
|
|
157
|
$self->_shoot($target); |
|
80
|
44
|
|
|
|
|
182
|
$self->{num_rounds}--; |
|
81
|
|
|
|
|
|
|
} |
|
82
|
|
|
|
|
|
|
|
|
83
|
13
|
|
|
|
|
123
|
return $self; |
|
84
|
|
|
|
|
|
|
} |
|
85
|
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
## Private methods |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub _shoot { |
|
89
|
44
|
|
|
44
|
|
137
|
my ($self, $target) = @_; |
|
90
|
|
|
|
|
|
|
|
|
91
|
44
|
100
|
|
|
|
141
|
if ($self->{debug}) { |
|
92
|
2
|
|
|
|
|
16
|
print "POW! (debug - no file modified)\n"; |
|
93
|
2
|
|
|
|
|
5
|
return; |
|
94
|
|
|
|
|
|
|
} |
|
95
|
|
|
|
|
|
|
|
|
96
|
42
|
50
|
|
|
|
1748
|
open my $in, '<', $target or die "Unable to open target file: $target\n"; |
|
97
|
42
|
|
|
|
|
1302
|
my @lines = <$in>; |
|
98
|
42
|
|
|
|
|
480
|
close $in; |
|
99
|
|
|
|
|
|
|
|
|
100
|
42
|
|
|
|
|
118
|
my $height = scalar @lines; |
|
101
|
42
|
|
|
|
|
92
|
my $width = 80; |
|
102
|
42
|
|
|
|
|
185
|
my $v_buffer = int rand($height); |
|
103
|
42
|
|
|
|
|
79
|
my $h_buffer = int rand($width); |
|
104
|
42
|
|
|
|
|
82
|
my $v_spread = 7; |
|
105
|
42
|
|
|
|
|
64
|
my $h_spread = 13; |
|
106
|
42
|
|
|
|
|
81
|
my $r = int rand(3); |
|
107
|
|
|
|
|
|
|
|
|
108
|
42
|
|
|
|
|
189
|
for my $v (0 .. $v_spread - 1) { |
|
109
|
245
|
|
|
|
|
369
|
my $v_offset = $v_buffer + $v; |
|
110
|
245
|
100
|
|
|
|
617
|
last if $v_offset >= $height; |
|
111
|
|
|
|
|
|
|
|
|
112
|
222
|
|
|
|
|
1659
|
my @line = split '', $lines[$v_offset]; |
|
113
|
|
|
|
|
|
|
|
|
114
|
222
|
|
|
|
|
509
|
for my $h (0 .. $h_spread - 1) { |
|
115
|
1286
|
|
|
|
|
2240
|
my $h_offset = $h_buffer + $h; |
|
116
|
1286
|
100
|
|
|
|
2940
|
last if $h_offset >= @line; |
|
117
|
1175
|
100
|
|
|
|
2599
|
last if $line[$h_offset] eq "\n"; |
|
118
|
|
|
|
|
|
|
|
|
119
|
1131
|
100
|
|
|
|
2732
|
if ($self->{load} eq 'buck') { |
|
|
|
100
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
$line[$h_offset] = ' ' |
|
121
|
117
|
100
|
50
|
|
|
596
|
if grep { $_ == $h } @{ _buck_pattern($r)->{$v} // [] }; |
|
|
416
|
|
|
|
|
2071
|
|
|
|
117
|
|
|
|
|
243
|
|
|
122
|
|
|
|
|
|
|
} elsif ($self->{load} eq 'slug') { |
|
123
|
|
|
|
|
|
|
$line[$h_offset] = ' ' |
|
124
|
29
|
100
|
100
|
|
|
42
|
if grep { $_ == $h } @{ _slug_pattern($r)->{$v} // [] }; |
|
|
33
|
|
|
|
|
78
|
|
|
|
29
|
|
|
|
|
56
|
|
|
125
|
|
|
|
|
|
|
} else { |
|
126
|
|
|
|
|
|
|
$line[$h_offset] = ' ' |
|
127
|
985
|
100
|
50
|
|
|
1281
|
if grep { $_ == $h } @{ _bird_pattern($r)->{$v} // [] }; |
|
|
1813
|
|
|
|
|
3922
|
|
|
|
985
|
|
|
|
|
1695
|
|
|
128
|
|
|
|
|
|
|
} |
|
129
|
|
|
|
|
|
|
|
|
130
|
1131
|
|
|
|
|
5309
|
$lines[$v_offset] = join('', @line); |
|
131
|
|
|
|
|
|
|
} |
|
132
|
|
|
|
|
|
|
} |
|
133
|
|
|
|
|
|
|
|
|
134
|
42
|
50
|
|
|
|
5100
|
open my $fh, '>', $target or die "Unable to open target file: $target\n"; |
|
135
|
42
|
|
|
|
|
683
|
print $fh $_ for @lines; |
|
136
|
42
|
|
|
|
|
8986
|
close $fh; |
|
137
|
|
|
|
|
|
|
|
|
138
|
42
|
50
|
|
|
|
788
|
print "POW!\n" unless $self->{quiet}; |
|
139
|
|
|
|
|
|
|
} |
|
140
|
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
## Shot pattern data |
|
142
|
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
sub _buck_pattern { |
|
144
|
117
|
|
|
117
|
|
195
|
my $r = shift; |
|
145
|
117
|
|
|
|
|
5516
|
my @patterns = ( |
|
146
|
|
|
|
|
|
|
{ 0=>[6,7], 1=>[1,2,6,7], 2=>[1,2,11,12], 3=>[6,7,11,12], |
|
147
|
|
|
|
|
|
|
4=>[1,2,6,7], 5=>[1,2,9,10], 6=>[9,10] }, |
|
148
|
|
|
|
|
|
|
{ 0=>[1,2,9,10], 1=>[1,2,9,10], 2=>[5,6], 3=>[1,5,6,10,11], |
|
149
|
|
|
|
|
|
|
4=>[1,2,10,11], 5=>[6,7], 6=>[6,7] }, |
|
150
|
|
|
|
|
|
|
{ 0=>[5,6,7], 1=>[1,2,6,10,11], 2=>[1,2,10,11], 3=>[5,6,7], |
|
151
|
|
|
|
|
|
|
4=>[1,2,6], 5=>[1,2,10], 6=>[9,10] }, |
|
152
|
|
|
|
|
|
|
); |
|
153
|
117
|
|
|
|
|
1312
|
return $patterns[$r]; |
|
154
|
|
|
|
|
|
|
} |
|
155
|
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
sub _slug_pattern { |
|
157
|
29
|
|
|
29
|
|
71
|
my $r = shift; |
|
158
|
29
|
|
|
|
|
148
|
my @patterns = ( |
|
159
|
|
|
|
|
|
|
{ 0=>[5,6,7], 1=>[5,6] }, |
|
160
|
|
|
|
|
|
|
{ 0=>[5,6], 1=>[5,6,7] }, |
|
161
|
|
|
|
|
|
|
{ 0=>[5,6], 1=>[4,5,6] }, |
|
162
|
|
|
|
|
|
|
); |
|
163
|
29
|
|
|
|
|
175
|
return $patterns[$r]; |
|
164
|
|
|
|
|
|
|
} |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sub _bird_pattern { |
|
167
|
985
|
|
|
985
|
|
1461
|
my $r = shift; |
|
168
|
985
|
|
|
|
|
12586
|
my @patterns = ( |
|
169
|
|
|
|
|
|
|
{ 0=>[6], 1=>[3,9], 2=>[6], 3=>[3], 4=>[1,6,10], 5=>[4], 6=>[0,7] }, |
|
170
|
|
|
|
|
|
|
{ 0=>[6], 1=>[3,9], 2=>[6,11], 3=>[3,7,9], 4=>[6,10], |
|
171
|
|
|
|
|
|
|
5=>[4,9], 6=>[7,11] }, |
|
172
|
|
|
|
|
|
|
{ 0=>[6,9], 1=>[2,4,7], 2=>[5,9], 3=>[1,7], 4=>[6], |
|
173
|
|
|
|
|
|
|
5=>[3,6,9], 6=>[5] }, |
|
174
|
|
|
|
|
|
|
); |
|
175
|
985
|
|
|
|
|
7821
|
return $patterns[$r]; |
|
176
|
|
|
|
|
|
|
} |
|
177
|
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
1; |
|
179
|
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
__END__ |