int do_look(int type) { int i; struct nstr_item ni; union empobj_storage unit; struct sctstr sect; int x, y; unsigned char *bitmap; int changed = 0; if (CANT_HAPPEN(type != EF_LAND && type != EF_SHIP)) type = EF_SHIP; if (!snxtitem(&ni, type, player->argp[1], NULL)) return RET_SYN; bitmap = calloc((WORLD_SZ() + 7) / 8, 1); if (!bitmap) { logerror("malloc failed in do_look\n"); pr("Memory error. Tell the deity.\n"); return RET_FAIL; } while (nxtitem(&ni, &unit)) { if (!player->owner) continue; if (type == EF_LAND) { if (unit.land.lnd_ship >= 0) continue; if (unit.land.lnd_land >= 0) continue; /* Spies don't need military to do a "llook". Other units do */ if ((unit.land.lnd_item[I_MILIT] <= 0) && !(lchr[(int)unit.land.lnd_type].l_flags & L_SPY)) continue; look_land(&unit.land); } else look_ship(&unit.ship); for (i = 0; i <= 6; i++) { x = diroff[i][0] + unit.gen.x; y = diroff[i][1] + unit.gen.y; if (emp_getbit(x, y, bitmap)) continue; emp_setbit(x, y, bitmap); getsect(x, y, §); if (sect.sct_type == SCT_WATER) continue; look_at_sect(§, 10); changed += map_set(player->cnum, x, y, dchr[sect.sct_type].d_mnem, 0); if (opt_HIDDEN) { setcont(player->cnum, sect.sct_own, FOUND_LOOK); } } } if (changed) writemap(player->cnum); free(bitmap); return RET_OK; }
void finish_sects(int etu) { static double *import_cost; struct sctstr *sp; int n; struct rusage rus1, rus2; if (import_cost == NULL) { logerror("First update since reboot, allocating buffer\n"); import_cost = malloc(WORLD_SZ() * sizeof(*import_cost)); if (import_cost == NULL) { logerror("malloc failed in finish_sects.\n"); return; } } logerror("delivering...\n"); /* Do deliveries */ for (n = 0; NULL != (sp = getsectid(n)); n++) { if (!sp->sct_own || sp->sct_type == SCT_SANCT) continue; if (nat_budget[sp->sct_own].money < 0) continue; dodeliver(sp); } logerror("done delivering\n"); logerror("assembling paths...\n"); getrusage(RUSAGE_SELF, &rus1); assemble_dist_paths(import_cost); getrusage(RUSAGE_SELF, &rus2); logerror("done assembling paths %g user %g system", rus2.ru_utime.tv_sec + rus2.ru_utime.tv_usec / 1e6 - (rus1.ru_utime.tv_sec + rus1.ru_utime.tv_usec / 1e6), rus2.ru_stime.tv_sec + rus2.ru_stime.tv_usec / 1e6 - (rus1.ru_stime.tv_sec + rus1.ru_stime.tv_usec / 1e6)); logerror("exporting..."); for (n = 0; NULL != (sp = getsectid(n)); n++) { if (!sp->sct_own || sp->sct_type == SCT_SANCT) continue; if (nat_budget[sp->sct_own].money < 0) continue; dodistribute(sp, EXPORT, import_cost[n]); } logerror("done exporting\n"); logerror("importing..."); for (n = 0; NULL != (sp = getsectid(n)); n++) { sp->sct_off = 0; if (!sp->sct_own || sp->sct_type == SCT_SANCT) continue; if (nat_budget[sp->sct_own].money < 0) continue; dodistribute(sp, IMPORT, import_cost[n]); } logerror("done importing\n"); }
static void assemble_dist_paths(double *import_cost) { struct sctstr *sp; struct sctstr *dist; int n; static int *job; int uid, i; coord dx = 1, dy = 0; /* invalid */ if (!job) job = malloc(WORLD_SZ() * sizeof(*job)); n = 0; for (uid = 0; NULL != (sp = getsectid(uid)); uid++) { import_cost[uid] = -1; if (sp->sct_dist_x == sp->sct_x && sp->sct_dist_y == sp->sct_y) continue; job[n++] = uid; } #ifdef PATH_FIND_STATS printf("dist path reuse %zu bytes, %d/%d used\n", WORLD_SZ() * sizeof(*job), n, WORLD_SZ()); #endif qsort(job, n, sizeof(*job), distcmp); for (i = 0; i < n; i++) { uid = job[i]; sp = getsectid(uid); dist = getsectp(sp->sct_dist_x, sp->sct_dist_y); if (CANT_HAPPEN(!dist)) continue; if (sp->sct_own != dist->sct_own) continue; if (sp->sct_dist_x != dx || sp->sct_dist_y != dy) { dx = sp->sct_dist_x; dy = sp->sct_dist_y; path_find_from(dx, dy, dist->sct_own, MOB_MOVE); } import_cost[uid] = path_find_to(sp->sct_x, sp->sct_y); } path_find_print_stats(); }
/* * Return a new bp map. * Caller should pass it to free() when done with it. */ struct bp * bp_alloc(void) { return calloc(WORLD_SZ(), sizeof(struct bp)); }
/*ARGSUSED*/ void player_accept(void *unused) { static int conn_cnt; struct sockaddr *sap; struct player *np; socklen_t len; const char *p; int ns; int set = 1; int stacksize; char buf[128]; #ifdef RESOLVE_IPADDRESS struct hostent *hostp; #endif /* auto sockaddr_storage would be simpler, but less portable */ sap = malloc(player_addrlen); len = player_addrlen; if (getsockname(player_socket, sap, &len)) { logerror("getsockname() failed: %s", strerror(errno)); p = NULL; } else { p = sockaddr_ntop(sap, buf, sizeof(buf)); CANT_HAPPEN(!p); } logerror("Listening on %s", p ? buf : "unknown address"); while (1) { empth_select(player_socket, EMPTH_FD_READ, NULL); len = player_addrlen; ns = accept(player_socket, sap, &len); /* FIXME accept() can block on some systems (RST after select() reports ready) */ if (ns < 0) { logerror("new socket accept"); continue; } (void)setsockopt(ns, SOL_SOCKET, SO_KEEPALIVE, &set, sizeof(set)); np = player_new(ns); if (!np) { logerror("can't create player for fd %d", ns); close(ns); continue; } if (!sockaddr_ntop(sap, np->hostaddr, sizeof(np->hostaddr))) { CANT_REACH(); player_delete(np); continue; } logerror("Connect from %s", np->hostaddr); #ifdef RESOLVE_IPADDRESS hostp = gethostbyaddr(inaddr, player_addrlen, sap->sa_family); if (NULL != hostp) strcpy(np->hostname, hostp->h_name); #endif /* RESOLVE_IPADDRESS */ /* FIXME ancient black magic; figure out true stack need */ stacksize = 100000 /* budget */ + MAX(WORLD_SZ() * sizeof(int) * 7, /* power */ MAXNOC * sizeof(struct powstr)); sprintf(buf, "Conn%d", conn_cnt++); empth_create(player_login, stacksize, 0, buf, np); } }