]> git.pond.sub.org Git - empserver/blob - src/lib/common/wantupd.c
b3628c4363284ed0b2cd49636ff8d9e939327bec
[empserver] / src / lib / common / wantupd.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2006, 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 files README, COPYING and CREDITS in the root of the source
23  *  tree for related information and legal notices.  It is expected
24  *  that future 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 <fcntl.h>
37 #include <stdio.h>
38 #if defined(_WIN32) && !defined(__GNUC__)
39 #include <io.h>
40 #endif
41 #include <time.h>
42 #if !defined(_WIN32)
43 #include <unistd.h>
44 #endif
45 #include "file.h"
46 #include "misc.h"
47 #include "nat.h"
48 #include "optlist.h"
49 #include "prototypes.h"
50 #include "wantupd.h"
51
52 void
53 update_policy_check(void)
54 {
55     if (update_policy < 0)
56         update_policy = UDP_DEFAULT;
57     if (update_policy > UDP_MAX)
58         update_policy = UDP_DEFAULT;
59     if (update_demandpolicy < 0)
60         update_demandpolicy = UDDEM_DEFAULT;
61     if (update_demandpolicy > UDDEM_MAX)
62         update_demandpolicy = UDDEM_DEFAULT;
63     if (update_wantmin < 1)
64         update_wantmin = 1;
65     if (update_wantmin > MAXNOC)
66         update_wantmin = MAXNOC;
67     if (blitz_time < 1)
68         blitz_time = 1;
69 }
70
71 static int
72 demand_update_time(time_t *now)
73 {
74     struct tm *tm;
75
76     tm = localtime(now);
77     return is_daytime_allowed(60 * tm->tm_hour + tm->tm_min,
78                               update_demandtimes);
79 }
80
81 /* When is the next regularly scheduled update from now. */
82 static void
83 regular_update_time(time_t *now, time_t *tim, time_t *delta)
84 {
85     time_t tw;
86     int secs_per_update;
87
88     tw = *now + adj_update;
89     secs_per_update = etu_per_update * s_p_etu;
90     *delta = secs_per_update - (tw % secs_per_update);
91     *tim = *now + *delta;
92 }
93
94 /* Is this a valid time for a scheduled update. */
95 static int
96 scheduled_update_time(time_t *now)
97 {
98     struct tm *tm;
99
100     tm = localtime(now);
101     return is_daytime_near(60 * tm->tm_hour + tm->tm_min,
102                            update_times, hourslop);
103 }
104
105 static int
106 next_scheduled_time(time_t *now, time_t *tim, time_t *delta)
107 {
108     struct tm *tm;
109     int d;
110
111     tm = localtime(now);
112     d = min_to_next_daytime(60 * tm->tm_hour + tm->tm_min, update_times);
113     if (d < 0)
114         return 0;
115     *delta = 60 * d;
116     *tim = *now + *delta - tm->tm_sec;
117     return 1;
118 }
119
120 int
121 demand_update_want(int *want, int *pop, int which)
122 {
123     natid cn;
124     struct natstr *natp;
125     int totpop;
126     int totwant;
127     int whichwants;
128
129     whichwants = totpop = totwant = 0;
130     for (cn = 1; 0 != (natp = getnatp(cn)); cn++) {
131         /* Only countries which are normal. */
132         /* Should probably include sanctuaries ..... */
133         if (natp->nat_stat == STAT_ACTIVE) {
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     demand_update_want(&want, &pop, 0);
158     if (want < update_wantmin) {
159         logerror("no demand update, want = %d, min = %d",
160                  want, update_wantmin);
161         return 0;
162     }
163
164     time(&now);
165     if (!demand_update_time(&now)) {
166         logerror("no demand update, not within hours allowed.");
167         return 0;
168     }
169
170
171     veto = 0;
172     for (cn = 1; 0 != (natp = getnatp(cn)); cn++) {
173         if (natp->nat_stat == STAT_ACTIVE) {
174             if (natp->nat_missed >= update_missed)
175                 veto = cn;
176         }
177     }
178
179     if (veto) {
180         logerror("no demand update, %d has missed more than %d updates",
181                  veto, update_missed);
182         return 0;
183     }
184
185     return 1;
186 }
187
188 /*
189  * Check if enough countries want an update,
190  * and if demand updates are allowed now.
191  */
192 int
193 demandupdatecheck(void)
194 {
195     if (UDDEM_COMSET != update_demandpolicy) {
196         logerror("no demand update, not policy.");
197         return 0;
198     }
199
200     return demand_check();
201 }
202
203 /*
204  * Is it time for a regular or scheduled update?
205  * As well, if none of the above, check to see if
206  * a demand update can occur.
207  */
208 int
209 updatetime(time_t *now)
210 {
211     if (opt_BLITZ && update_policy == UDP_BLITZ) {
212         logerror("BLITZ Update.");
213         return 1;
214     }
215
216     if (UDP_NORMAL == update_policy) {
217         logerror("Regular update, etu type.");
218         return 1;
219     }
220
221     if (UDP_TIMES == update_policy) {
222         if (scheduled_update_time(now)) {
223             logerror("Scheduled update.");
224             return 1;
225         }
226     }
227     if (opt_DEMANDUPDATE) {
228         if (demand_check()) {
229             logerror("Demand update, at check time.");
230             return 1;
231         }
232     }
233     return 0;
234 }
235
236 /*
237  * Return the time, and delta seconds, of the next update.
238  * If the policy is no regular updates, return the time of
239  * the next possible check.
240  */
241 void
242 next_update_time(time_t *now, time_t *tim, time_t *delta)
243                         /* From when */
244                         /* Time of next update */
245                         /* Seconds till next update */
246 {
247     time_t stim, sdelta;
248
249     switch (update_policy) {
250     case UDP_NORMAL:
251         regular_update_time(now, tim, delta);
252         break;
253     case UDP_TIMES:
254         if (!next_scheduled_time(now, tim, delta))
255             regular_update_time(now, tim, delta);
256         break;
257     case UDP_BLITZ:
258         *delta = (blitz_time * 60) - (*now % (blitz_time * 60));
259         *tim = *now + *delta;
260         break;
261     case UDP_NOREG:
262     default:
263         regular_update_time(now, tim, delta);
264         if (next_scheduled_time(now, &stim, &sdelta)) {
265             if (*delta > sdelta) {
266                 *delta = sdelta;
267                 *tim = stim;
268             }
269         }
270         break;
271     }
272 }
273
274 void
275 next_update_check_time(time_t *now, time_t *tim, time_t *delta)
276                         /* From when */
277                         /* Time of next update */
278                         /* Seconds till next update check */
279 {
280     time_t stim, sdelta;
281
282     switch (update_policy) {
283     case UDP_NORMAL:
284         regular_update_time(now, tim, delta);
285         break;
286     case UDP_BLITZ:
287         *delta = (blitz_time * 60) - (*now % (blitz_time * 60));
288         *tim = *now + *delta;
289         break;
290     case UDP_TIMES:
291     case UDP_NOREG:
292     default:
293         regular_update_time(now, tim, delta);
294         if (next_scheduled_time(now, &stim, &sdelta)) {
295             if (*delta > sdelta) {
296                 *delta = sdelta;
297                 *tim = stim;
298             }
299         }
300     }
301 }
302
303 int
304 updates_disabled(void)
305 {
306     int fd;
307
308     if ((fd = open(disablefil, O_RDONLY, 0)) < 0)
309         return 0;
310     close(fd);
311     return 1;
312 }