]> git.pond.sub.org Git - empserver/blob - src/lib/common/wantupd.c
Import of Empire 4.2.12
[empserver] / src / lib / common / wantupd.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2000, 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 <stdio.h>
35 #if !defined(_WIN32)
36 #include <unistd.h>
37 #endif
38 #include "misc.h"
39 #include "nat.h"
40 #include "file.h"
41 #include "keyword.h"
42 #include "wantupd.h"
43 #include "optlist.h"
44 #include "common.h"
45
46 #include <sys/types.h>
47 #include <fcntl.h>
48 #if defined(Rel4) || defined(_WIN32)
49 #include <time.h>
50 #else /* Rel4 */
51 #include <sys/time.h>
52 #endif /* Rel4 */
53
54 void
55 update_policy_check(void)
56 {
57         extern int update_policy,update_demandpolicy;
58         extern int update_wantmin,blitz_time;
59
60         if (update_policy < 0) update_policy = UDP_DEFAULT;
61         if (update_policy > UDP_MAX) update_policy = UDP_DEFAULT;
62         if (update_demandpolicy < 0) update_demandpolicy = UDDEM_DEFAULT;
63         if (update_demandpolicy > UDDEM_MAX)
64                 update_demandpolicy = UDDEM_DEFAULT;
65         if (update_wantmin < 0) update_wantmin = 0;
66         if (update_wantmin > MAXNOC) update_wantmin = MAXNOC;
67         if (blitz_time < 0) blitz_time = 0;
68 }
69
70 static int
71 demand_update_time(time_t *now)
72 {
73         struct tm *tm;
74         s_char *p;
75         int curtime;
76         int hour[2];
77         extern s_char *update_demandtimes;
78
79         tm = localtime(now);
80         curtime = tm->tm_min + tm->tm_hour * 60;
81         p=update_demandtimes;
82         if (*p == 0) return(1);
83         while (NULL != (p = kw_parse(CF_TIMERANGE, p, &hour[0]))) {
84                 if (curtime >= hour[0] && curtime < hour[1])
85                         return(1);
86         }
87         return(0);
88 }
89
90 /* When is the next regularly scheduled update from now. */
91 static void
92 regular_update_time(time_t *now, time_t *tim, time_t *delta)
93 {
94         extern int s_p_etu;
95         extern int etu_per_update;
96         extern int adj_update;
97         s_char *p;
98         time_t tw;
99         int secs_per_update;
100
101         tw = *now + adj_update;
102         secs_per_update = etu_per_update * s_p_etu;
103         *delta = secs_per_update - (tw % secs_per_update);
104         *tim = *now + *delta;
105 }
106
107 /* Is this a valid time for a scheduled update. */
108 static int
109 scheduled_update_time(time_t *now, int *which)
110 {
111         struct tm *tm;
112         s_char *p, *p1;
113         int curtime;
114         int hour;
115         extern int hourslop;
116         extern s_char *update_times;
117
118         *which = -1;
119         p=update_times;
120         if (*p == 0) return(0);
121
122         tm = localtime(now);
123         curtime = tm->tm_min + tm->tm_hour * 60;
124         while (NULL != (p = kw_parse(CF_TIME, p, &hour))) {
125                 (*which) ++;
126                 if (curtime >= hour &&
127                     curtime < hour+hourslop)
128                         return(1);
129         }
130
131         return 0;
132 }
133
134 static int
135 next_scheduled_time(time_t *now, time_t *tim, time_t *delta)
136 {
137         struct tm *tm;
138         s_char *p;
139         int curtime;
140         int hour;
141         int mintime;
142         extern s_char *update_times;
143
144         p=update_times;
145         if (*p == 0) return(0);
146
147         tm = localtime(now);
148         curtime = tm->tm_min + tm->tm_hour * 60; /* now - in minutes */
149         mintime = curtime + 24*60+1;            /* start with now + 1 day */
150         while (NULL != (p = kw_parse(CF_TIME, p, &hour))) {
151                 if (hour <= curtime)
152                         hour += 24 * 60;        /* this must be tomorrow */
153                 if (hour < mintime)
154                         mintime = hour;         /* this is best bet so far */
155         }
156         *delta = 60*(mintime - curtime);
157         *tim = *now + *delta - tm->tm_sec;
158         return(1);
159 }
160
161 int
162 demand_update_want(int *want, int *pop, int which)
163 {
164         natid   cn;
165         struct  natstr *natp;
166         int     totpop;
167         int     totwant;
168         int     whichwants;
169
170         whichwants = totpop = totwant = 0;
171         for (cn = 1; 0 != (natp = getnatp(cn)); cn++) {
172                 /* Only countries which are normal. */
173                 /* Should probably include sanctuaries ..... */
174                 if (((natp->nat_stat & NORM) == NORM) &&
175                         ((natp->nat_stat & GOD) != GOD)) { 
176                         totpop++;
177                         if ((natp->nat_update & WUPD_WANT) == WUPD_WANT) {
178                                 totwant++;
179                                 if (which == cn)
180                                         whichwants++;
181                         }
182                 }
183         }
184         *want = totwant;
185         *pop = totpop;
186         return(whichwants);
187 }
188
189 static int
190 demand_check(void)
191 {
192         extern int update_wantmin,update_missed;
193         struct  natstr *natp;
194         int want, pop, cn, veto;
195         time_t    now;
196         time_t    cur;
197         extern long     last_demand_update;
198
199         time(&cur);
200
201 /*
202         if (last_demand_update == 0){
203                 natp=getnatp(0);
204                 last_demand_update = natp->nat_reserve;
205         }
206
207         logerror("last_demand_update = %d\n",last_demand_update);
208         logerror("update_between = %d\n",update_between());
209         logerror("now = %d\n",cur);
210         diff = (cur-(last_demand_update + update_between()));
211         logerror("diff = %d\n",diff);
212         if (diff >= 0){
213                 logerror("Forced update!\n");
214                 last_demand_update = cur;
215                 for (cn = 1; natp = getnatp(cn); cn++){
216                         if (((natp->nat_stat & NORM) == NORM)  &&
217                                 ((natp->nat_stat & GOD) != GOD)){
218                                 natp->nat_missed = 0;
219                         }
220                 }
221                 return(1);
222         }
223
224         logerror("No forced update!\n");
225 */
226         if (0 == update_wantmin) {
227                 logerror("no demand update allowed, wantmin = 0");
228                 return(0);
229         }
230
231         demand_update_want(&want, &pop, 0);
232         if (want < update_wantmin) {
233                 logerror("no demand update, want = %d, min = %d",
234                                 want, update_wantmin);
235                 return(0);
236         }
237
238         time(&now);
239         if (!demand_update_time(&now)) {
240                 logerror("no demand update, not within hours allowed.");
241                 return(0);
242         }
243
244
245         veto=0;
246         for (cn = 1; 0 != (natp = getnatp(cn)); cn++){
247                 if (((natp->nat_stat & NORM) == NORM)  &&
248                         ((natp->nat_stat & GOD) != GOD)){
249                         if (natp->nat_missed >= update_missed)
250                                 veto=cn+1;
251                 }
252         }
253
254         if (veto){
255                 logerror("no demand update, %d has missed more than %d updates",
256                         veto-1, update_missed);
257                 return(0);
258         }
259
260         last_demand_update = cur;
261         natp=getnatp(0);
262         /* A dumb way to do it, but simple */
263         last_demand_update = natp->nat_reserve;
264         return(1);
265 }
266
267 /* Check if enough countries want an update,
268  * and if demand updates are allowed now.
269  */
270 int
271 demandupdatecheck(void)
272 {
273         extern int update_demandpolicy;
274
275         if (UDDEM_COMSET != update_demandpolicy) {
276                 logerror("no demand update, not policy.");
277                 return(0);
278         }
279
280         return(demand_check());
281 }
282
283 /* Is it time for a regular or scheduled update?
284  * As well, if none of the above, check to see if
285  * a demand update can occur.
286  */
287 int
288 updatetime(time_t *now)
289 {
290         extern int update_policy;
291         int     which;
292
293         if (opt_BLITZ && update_policy == UDP_BLITZ) {
294                 logerror("BLITZ Update.");
295                 return(1);
296         }
297
298         if (UDP_NORMAL == update_policy) {
299                 logerror("Regular update, etu type.");
300                 return(1);
301         }
302
303         if (UDP_TIMES == update_policy) {
304                 if (scheduled_update_time(now, &which)) {
305                         logerror("Scheduled update, %d.", which);
306                         return(1);
307                 }
308         }
309         if (opt_DEMANDUPDATE) {
310             if (demand_check()) {
311                 logerror("Demand update, at check time.");
312                 return(1);
313             }
314         }
315         return(0);
316 }
317
318 /* Return the time, and delta seconds, of the next update.
319  * If the policy is no regular updates, return the time of
320  * the next possible check.
321  */
322 void
323 next_update_time(time_t *now, time_t *tim, time_t *delta)
324                         /* From when */
325                         /* Time of next update */
326                         /* Seconds till next update */
327 {
328         extern int update_policy;
329         time_t stim, sdelta;
330         extern int blitz_time;
331
332         switch (update_policy) {
333         case UDP_NORMAL:
334                 regular_update_time(now, tim, delta);
335                 break;
336         case UDP_TIMES:
337                 if (!next_scheduled_time(now, tim, delta))
338                         regular_update_time(now, tim, delta);
339                 break;
340         case UDP_BLITZ:
341                 *delta = (blitz_time * 60) - (*now % (blitz_time * 60));
342                 *tim = *now + *delta;
343                 break;
344
345         case UDP_NOREG:
346         default:
347                 regular_update_time(now, tim, delta);
348                 if (next_scheduled_time(now, &stim, &sdelta)) {
349                         if (*delta > sdelta) {
350                                 *delta = sdelta;
351                                 *tim = stim;
352                         }
353                 }
354                 break;
355         }
356 }
357
358 void
359 next_update_check_time(time_t *now, time_t *tim, time_t *delta)
360                         /* From when */
361                         /* Time of next update */
362                         /* Seconds till next update check */
363 {
364         extern int update_policy;
365         time_t stim, sdelta;
366         extern int blitz_time;
367
368         switch (update_policy) {
369         case UDP_NORMAL:
370                 regular_update_time(now, tim, delta);
371                 break;
372         case UDP_BLITZ:
373                 *delta = (blitz_time * 60) - (*now % (blitz_time * 60));
374                 *tim = *now + *delta;
375                 break;
376         case UDP_TIMES:
377         case UDP_NOREG:
378         default:
379                 regular_update_time(now, tim, delta);
380                 if (next_scheduled_time(now, &stim, &sdelta)) {
381                         if (*delta > sdelta) {
382                                 *delta = sdelta;
383                                 *tim = stim;
384                         }
385                 }
386         }
387 }
388
389 int
390 updates_disabled(void)
391 {
392         extern  s_char *disablefil;
393         int     fd;
394
395         if ((fd = open(disablefil, O_RDONLY, 0)) < 0)
396                 return 0;
397         close(fd);
398         return 1;
399 }