update readme and add gitignore
[client-tools.git] / tools / MoneyCheckActivity.pl
blob43e58f3942f891f8aab23c500e6299d716c37233
1 #! /usr/bin/perl
3 use strict;
4 use warnings;
5 use Getopt::Std;
6 use Math::BigInt;
8 my %player_hash;
10 # key (player id) => (# trans to, total amt to them, last time to them,
11 # # trans from, total amt from them, last time from them)
12 # money_hash is a global hash referece for whatever player we are analyzing
13 my $money_hash;
15 my $cnt = 0;
16 my $sort_val = 0;
17 my $max_cnt = 0;
18 my %args;
19 my $start_time;
20 my $min_thresh = 0;
21 my $max_thresh = 0;
22 my $player_id = 0;
23 my $start_date;
24 my $end_date;
25 my $num_days;
27 my $total_in = new Math::BigInt '0';
28 my $total_out = new Math::BigInt '0';
29 my $num_total_in = new Math::BigInt '0';
30 my $num_total_out = new Math::BigInt '0';
31 my @keys;
33 my $big_zero = new Math::BigInt '0';
34 my $str_out;
36 my $abridged = 1;
38 # Usage
39 sub usage
41 my $name = $0;
42 $name =~ s/^(.*)\\//;
43 print STDERR "\nUsage:\n";
44 print STDERR "\t$name <optional parameters> <server> <start date> <end date> <player id> ... (as many player ids as you want to scan)\n";
45 print STDERR "\t\tDate format = yyyy-mm-dd (eg: 2004-06-08)\n";
46 print STDERR "\t$name <optional parameters> -f <money log file> <player id> ... (as many player ids as you want to scan)\n";
47 print STDERR "Optional parameters:\n";
48 print STDERR "\t[-l <num>] [-s <str> | -S <str>] [-n | -a | -t | -N | -A | -T] [-m <str> | -x <str> | -e <str>] [-d]\n";
49 print STDERR "\t-l <num>\tOnly process <num> lines of log file\n";
50 print STDERR "\t-s <time>\tStart processing at <time> \(eg \"2004-06-01 17:00:03\"\)\n";
51 print STDERR "\t-S <time>\tEnd processing at <time>\n";
52 print STDERR "\t-p \tSort by player id number (default)\n";
53 print STDERR "\t-n \tSort by number of transactions to the player\n";
54 print STDERR "\t-a \tSort by total amount of money to the player\n";
55 print STDERR "\t-t \tSort by time of most recent transaction to the player\n";
56 print STDERR "\t-N \tSort by number of transactions from the player\n";
57 print STDERR "\t-A \tSort by total amount of money from the player\n";
58 print STDERR "\t-T \tSort by time of most recent transaction from the player\n";
59 print STDERR "\t-m <str>\tSet minimum threshold for sorted parameter\n";
60 print STDERR "\t-x <str>\tSet maximum threshold for sorted parameter\n";
61 print STDERR "\t-e <str>\tSet threshold to exactly <num>\n";
62 print STDERR "\t-d \tShow detailed output\n";
63 die "\n";
66 # Adds money / player id into hash
67 # Two arguments - key, amount of money, and (to / from)
68 sub put_into
70 my ($key, $amt, $tim, $tf) = @_;
72 $tf = ($tf * 3);
74 $$money_hash{$key} = [0, 0, 0, 0, 0, 0, 0] if(!exists $$money_hash{$key});
76 $$money_hash{$key}->[$tf] += 1;
77 $$money_hash{$key}->[$tf+1] += $amt;
78 $$money_hash{$key}->[$tf+2] = $tim if($tim gt $$money_hash{$key}->[$tf+2]);
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 # Displays the money chart in %money_hash
101 # Takes no arguments
102 sub display_money_chart
104 my $temp_total = $big_zero;
105 my $temp_hash = $_[0];
106 my @key_vals;
107 my @sorted_vals;
109 @key_vals = keys %$money_hash;
110 @sorted_vals = ();
111 foreach my $sub_elem (@key_vals)
113 push(@sorted_vals, [$sub_elem, $$money_hash{$sub_elem}->[0], $$money_hash{$sub_elem}->[1],
114 $$money_hash{$sub_elem}->[2], $$money_hash{$sub_elem}->[3],
115 $$money_hash{$sub_elem}->[4], $$money_hash{$sub_elem}->[5]]);
118 @sorted_vals = sort { &str_num_cmp($b->[$sort_val], $a->[$sort_val]) } @sorted_vals;
119 @sorted_vals = reverse(@sorted_vals) if($sort_val == 0);
120 foreach my $val (@sorted_vals)
122 if((!exists $args{"m"} || (&str_num_cmp($val->[$sort_val], $min_thresh) == 0 || &str_num_cmp($val->[$sort_val], $min_thresh) == 1))
123 && (!exists $args{"x"} || (&str_num_cmp($val->[$sort_val], $max_thresh) == 0 || &str_num_cmp($val->[$sort_val], $max_thresh) == -1))
124 && (!exists $args{"e"} || &str_num_cmp($val->[$sort_val], $max_thresh) == 0))
126 $total_in += $val->[5];
127 $total_out += $val->[2];
129 $num_total_in += $val->[4];
130 $num_total_out += $val->[1];
132 if(!$abridged)
134 printf "\t%-34s%-8s%-12s%-24s%-8s%-12s%-24s\n", $val->[0], $val->[1], $val->[2], $val->[3], $val->[4], $val->[5], $val->[6];
136 else
138 $str_out = sprintf "%s\t%s\t%s\t%s\t%s\t%s\n", $val->[5], $val->[4], $val->[2], $val->[1], ($val->[5] - $val->[2]), $val->[0];
139 $str_out =~ s/\+//g;
140 print $str_out;
147 $start_time = time;
148 &usage() if(!getopts('dpnatNATm:x:l:e:s:S:f:', \%args));
149 &usage if(((exists $args{"n"}) + (exists $args{"a"}) + (exists $args{"t"})
150 + (exists $args{"N"}) + (exists $args{"A"}) + (exists $args{"T"}) + (exists $args{"p"})) > 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 $sort_val = 4 if(exists $args{"N"});
159 $sort_val = 5 if(exists $args{"A"});
160 $sort_val = 6 if(exists $args{"T"});
161 $max_cnt = $args{"l"} if(exists($args{"l"}));
162 $min_thresh = $args{"m"} if(exists($args{"m"}));
163 $max_thresh = $args{"x"} if(exists($args{"x"}));
164 $min_thresh = $max_thresh = $args{"e"} if(exists($args{"e"}));
165 $start_date = $args{"s"} if(exists($args{"s"}));
166 $end_date = $args{"S"} if(exists($args{"S"}));
167 $abridged = 0 if(exists($args{"d"}));
169 if(exists($args{"f"}))
171 &usage if(@ARGV < 1);
172 open (MONEY, $args{"f"});
174 else
176 &usage if(@ARGV < 4);
177 my $server = shift;
178 my $start = shift;
179 my $end = shift;
180 open(MONEY, "/m2/logsrv/log_dump.pl swg money $server $start $end |");
183 # Fill the player hash
184 foreach(@ARGV)
186 $player_hash{$_} = {};
189 while (<MONEY>)
191 # Clear out three possible Unicode chars
192 s/^...20(\d{2})/20$1/;
193 chomp;
195 my $day;
196 my $time;
197 my $planet;
198 my $vara;
199 my $varb;
200 my $varc;
201 my $type;
202 my $from;
203 my $to;
204 my $amount;
205 my $total;
207 # Check start date if argument was passed
208 if(exists $args{"s"} && /^(\S+)\s+(\S+)/)
210 my $date = $1." ".$2;
211 next if($date lt $start_date);
213 # Check end date if argument was passed
214 if(exists $args{"S"} && /^(\S+)\s+(\S+)/)
216 my $date = $1." ".$2;
217 last if($date gt $end_date);
220 # Check a few special cases
221 if(/^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+) (from|to) bank by (.+), amount (\d+), (total|total\(from\)) -?(\d+):$/)
223 #player deposited / withdrew money from bank
225 $day = $1;
226 $time = $2;
227 $planet = $3;
228 $vara = $4;
229 $varb = $5;
230 $varc = $6;
231 $type = $7;
232 $from = $8;
233 $to = $9;
234 $amount = $10;
235 $total = $11;
237 #Strip the station id - can cause problems searching for player id
238 $from =~ s/StationId\(\d+\)//g;
239 $to =~ s/StationId\(\d+\)//g;
241 # If it's a named account, strip the name out
242 $to =~ s/named account //;
244 # Extract player Id number
245 $to =~ s/.*\((\d+)\).*/$1/ if($to =~ /Player/);
247 # Add into the approproiate hash
248 if($from eq "to" && exists $player_hash{$to})
250 $money_hash = $player_hash{$to};
251 &put_into("bank", $amount, ($day." ".$time), 0);
254 if($to eq "from" && exists $player_hash{$to})
256 $money_hash = $player_hash{$to};
257 &put_into("bank", $amount, ($day." ".$time), 1);
261 elsif(/logging out with/ || /logged in with/)
263 #player logged in / out
264 next;
266 elsif(/^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+) from (.+) to (.+), amount (\d+), (total|total\(from\)) -?(\d+):$/)
268 $day = $1;
269 $time = $2;
270 $planet = $3;
271 $vara = $4;
272 $varb = $5;
273 $varc = $6;
274 $type = $7;
275 $from = $8;
276 $to = $9;
277 $amount = $10;
278 $total = $11;
280 #Strip the station id - can cause problems searching for player id
281 $from =~ s/StationId\(\d+\)//g;
282 $to =~ s/StationId\(\d+\)//g;
284 # If it's a named account, strip the name out
285 $from =~ s/named account //;
286 $to =~ s/named account //;
288 # Extract player Id number
289 $from =~ s/.*\((\d+)\).*/$1/ if($from =~ /Player/);
290 $to =~ s/.*\((\d+)\).*/$1/ if($to =~ /Player/);
292 # Special case where player has " from " in store title
293 if($type =~ /Player/)
295 $type =~ s/(.*) from /$1/;
296 $from =~ s/.*\((\d+)\).*/$1/;
299 # Add into the approproiate hash
300 if(exists $player_hash{$from})
302 $money_hash = $player_hash{$from};
303 &put_into($to, $amount, ($day." ".$time), 0);
306 if(exists $player_hash{$to})
308 $money_hash = $player_hash{$to};
309 &put_into($from, $amount, ($day." ".$time), 1);
314 else
316 print "$_\n";
317 die "Error in log file format.\n";
321 # Check counter
322 ++$cnt;
323 last if($cnt == $max_cnt);
326 close (MONEY);
328 #update money hash
329 foreach my $player (keys %player_hash)
331 $money_hash = $player_hash{$player};
333 $total_in = $big_zero;
334 $total_out = $big_zero;
335 $num_total_in = $big_zero;
336 $num_total_out = $big_zero;
338 if(!$abridged)
340 print "Transactions for user $player_id:\n";
341 print "---------------------------------\n\n";
342 print "\tTransactions:\n";
343 printf "\t%-34s%-8s%-12s%-24s%-8s%-12s%-24s\n", "Player Id:", "# To:", "Amt To:", "Last Tm To", "# Fr:", "Amt Fr:", "Last Tm Fr";
344 printf "\t%-34s%-8s%-12s%-24s%-8s%-12s%-24s\n", "----------", "-----", "-------", "----------", "-----", "-------", "----------";
346 display_money_chart();
348 print "\n";
349 print "Total money given to $player_id: $total_in\n";
350 print "Total money $player_id gave: $total_out\n";
351 print "\nFinished in ".(time - $start_time)." seconds.\n";
353 else
355 print "Information for player id: $player\n";
356 printf "%s\t%s\t%s\t%s\t%s\t%s\n", "To:", "# To:", "From:", "# From", "Delta:", "Account:";
357 display_money_chart();
358 $str_out = sprintf "\n%s\t%s\t%s\t%s\t%s\t%s\n", $total_in, $num_total_in, $total_out, $num_total_out, ($total_in - $total_out), "Total";
359 $str_out =~ s/\+//g;
360 print $str_out;
362 print "\n";