]> git.pond.sub.org Git - empserver/blob - src/lib/common/wantupd.c
(demand_check): Slight simplification.
[empserver] / src / lib / common / wantupd.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2005, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                           Ken Stevens, Steve McClure
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  ---
21  *
22  *  See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23  *  related information and legal notices. It is expected that any future
24  *  projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  wantupd.c: Check to se if an update is wanted and/or allowed.
29  * 
30  *  Known contributors to this file:
31  *     Doug Hay, 1990
32  */
33
34 #include <config.h>
35
36 #include <stdio.h>
37 #if !defined(_WIN32)
38 #include <unistd.h>
39 #endif
40 #include "misc.h"
41 #include "nat.h"
42 #include "file.h"
43 #include "wantupd.h"
44 #include "optlist.h"
45 #include "common.h"
46
47 #include <sys/types.h>
48 #include <fcntl.h>
49 #include <time.h>
50
51 void
52 update_policy_check(void)
53 {
54     if (update_policy < 0)
55         update_policy = UDP_DEFAULT;
56     if (update_policy > UDP_MAX)
57         update_policy = UDP_DEFAULT;
58     if (update_demandpolicy < 0)
59         update_demandpolicy = UDDEM_DEFAULT;
60     if (update_demandpolicy > UDDEM_MAX)
61         update_demandpolicy = UDDEM_DEFAULT;
62     if (update_wantmin < 0)
63         update_wantmin = 0;
64     if (update_wantmin > MAXNOC)
65         update_wantmin = MAXNOC;
66     if (blitz_time < 0)
67         blitz_time = 0;
68 }
69
70 static int
71 demand_update_time(time_t *now)
72 {
73     struct tm *tm;
74
75     tm = localtime(now);
76     return is_daytime_allowed(60 * tm->tm_hour + tm->tm_min,
77                               update_demandtimes);
78 }
79
80 /* When is the next regularly scheduled update from now. */
81 static void
82 regular_update_time(time_t *now, time_t *tim, time_t *delta)
83 {
84     time_t tw;
85     int secs_per_update;
86
87     tw = *now + adj_update;
88     secs_per_update = etu_per_update * s_p_etu;
89     *delta = secs_per_update - (tw % secs_per_update);
90     *tim = *now + *delta;
91 }
92
93 /* Is this a valid time for a scheduled update. */
94 static int
95 scheduled_update_time(time_t *now)
96 {
97     struct tm *tm;
98
99     tm = localtime(now);
100     return is_daytime_near(60 * tm->tm_hour + tm->tm_min,
101                            update_times, hourslop);
102 }
103
104 static int
105 next_scheduled_time(time_t *now, time_t *tim, time_t *delta)
106 {
107     struct tm *tm;
108     int d;
109
110     tm = localtime(now);
111     d = min_to_next_daytime(60 * tm->tm_hour + tm->tm_min, update_times);
112     if (d < 0)
113         return 0;
114     *delta = 60 * d;
115     *tim = *now + *delta - tm->tm_sec;
116     return 1;
117 }
118
119 int
120 demand_update_want(int *want, int *pop, int which)
121 {
122     natid cn;
123     struct natstr *natp;
124     int totpop;
125     int totwant;
126     int whichwants;
127
128     whichwants = totpop = totwant = 0;
129     for (cn = 1; 0 != (natp = getnatp(cn)); cn++) {
130         /* Only countries which are normal. */
131         /* Should probably include sanctuaries ..... */
132         if (((natp->nat_stat & NORM) == NORM) &&
133             ((natp->nat_stat & GOD) != GOD)) {
134             totpop++;
135             if ((natp->nat_update & WUPD_WANT) == WUPD_WANT) {
136                 totwant++;
137                 if (which == cn)
138                     whichwants++;
139             }
140         }
141     }
142     *want = totwant;
143     *pop = totpop;
144     return whichwants;
145 }
146
147 static int
148 demand_check(void)
149 {
150     struct natstr *natp;
151     int want, pop, cn, veto;
152     time_t now;
153     time_t cur;
154
155     time(&cur);
156
157     if (0 == update_wantmin) {
158         logerror("no demand update allowed, wantmin = 0");
159         return 0;
160     }
161
162     demand_update_want(&want, &pop, 0);
163     if (want < update_wantmin) {
164         logerror("no demand update, want = %d, min = %d",
165                  want, update_wantmin);
166         return 0;
167     }
168
169     time(&now);
170     if (!demand_update_time(&now)) {
171         logerror("no demand update, not within hours allowed.");
172         return 0;
173     }
174
175
176     veto = 0;
177     for (cn = 1; 0 != (natp = getnatp(cn)); cn++) {
178         if (((natp->nat_stat & NORM) == NORM) &&
179             ((natp->nat_stat & GOD) != GOD)) {
180             if (natp->nat_missed >= update_missed)
181                 veto = cn;
182         }
183     }
184
185     if (veto) {
186         logerror("no demand update, %d has missed more than %d updates",
187                  veto, update_missed);
188         return 0;
189     }
190
191     return 1;
192 }
193
194 /* Check if enough countries want an update,
195  * and if demand updates are allowed now.
196  */
197 int
198 demandupdatecheck(void)
199 {
200     if (UDDEM_COMSET != update_demandpolicy) {
201         logerror("no demand update, not policy.");
202         return 0;
203     }
204
205     return demand_check();
206 }
207
208 /* Is it time for a regular or scheduled update?
209  * As well, if none of the above, check to see if
210  * a demand update can occur.
211  */
212 int
213 updatetime(time_t *now)
214 {
215     if (opt_BLITZ && update_policy == UDP_BLITZ) {
216         logerror("BLITZ Update.");
217         return 1;
218     }
219
220     if (UDP_NORMAL == update_policy) {
221         logerror("Regular update, etu type.");
222         return 1;
223     }
224
225     if (UDP_TIMES == update_policy) {
226         if (scheduled_update_time(now)) {
227             logerror("Scheduled update.");
228             return 1;
229         }
230     }
231     if (opt_DEMANDUPDATE) {
232         if (demand_check()) {
233             logerror("Demand update, at check time.");
234             return 1;
235         }
236     }
237     return 0;
238 }
239
240 /* Return the time, and delta seconds, of the next update.
241  * If the policy is no regular updates, return the time of
242  * the next possible check.
243  */
244 void
245 next_update_time(time_t *now, time_t *tim, time_t *delta)
246                         /* From when */
247                         /* Time of next update */
248                         /* Seconds till next update */
249 {
250     time_t stim, sdelta;
251
252     switch (update_policy) {
253     case UDP_NORMAL:
254         regular_update_time(now, tim, delta);
255         break;
256     case UDP_TIMES:
257         if (!next_scheduled_time(now, tim, delta))
258             regular_update_time(now, tim, delta);
259         break;
260     case UDP_BLITZ:
261         *delta = (blitz_time * 60) - (*now % (blitz_time * 60));
262         *tim = *now + *delta;
263         break;
264
265     case UDP_NOREG:
266     default:
267         regular_update_time(now, tim, delta);
268         if (next_scheduled_time(now, &stim, &sdelta)) {
269             if (*delta > sdelta) {
270                 *delta = sdelta;
271                 *tim = stim;
272             }
273         }
274         break;
275     }
276 }
277
278 void
279 next_update_check_time(time_t *now, time_t *tim, time_t *delta)
280                         /* From when */
281                         /* Time of next update */
282                         /* Seconds till next update check */
283 {
284     time_t stim, sdelta;
285
286     switch (update_policy) {
287     case UDP_NORMAL:
288         regular_update_time(now, tim, delta);
289         break;
290     case UDP_BLITZ:
291         *delta = (blitz_time * 60) - (*now % (blitz_time * 60));
292         *tim = *now + *delta;
293         break;
294     case UDP_TIMES:
295     case UDP_NOREG:
296     default:
297         regular_update_time(now, tim, delta);
298         if (next_scheduled_time(now, &stim, &sdelta)) {
299             if (*delta > sdelta) {
300                 *delta = sdelta;
301                 *tim = stim;
302             }
303         }
304     }
305 }
306
307 int
308 updates_disabled(void)
309 {
310     int fd;
311
312     if ((fd = open(disablefil, O_RDONLY, 0)) < 0)
313         return 0;
314     close(fd);
315     return 1;
316 }