(nreport, filereport, ncache, addfree, findfree, delete_old_news)
(init_nreport, update_main, start_server): Switch news to be sorted list with all new news items added at the end of the list. The removal of expired news items is done at update time. Closes #766755.
This commit is contained in:
parent
55e6aca9e0
commit
3d3d6755aa
4 changed files with 80 additions and 79 deletions
|
@ -546,6 +546,8 @@ extern int natarg(s_char *, s_char *);
|
|||
/* neigh.c */
|
||||
extern int neigh(coord, coord, natid);
|
||||
/* nreport.c */
|
||||
extern void delete_old_news();
|
||||
extern void init_nreport();
|
||||
extern void nreport(natid, int, natid, int);
|
||||
/* nuke.c */
|
||||
extern int nuk_postread(int, s_char *);
|
||||
|
|
|
@ -32,25 +32,35 @@
|
|||
* Steve McClure, 1997
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "news.h"
|
||||
#include "nat.h"
|
||||
#include "file.h"
|
||||
#include "empio.h"
|
||||
#include <fcntl.h>
|
||||
#include "optlist.h"
|
||||
#include "prototypes.h"
|
||||
#include "news.h"
|
||||
#include "file.h"
|
||||
#include "optlist.h"
|
||||
|
||||
static void filereport(int, int, int, int);
|
||||
#define SLOTS 5
|
||||
|
||||
struct newscache {
|
||||
struct nwsstr news;
|
||||
int id;
|
||||
};
|
||||
|
||||
static struct newscache cache[MAXNOC][SLOTS];
|
||||
static int news_tail;
|
||||
|
||||
static struct newscache *
|
||||
ncache(int actor, int event, int victim, int times);
|
||||
|
||||
void
|
||||
nreport(natid actor, int event, natid victim, int times)
|
||||
{
|
||||
int nice;
|
||||
int rel;
|
||||
struct natstr *np;
|
||||
struct natstr *natp;
|
||||
struct newscache *ncp;
|
||||
|
||||
ncp = ncache(actor, event, victim, times);
|
||||
putnews(ncp->id, &ncp->news);
|
||||
|
||||
filereport(actor, event, victim, times);
|
||||
/*
|
||||
* this is probably pretty expensive, but hopefully we
|
||||
* don't fire zillions of these things off every second.
|
||||
|
@ -65,9 +75,9 @@ nreport(natid actor, int event, natid victim, int times)
|
|||
return;
|
||||
if (!chance((double)-nice * times / 20.0))
|
||||
return;
|
||||
if ((np = getnatp(victim)) == 0)
|
||||
if ((natp = getnatp(victim)) == 0)
|
||||
return;
|
||||
if ((rel = getrel(np, actor)) < HOSTILE)
|
||||
if ((rel = getrel(natp, actor)) < HOSTILE)
|
||||
return;
|
||||
|
||||
rel = HOSTILE;
|
||||
|
@ -80,79 +90,76 @@ nreport(natid actor, int event, natid victim, int times)
|
|||
setrel(victim, actor, rel);
|
||||
}
|
||||
|
||||
struct free {
|
||||
struct free *next;
|
||||
int id;
|
||||
};
|
||||
|
||||
struct free *freelist;
|
||||
|
||||
static void
|
||||
addfree(int n)
|
||||
/*
|
||||
* Delete news articles that have expired.
|
||||
*/
|
||||
void
|
||||
delete_old_news(void)
|
||||
{
|
||||
struct free *fp;
|
||||
time_t expiry_time;
|
||||
int i, j, k;
|
||||
struct nwsstr news;
|
||||
|
||||
fp = (struct free *)malloc(sizeof(*fp));
|
||||
fp->next = freelist;
|
||||
fp->id = n;
|
||||
freelist = fp;
|
||||
/* skip over expired news */
|
||||
expiry_time = time(NULL) - days(news_keep_days);
|
||||
for (i = 0; getnews(i, &news); i++) {
|
||||
if (news.nws_when == 0 || news.nws_when >= expiry_time)
|
||||
break;
|
||||
}
|
||||
/* news id 0..I-1 have expired */
|
||||
CANT_HAPPEN(i > news_tail);
|
||||
/* no items to delete if I is equal zero */
|
||||
if (i == 0)
|
||||
return;
|
||||
|
||||
/* move unexpired news I.. to 0.., overwriting expired news */
|
||||
for (j = 0; getnews(i + j, &news); j++) {
|
||||
if (news.nws_when == 0)
|
||||
break;
|
||||
putnews(j, &news);
|
||||
}
|
||||
CANT_HAPPEN(i + j != news_tail);
|
||||
news_tail = j;
|
||||
|
||||
/* mark slots no longer in use */
|
||||
memset(&news, 0, sizeof(news));
|
||||
for (k = 0; k < i; k++)
|
||||
putnews(j + k, &news);
|
||||
|
||||
/* clear cache because moving news invalidated it */
|
||||
memset(&cache, 0, sizeof(cache));
|
||||
}
|
||||
|
||||
/*
|
||||
* snoop through the news articles looking
|
||||
* for articles which have timed out. Only
|
||||
* called when no free items left.
|
||||
* Initialize news reporting.
|
||||
* Must run between open of file EF_NEWS and first nreport().
|
||||
*/
|
||||
static void
|
||||
findfree(void)
|
||||
void
|
||||
init_nreport(void)
|
||||
{
|
||||
time_t oldnewstime;
|
||||
int n;
|
||||
int newest_item;
|
||||
struct nwsstr news;
|
||||
|
||||
oldnewstime = time(NULL) - days(news_keep_days);
|
||||
for (n = 0; getnews(n, &news); n++) {
|
||||
if (news.nws_when < oldnewstime)
|
||||
addfree(n);
|
||||
}
|
||||
if (freelist == 0) {
|
||||
if (!ef_extend(EF_NEWS, 100))
|
||||
return;
|
||||
findfree();
|
||||
for (newest_item = 0; getnews(newest_item, &news); newest_item++) {
|
||||
if (news.nws_when == 0)
|
||||
break;
|
||||
}
|
||||
news_tail = newest_item;
|
||||
}
|
||||
|
||||
static int
|
||||
nextfree(void)
|
||||
{
|
||||
struct free *fp;
|
||||
int id;
|
||||
|
||||
if (freelist == 0)
|
||||
findfree();
|
||||
if ((fp = freelist) == 0)
|
||||
return 0;
|
||||
freelist = fp->next;
|
||||
id = fp->id;
|
||||
free(fp);
|
||||
return id;
|
||||
}
|
||||
|
||||
#define SLOTS 5
|
||||
|
||||
struct newscache {
|
||||
struct nwsstr news;
|
||||
int id;
|
||||
};
|
||||
|
||||
/*
|
||||
* Look to see if the same message has been generated
|
||||
* in the last 5 minutes, if so just increment the times
|
||||
* field instead of creating a new message.
|
||||
*/
|
||||
static struct newscache *
|
||||
ncache(time_t now, int actor, int event, int victim, int times)
|
||||
ncache(int actor, int event, int victim, int times)
|
||||
{
|
||||
static struct newscache cache[MAXNOC][SLOTS];
|
||||
register struct newscache *np;
|
||||
int i;
|
||||
int oldslot;
|
||||
time_t oldtime;
|
||||
time_t now = time(NULL);
|
||||
|
||||
oldslot = -1;
|
||||
oldtime = 0x7fffffff;
|
||||
|
@ -182,17 +189,7 @@ ncache(time_t now, int actor, int event, int victim, int times)
|
|||
np->news.nws_when = now;
|
||||
np->news.nws_vrb = event;
|
||||
np->news.nws_ntm = times;
|
||||
np->id = nextfree();
|
||||
ef_ensure_space(EF_NEWS, news_tail, 100);
|
||||
np->id = news_tail++;
|
||||
return np;
|
||||
}
|
||||
|
||||
static void
|
||||
filereport(int actor, int event, int victim, int times)
|
||||
{
|
||||
struct newscache *np;
|
||||
time_t now;
|
||||
|
||||
time(&now);
|
||||
np = ncache(now, actor, event, victim, times);
|
||||
ef_write(EF_NEWS, np->id, (s_char *)&np->news);
|
||||
}
|
||||
|
|
|
@ -201,6 +201,7 @@ update_main(void *unused)
|
|||
ef_flush(EF_PLANE);
|
||||
ef_flush(EF_LAND);
|
||||
delete_old_announcements();
|
||||
delete_old_news();
|
||||
/* Clear all the telegram flags */
|
||||
for (cn = 0; cn < MAXNOC; cn++)
|
||||
clear_telegram_is_new(cn);
|
||||
|
|
|
@ -309,6 +309,7 @@ start_server(int flags, char *config_file)
|
|||
ef_init();
|
||||
init_files();
|
||||
io_init();
|
||||
init_nreport();
|
||||
|
||||
if (opt_MOB_ACCESS) {
|
||||
/* This fixes up mobility upon restart */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue