Populated Bestine Capitol Building with missing NPCs. Also spawns several other missi...
[swg-src.git] / tools / MoneyNamedAccountToFrom.pl
blob54e604f162669e5bcfe4d5c633bd6d031556718d
1 #! /usr/bin/perl
3 use strict;
4 use warnings;
5 use Getopt::Std;
6 use Math::BigInt;
8 my %from_hash;
9 my %to_hash;
10 my $cnt = 0;
11 my $sort_val = 0;
12 my $max_cnt = 0;
13 my %args;
14 my $start_time;
15 my $min_thresh = 0;
16 my $max_thresh = 0;
17 my $start_date;
18 my $end_date;
20 my $total_in = new Math::BigInt '0';
21 my $total_out = new Math::BigInt '0';
22 my $num_total_in = new Math::BigInt '0';
23 my $num_total_out = new Math::BigInt '0';
25 my $temp_out = new Math::BigInt '0';
26 my $temp_in = new Math::BigInt '0';
27 my $num_temp_out = new Math::BigInt '0';
28 my $num_temp_in = new Math::BigInt '0';
30 my $big_zero = new Math::BigInt '0';
31 my $str_out;
33 my $abridged = 1;
34 my @keys;
36 # Usage
37 sub usage
39 my $name = $0;
40 $name =~ s/^(.*)\\//;
41 print STDERR "\nUsage:\n";
42 print STDERR "\t$name <optional parameters> <server> <start date> <end date>\n";
43 print STDERR "\t\tDate format = yyyy-mm-dd (eg: 2004-06-08)\n";
44 print STDERR "\t$name <optional parameters> -f <money log file>\n\n";
45 print STDERR "Optional parameters:\n";
46 print STDERR "\t[-l <num>] [-s <time> | -S <time>] [-p | -n | -a] [-m <num> | -x <num> | -e <num>] [-d]\n";
47 print STDERR "\t-l <num>\tOnly process <num> lines of log file\n";
48 print STDERR "\t-s <time>\tStart processing at <time> \(eg \"2004-06-01 17:00:03\"\)\n";
49 print STDERR "\t-S <time>\tEnd processing at <time>\n";
50 print STDERR "\t-p \tSort results by player id number (default)\n";
51 print STDERR "\t-n \tSort results by number of transactions\n";
52 print STDERR "\t-a \tSort results by total amount of money changed\n";
53 print STDERR "\t-t \tSort results by time of most recent transaction\n";
54 print STDERR "\t-m <num>\tSet minimum threshold for sorted parameter\n";
55 print STDERR "\t-x <num>\tSet maximum threshold for sorted parameter\n";
56 print STDERR "\t-e <num>\tSet threshold to exactly <num>\n";
57 print STDERR "\t-d \tShow detailed output\n";
58 die "\n";
61 # Adds money / player id into hash
62 # Three arguments - key, value, amount of money, and which hash (to / from)
63 sub put_into
65 my %head;
66 my ($key, $val, $amt, $tim, $tf) = @_;
68 %head = ($tf ? %to_hash : %from_hash);
70 $head{$key} = {} if(!exists $head{$key});
71 $head{$key}->{$val} = [0, 0, 0] if(!exists $head{$key}->{$val});
73 $head{$key}->{$val}->[0] += 1;
74 $head{$key}->{$val}->[1] += $amt;
75 $head{$key}->{$val}->[2] = $tim if($tim gt $head{$key}->{$val}->[2]);
77 if($tf) { %to_hash = %head; }
78 else { %from_hash = %head; }
81 # Will sort numbers and strings - returns -1, 0, or 1
82 # Takes two arguments, to compare
83 sub str_num_cmp
85 my($a, $b) = @_;
87 # Both are numbers
88 return $a <=> $b if($a =~ /^\d+$/ && $b =~ /^\d+$/);
90 # Both are not numbers
91 return $a cmp $b if(!($a =~ /^\d+$/) && !($b =~ /^\d+$/));
93 # $a is a number, $b is not
94 return 1 if($a =~ /^\d+$/);
96 # $a is not a number, $ b is
97 return -1;
100 sub display_money_chart {
101 my $temp_total = new Math::BigInt '0';
102 my $temp_num = new Math::BigInt '0';
103 my $temp_hash = $_[0];
104 my $t_out = $_[1];
105 my @inner_keys;
106 my @sorted_vals;
108 @inner_keys = keys %$temp_hash;
109 @inner_keys = sort @inner_keys;
110 @sorted_vals = ();
111 foreach my $sub_elem (@inner_keys)
113 push(@sorted_vals, [$sub_elem, %$temp_hash->{$sub_elem}->[0], %$temp_hash->{$sub_elem}->[1], %$temp_hash->{$sub_elem}->[2]]);
116 @sorted_vals = sort { &str_num_cmp($b->[$sort_val], $a->[$sort_val]) } @sorted_vals;
117 @sorted_vals = reverse(@sorted_vals) if($sort_val == 0);
118 foreach my $val (@sorted_vals)
120 if((!exists $args{"m"} || (&str_num_cmp($val->[$sort_val], $min_thresh) == 0 || &str_num_cmp($val->[$sort_val], $min_thresh) == 1))
121 && (!exists $args{"x"} || (&str_num_cmp($val->[$sort_val], $max_thresh) == 0 || &str_num_cmp($val->[$sort_val], $max_thresh) == -1))
122 && (!exists $args{"e"} || &str_num_cmp($val->[$sort_val], $max_thresh) == 0))
124 if($t_out)
126 $total_out += $val->[2];
127 $num_total_out += $val->[1];
129 else
131 $total_in += $val->[2];
132 $num_total_in += $val->[1];
135 $temp_total += $val->[2];
136 $temp_num += $val->[1];
138 if(!$abridged)
140 printf "\t\t%-32s%-10d%-12d%-24s\n", $val->[0], $val->[1], $val->[2], $val->[3];
145 return ($temp_total, $temp_num);
148 $start_time = time;
149 &usage() if(!getopts('dpnatm:x:l:e:s:S:f:', \%args));
150 &usage if(((exists $args{"p"}) + (exists $args{"n"}) + (exists $args{"a"})) > 1);
151 &usage if((exists $args{"e"}) && (exists $args{"m"} || exists $args{"x"}));
153 # Process arguments
154 $sort_val = 0 if(exists $args{"p"});
155 $sort_val = 1 if(exists $args{"n"});
156 $sort_val = 2 if(exists $args{"a"});
157 $sort_val = 3 if(exists $args{"t"});
158 $max_cnt = $args{"l"} if(exists($args{"l"}));
159 $min_thresh = $args{"m"} if(exists($args{"m"}));
160 $max_thresh = $args{"x"} if(exists($args{"x"}));
161 $min_thresh = $max_thresh = $args{"e"} if(exists($args{"e"}));
162 $start_date = $args{"s"} if(exists($args{"s"}));
163 $end_date = $args{"S"} if(exists($args{"S"}));
164 $abridged = 0 if(exists($args{"d"}));
166 if(exists($args{"f"}))
168 &usage if(@ARGV != 0);
169 open (MONEY, $args{"f"});
171 else
173 &usage if(@ARGV != 3);
174 open(MONEY, "/m2/logsrv/log_dump.pl swg money $ARGV[0] $ARGV[1] $ARGV[2] |");
177 while (<MONEY>)
179 # Clear out three possible Unicode chars
180 s/^...20(\d{2})/20$1/;
181 chomp;
183 # Check start date if argument was passed
184 if(exists $args{"s"} && /^(\S+)\s+(\S+)/)
186 my $date = $1." ".$2;
187 next if($date lt $start_date);
189 # Check end date if argument was passed
190 if(exists $args{"S"} && /^(\S+)\s+(\S+)/)
192 my $date = $1." ".$2;
193 last if($date gt $end_date);
196 # Check a few special cases
197 if(/cash withdraw from bank by/ || /cash deposit to bank/)
199 #player deposited / withdrew money from bank
201 elsif(/logging out with/ || /logged in with/)
203 #player logged in / out
205 elsif(/^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+) from (.+) to (.+), amount (\d+), (total|total\(from\)) -?(\d+):$/)
207 my $day = $1;
208 my $time = $2;
209 my $planet = $3;
210 my $vara = $4;
211 my $varb = $5;
212 my $varc = $6;
213 my $type = $7;
214 my $from = $8;
215 my $to = $9;
216 my $amount = $10;
217 my $total = $11;
219 my $from_named = $from =~ s/named account //;
220 my $to_named = $to =~ s/named account //;
222 #Strip the station id - can cause problems searching for player id
223 $from =~ s/StationId\(\d+\)//g;
224 $to =~ s/StationId\(\d+\)//g;
226 # Extract player Id number
227 $from =~ s/.*\((\d+)\).*/$1/ if($from =~ /Player/);
228 $to =~ s/.*\((\d+)\).*/$1/ if($to =~ /Player/);
230 # Special case where player has " from " in store title
231 if($type =~ /Player/)
233 $type =~ s/(.*) from /$1/;
234 $from =~ s/.*\((\d+)\).*/$1/;
237 # Add into the approproiate hash
238 if($from_named)
240 &put_into($from, $to, $amount, ($day." ".$time), 0);
243 if($to_named)
245 &put_into($to, $from, $amount, ($day." ".$time), 1);
250 else
252 print "$_\n";
253 die "Error in log file format.\n";
255 # Check counter
256 ++$cnt;
257 last if($cnt == $max_cnt);
260 close (MONEY);
263 print "Named users transaction information:\n" if (!$abridged);
264 print "------------------------------------\n\n" if (!$abridged);
265 @keys = keys %from_hash;
266 push (@keys, (keys %to_hash));
267 @keys = sort @keys;
269 my $prev = -1;
270 @keys = grep($_ ne $prev && ($prev = $_), @keys);
272 printf "%s\t%s\t%s\t%s\t%s\t%s\n", "To:", "# To:", "From:", "# From:", "Delta:", "Account:" if($abridged);
274 foreach my $elem (@keys)
276 $temp_in = $big_zero;
277 $temp_out = $big_zero;
279 $num_temp_in = $big_zero;
280 $num_temp_out = $big_zero;
283 print "$elem:\n" if(!$abridged);
284 if(exists $from_hash{$elem})
286 if(!$abridged)
288 print "\tMoney from $elem:\n";
289 printf "\t\t%-32s%-10s%-12s%-24s\n", "To:", "# Times:", "Total Amt:", "Most Recent Time:";
290 printf "\t\t%-32s%-10s%-12s%-24s\n", "---", "--------", "----------", "-----------------";
293 ($temp_out, $num_temp_out) = display_money_chart($from_hash{$elem}, 0);
295 if(!$abridged)
297 print "\tTotal $elem gave:\n";
298 print "\t\t$temp_out\n\n";
301 if(exists $to_hash{$elem})
303 if(!$abridged)
305 print "\tMoney to $elem:\n";
306 printf "\t\t%-32s%-10s%-12s%-24s\n", "From:", "# Times:", "Total Amt:", "Most Recent Time:";
307 printf "\t\t%-32s%-10s%-12s%-24s\n", "-----", "--------", "----------", "-----------------";
310 ($temp_in, $num_temp_in) = display_money_chart($to_hash{$elem}, 1);
312 if(!$abridged)
314 print "\tTotal given to $elem:\n";
315 print "\t\t$temp_in\n\n";
319 printf "%s\t%s\t%s\t%s\t%s\t%s\n", "To:", "# To:", "From:", "# From:", "Delta:", "Account:" if(!$abridged);
320 $str_out = sprintf "%s\t%s\t%s\t%s\t%s\t%s\n", $temp_in, $num_temp_in, $temp_out, $num_temp_out, ($temp_out - $temp_in), $elem;
321 $str_out =~ s/\+//g;
322 print $str_out;
326 if(!$abridged)
328 print "\nTotal out:\t$total_out\n";
329 print "Total in:\t$total_in\n";
330 print "Total Delta:\t".($total_in - $total_out)."\n";
331 print "\nFinished in ".(time - $start_time)." seconds.\n";
333 else
335 $str_out = sprintf "\n%s\t%s\t%s\t%s\t%s\t%s\n", $total_out, $num_total_out, $total_in, $num_total_in, ($total_in - $total_out), "Total";
336 $str_out =~ s/\+//g;
337 print $str_out;