]> ruin.nu Git - ndwebbie.git/blob - raids.pl
4480d6bff2a13ba74a3797b3532ba4d0b3b6f268
[ndwebbie.git] / raids.pl
1 #**************************************************************************
2 #   Copyright (C) 2006 by Michael Andreen <harvATruinDOTnu>               *
3 #                                                                         *
4 #   This program is free software; you can redistribute it and/or modify  *
5 #   it under the terms of the GNU General Public License as published by  *
6 #   the Free Software Foundation; either version 2 of the License, or     *
7 #   (at your option) any later version.                                   *
8 #                                                                         *
9 #   This program is distributed in the hope that it will be useful,       *
10 #   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12 #   GNU General Public License for more details.                          *
13 #                                                                         *
14 #   You should have received a copy of the GNU General Public License     *
15 #   along with this program; if not, write to the                         *
16 #   Free Software Foundation, Inc.,                                       *
17 #   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
18 #**************************************************************************/
19
20 use strict;
21 use POSIX;
22 our $BODY;
23 our $DBH;
24 our $LOG;
25 our $XML;
26
27
28 sub generateClaimXml {
29         my ($raid, $from, $target) = @_;
30
31         my ($timestamp) = $DBH->selectrow_array("SELECT MAX(modified)::timestamp AS modified FROM raid_targets");
32         $BODY->param(Timestamp => $timestamp);
33         if ($target){
34                 $target = "r.id = $target";
35                 $_ = listTargets();
36                 $BODY->param(TargetList => $_);
37         }else{
38                 $target = "r.raid = $raid->{id}";
39         }
40
41         if ($from){
42                 $from = "AND modified > '$from'";
43         }
44         my $targets = $DBH->prepare(qq{SELECT r.id,r.planet FROM raid_targets r WHERE $target $from});
45         $targets->execute;
46         my $claims =  $DBH->prepare(qq{ SELECT username,joinable,launched FROM raid_claims
47                 NATURAL JOIN users WHERE target = ? AND wave = ?});
48         my @targets;
49         while (my $target = $targets->fetchrow_hashref){
50                 my %target;
51                 $target{Id} = $target->{id};
52                 $target{Coords} = $target->{id};
53                 my @waves;
54                 for (my $i = 1; $i <= $raid->{waves}; $i++){
55                         my %wave;
56                         $wave{Id} = $i;
57                         $claims->execute($target->{id},$i);
58                         my $joinable = 0;
59                         my $claimers;
60                         if ($claims->rows != 0){
61                                 my $owner = 0;
62                                 my @claimers;
63                                 while (my $claim = $claims->fetchrow_hashref){
64                                         $owner = 1 if ($ND::USER eq $claim->{username});
65                                         $joinable = 1 if ($claim->{joinable});
66                                         $claim->{username} .= '*' if ($claim->{launched});
67                                         push @claimers,$claim->{username};
68                                 }
69                                 $claimers = join '/', @claimers;
70                                 if ($owner){
71                                         $wave{Command} = 'Unclaim';
72                                         if ($raid->{released_coords}){
73                                                 $target{Coords} = $DBH->selectrow_array('SELECT coords(x,y,z) FROM current_planet_stats WHERE id = ?',undef,$target->{planet});
74                                         }
75                                 }elsif ($joinable){
76                                         $wave{Command} = 'Join';
77                                 }else{
78                                         $wave{Command} = 'none';
79                                 }
80                         }else{
81                                 #if (!isset($planet) || ($target->value/$planet->value > 0.4 || $target->score/$planet->score > 0.4))
82                                 $wave{Command} = 'Claim';
83                         }
84                         $wave{Claimers} = $claimers;
85                         $wave{Joinable} = $joinable;
86                         push @waves,\%wave;
87                 }
88                 $target{Waves} = \@waves;
89                 push @targets,\%target;
90         }
91         $BODY->param(Targets => \@targets);
92 }
93
94 my $raid;
95 if (param('raid') =~ /^(\d+)$/){
96         my $query = $DBH->prepare(q{SELECT id,tick,waves,message,released_coords FROM raids WHERE id = ? AND open AND not removed AND id IN (SELECT raid FROM raid_access NATURAL JOIN groupmembers WHERE uid = ?)});
97         $raid = $DBH->selectrow_hashref($query,undef,$1,$ND::UID);
98 }
99
100 if (param('target') =~ /^(\d+)$/ && param('wave') =~ /^(\d+)$/){
101         my $target = param('target');
102         my $wave = param('wave');
103         
104         my $findtarget = $DBH->prepare("SELECT rt.id FROM raid_targets rt NATURAL JOIN raid_access ra NATURAL JOIN groupmembers where uid = ? AND id = ?");
105         my $result = $DBH->selectrow_array($findtarget,undef,$ND::UID,$target);
106         if ($result != $target){
107                 die("You don't have access to that target");
108         }
109
110         $DBH->begin_work;
111         if (param('cmd') eq 'Claim'){
112                 my $claims = $DBH->prepare(qq{SELECT username FROM raid_claims NATURAL JOIN users WHERE target = ? AND wave = ?});
113                 $claims->execute($target,$wave);
114                 if ($claims->rows == 0){
115                         my $query = $DBH->prepare(q{INSERT INTO raid_claims (target,uid,wave) VALUES(?,?,?)});
116                         if($query->execute($target,$ND::UID,$wave)){
117                                 $LOG->execute($ND::UID,"Claimed target $target wave $wave.");
118                         }
119                 }
120         }
121         if (param('cmd') eq 'Join'){
122                 my $claims = $DBH->prepare(qq{SELECT username FROM raid_claims
123                         NATURAL JOIN users WHERE target = ? AND wave = ? AND
124                         joinable = TRUE});
125                 $claims->execute($target,$wave);
126                 if ($claims->rows != 0){
127                         my $query = $DBH->prepare(q{INSERT INTO raid_claims (target,uid,wave,joinable) VALUES(?,?,?,TRUE)});
128                         if($query->execute($target,$ND::UID,$wave)){
129                                 $LOG->execute($ND::UID,"Joined target $target wave $wave.");
130                         }
131                 }
132         }
133         if (param('joinable') =~ /(TRUE|FALSE)/){
134                 my $claims = $DBH->prepare(qq{SELECT username FROM raid_claims NATURAL JOIN users WHERE target = ? AND wave = ? AND uid = ?});
135                 $claims->execute($target,$wave,$ND::UID);
136                 if ($claims->rows != 0){
137                         $DBH->do(q{UPDATE raid_claims SET joinable = ? WHERE target = ? AND wave = ?},undef,$1,$target,$wave)
138                 }
139         }
140         if (param('cmd') eq 'Unclaim'){
141                 my $query = $DBH->prepare(qq{DELETE FROM raid_claims WHERE target = ? AND uid = ? AND wave = ?});
142                 if ($query->execute($target,$ND::UID,$wave)){
143                         $LOG->execute($ND::UID,"Unclaimed target $target wave $wave.");
144                 }
145         }
146         $DBH->commit;
147         if ($XML && $raid){
148                 generateClaimXml($raid,undef,$target);
149         }
150 }
151 if ($XML && $raid && param('cmd') eq 'update' ){
152         my $from;
153         if (param('from') =~ /^[-\d\ \:\.]+$/){
154                 $from = param('from');
155         }
156         generateClaimXml($raid,$from);
157 }
158 if ($XML && param('cmd') eq 'gettargets' ){
159         $_ = listTargets();
160         $BODY->param(TargetList => $_);
161 }
162
163 unless ($XML){
164         $ND::TEMPLATE->param(TITLE => 'Raids');
165         #$ND::TEMPLATE->param(HEADER => '<script type="text/javascript" src="raid.js"></script>');
166         if ($raid){#We have a raid, so list all targets
167                 $BODY->param(Raid => $raid->{id});
168                 $BODY->param(Ajax => $ND::AJAX);
169                 my $noingal = '';
170                 my $planet;
171                 if ($ND::PLANET){
172                         my $query = $DBH->prepare("SELECT value, score,x,y FROM current_planet_stats WHERE id = ?");
173                         $planet = $DBH->selectrow_hashref($query,undef,$ND::PLANET);
174                         $noingal = "AND NOT (x = $planet->{x} AND y = $planet->{y})";
175                 }
176                 $BODY->param(Message => parseMarkup($raid->{message}));
177                 $BODY->param(LandingTick => parseMarkup($raid->{tick}));
178                 my $targetquery = $DBH->prepare(qq{SELECT r.id, r.planet, size, score, value, coords(p.x,p.y,p.z), race, p.value - p.size*200 -coalesce(c.metal+c.crystal+c.eonium,0)/150 - coalesce(c.structures,(SELECT avg(structures) FROM covop_targets)::int)*1500 AS fleetvalue,(c.metal+c.crystal+c.eonium)/100 AS resvalue, comment
179 FROM current_planet_stats p 
180         JOIN raid_targets r ON p.id = r.planet 
181         LEFT OUTER JOIN covop_targets c ON p.id = c.planet
182 WHERE r.raid = ?
183         $noingal
184 ORDER BY size});
185                 $targetquery->execute($raid->{id});
186                 my @targets;
187                 while (my $target = $targetquery->fetchrow_hashref){
188                         my %target;
189                         $target{Id} = $target->{id};
190                         $target{Race} = $target->{race};
191                         $target{Ajax} = $ND::AJAX;
192                         my $num = pow(10,length($target->{score})-2);
193                         $target{Score} = ceil($target->{score}/$num)*$num;
194                         $num = pow(10,length($target->{value})-2);
195                         $target{Value} = ceil($target->{value}/$num)*$num;
196                         $num = pow(10,length($target->{size})-2);
197                         $target{Size} = floor($target->{size}/$num)*$num;
198                         $num = pow(10,length($target->{fleetvalue})-2);
199                         $target{FleetValue} = floor($target->{fleetvalue}/$num)*$num;
200                         $num = pow(10,length($target->{resvalue})-2);
201                         $target{ResValue} = floor($target->{resvalue}/$num)*$num;
202                         $target{comment} = parseMarkup($target->{comment}) if ($target->{comment});
203
204                         my $scans = $DBH->prepare(q{SELECT DISTINCT ON (type) type, tick, scan FROM scans 
205                                 WHERE planet = ? AND type ~ 'Unit|Planet|Military|.* Analysis' AND tick + 24 > tick()
206                                 GROUP BY type, tick, scan ORDER BY type ,tick DESC});
207                         $scans->execute($target->{planet});
208                         my %scans;
209                         while (my $scan = $scans->fetchrow_hashref){
210                                 $scans{$scan->{type}} = $scan;
211                         }
212
213                         my @scans;
214                         for my $type ('Planet','Unit','Military','Surface Analysis','Technology Analysis'){
215                                 next unless exists $scans{$type};
216                                 my $scan = $scans{$type};
217                                 if ($ND::TICK - $scan->{tick} > 5){
218                                         $scan->{scan} =~ s{<table( cellpadding="\d+")?>}{<table$1 class="old">};
219                                 }
220                                 if ($type eq 'Planet'){
221                                         $target{PlanetScan} = $scan->{scan};
222                                         next;
223                                 }
224                                 push @scans,{Scan => $scan->{scan}};
225                         }
226                         $target{Scans} = \@scans;
227
228                         my @roids;
229                         my @claims;
230                         my $size = $target{Size};
231                         for (my $i = 1; $i <= $raid->{waves}; $i++){
232                                 my $roids = floor(0.25*$size);
233                                 $size -= $roids;
234                                 my $xp;
235                                 if ($planet){
236                                         $xp = max(0,floor($roids * 10 * (min(2,$target{Score}/$planet->{score}) + min(2,$target{Value}/$planet->{value})-1)));
237                                 }
238                                 push @roids,{Wave => $i, Roids => $roids, XP => $xp};
239                                 if ($ND::AJAX){
240                                         push @claims,{Wave => $i, Target => $target{Id}}
241                                 }else{
242                                         push @claims,{Wave => $i, Target => $target{Id}, Command => 'Claim'
243                                                 , Owner => 1, Raid => $raid->{id}, Joinable => 0};
244                                 }
245                         }
246                         $target{Roids} = \@roids;
247                         $target{Claims} = \@claims;
248
249                         push @targets,\%target;
250                 }
251                 $BODY->param(Targets => \@targets);
252         }else{#list raids if we haven't chosen one yet
253                 my $query = $DBH->prepare(q{SELECT id,released_coords FROM raids WHERE open AND not removed AND
254 id IN (SELECT raid FROM raid_access NATURAL JOIN groupmembers WHERE uid = ?)});
255                 $query->execute($ND::UID);
256                 my @raids;
257                 while (my $raid = $query->fetchrow_hashref){
258                         push @raids,{Raid => $raid->{id}, ReleasedCoords => $raid->{released_coords}, isBC => isBC()};
259                 }
260                 $BODY->param(Raids => \@raids);
261
262                 if (isBC()){
263                         my $query = $DBH->prepare(q{SELECT id,open FROM raids WHERE not removed AND (not open 
264 OR id NOT IN (SELECT raid FROM raid_access NATURAL JOIN groupmembers WHERE uid = ?))});
265                         $query->execute($ND::UID);
266                         my @raids;
267                         while (my $raid = $query->fetchrow_hashref){
268                                 push @raids,{Raid => $raid->{id}, Open => $raid->{open}};
269                         }
270                         $BODY->param(ClosedRaids => \@raids);
271                 }
272         }
273 }
274 1;