Commit graph

4521 commits

Author SHA1 Message Date
fb45b04420 edit: De-duplicate code for commodities on ships and land units
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:55:00 +02:00
cdfdbbe5ce edit: Pass full keys around, not just first characters
To simplify the next commit.

Changes the error message for unknown keys to show the full key.
Shouldn't matter.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:55:00 +02:00
c0f3a1e5e5 edit: Accept interactive empty key argument again
Empty key arguments work fine when passed as command arguments, but
not interactively.  For example, 'edit s 42 R ""' clears the retreat
path, but in an interactive 'edit s 43', 'R ""' sets it to "".

In Empire 1, omitting the argument made it empty.  Empire 2 turned
that into an error without providing an alternative.

Switch to the common command parser, so that quoting works, and "" is
parsed as empty argument.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:54:58 +02:00
33456b3371 edit: Treat blank interactive input like empty input
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:53:56 +02:00
4c1866285b give: Report number given when less than requested amount
Necessary to give the deity a chance to catch unexpected changes,
e.g. a player moving away stuff right before a give command, leaving
fewer items than the deity intends to take.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:52:26 +02:00
9aaf609359 give: Fix integer overflows on silly third arguments
give() silently caps the resulting number of items to 0..ITEM_MAX.

However, its test for "< 0" suffers integer overflow on two's
complement machines (i.e. practically everywhere) when the amount
argument is INT_MIN.  give() proceeds as if the result was in range:
it sets the number of items to (short)(n + INT_MIN), telexes the owner
that INT_MIN items were stolen (obviously bogus), and tells the deity
that there are now n + INT_MIN items in X,Y.

On common machines, (short)(n + INT_MIN) == n, i.e. nothing is given.

On an oddball machine with short as wide as int, the cast to short
does nothing, item_prewrite() oopses, and corrects the number of items
to zero.

In both cases, output and telegram lie.

Likewise, its test for "> ITEM_MAX" suffers integer overflow for
sufficiently big amount arguments.  Again, give() proceeds as if the
result was in range: it sets the number of items to (short)(n + amt),
telexes the owner that -amt items were stolen (obviously bogus), and
tells the deity that there are now close to INT_MIN items in X,Y.

On common machines, (short)(n + amt) = n + INT_MAX - amt - 1,
i.e. some items are stolen.

On an oddball machine with short as wide as int, the cast to short
does nothing, item_prewrite() oopses, and corrects the number of items
to zero.

Again, output and telegram lie.

Aside: setsector can suffer similar overflows, but it reports the
resulting change correctly.  Good enough.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:52:26 +02:00
546e1220e0 edit: Don't permit putting a land unit or plane on two carriers
Only one of struct lndstr members lnd_ship, lnd_land may be
non-negative.  When a deity screws that up, the server oopses.  Be
nice: when setting one, zap the other.

Same for struct plnstr members pln_ship, pln_land.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:52:26 +02:00
2b80ce93da edit: Fix integer argument range checking
Upper bounds corrected:

    cmd  key  struct member   wrong   correct   notes
    -------------------------------------------------
    edit l m  sct_mobil         255       127      1
           t  sct_ptime         255     32767
    edit c b  nat_btu          1024  max_btus
    edit p m  pln_mobil         255       127      1
    edit u F  lnd_harden        255       127	   1

Missing bounds supplied, arguments out of bounds are silently clipped
unless noted otherwise:

    cmd  key     struct member   bounds           notes
    ---------------------------------------------------
    edit c t     nat_tgms        0   USHRT_MAX       2
           m     nat_reserve     0   INT_MAX
           T...  nat_level[]     0   infinity
    edit s a     shp_pstage      0   PLG_EXPOSED     3
           b     shp_ptime       0   32767
           M     shp_mobil    -127   127
           c...  shp_item[]      0   load limit      4
    edit u Y     lnd_land       -1   size of table   5
           M     lnd_mobil    -127   127
           S     lnd_ship       -1   size of table   5
           Z     lnd_retreat     0   100
           c...  lnd_item[]      0   load limit      4
    edit p r     pln_range       0   max range
           s     pln_ship       -1   size of table   5
           y     pln_land       -1   size of table   5

Notes:

1. Values between SCHAR_MAX and 255 were cast to signed char, changing
the sign.

2. The real upper bound is the number of telegrams in the mailbox, but
counting them isn't worth it.

3. This check is particularly important, because values out of bounds
make the server refuse to start without -F, and empdump -x warn
"export has errors, not importable as is".

4. Values outside 0..ITEM_MAX got caught and clipped by
item_prewrite().  This check avoids the oops, and tightens the upper
bound for units.

5. Argument out-of-bounds are rejected.  This check is particularly
important, because unit numbers beyond the size of the table trigger
oopses.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:52:26 +02:00
c0dc4c42b5 edit: Drop pointless doland() variables old, des
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:52:26 +02:00
29c7ae3d80 edit: Suppress "sunk!" after "taken from you by deity"
The fact that the ship wasn't given to anyone is none of the
ex-owner's business.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:52:26 +02:00
381c479ff8 edit: Fix and unify handling of invalid country numbers
Negative numbers and numbers greater or equal than MAXNOC are invalid.
edit handles such arguments inconsistently:

    cmd  key  struct member   arg < 0     arg >= MAXNOC
    ---------------------------------------------------
    edit l o  sct_own         reject      MAXNOC - 1
           O  sct_oldown      reject      MAXNOC - 1
           X  sct_che_target  0           MAXNOC - 1
    edit s O  shp_own         cast        skip
    edit u O  lnd_own         cast        skip
    edit p O  pln_own         cast        skip

Legend:

    0           replace arg by 0
    MAXNOC - 1  replace arg by MAXNOC - 1
    reject      command fails
    cast        replace arg by (natid)arg
                bug: can be >= MAXNOC!
    skip        ignore this key and arg
                bug: telexes the owner he lost the unit, which is a lie

Unify to reject.  Matches setsector.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:52:26 +02:00
aa07f3393a edit: Don't show loyalty, plague stage and time as percentages
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:52:26 +02:00
53d0edc838 edit: Show edited planes and land units just like ships
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:52:26 +02:00
59a15113d3 edit: Show the edited ship even when its owner is invalid
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:52:26 +02:00
44fbf6cd30 prnatid: Recover from getnatp() failure
cname() calls getnatp(), and returns a null pointer when it fails.
Some systems (GNU, Windows) deal gracefully with printing null
strings, others crash.

Because we keep table EF_NATION entirely in memory, getnatp() should
fail only on invalid country number.

Rewrite prnatid() to catch this error and recover.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:52:26 +02:00
61a32b8b69 prnat() prnatid(): New, common country name (#number) formatting
prnat() is more convenient when you already got the struct natstr *.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:52:26 +02:00
383bbff603 edit: Rename some of helpers, and reorder parameters
doland() edits a sector, not a land unit.  That one's called dounit().
Lacks taste.  Call the helper for editing a FOO edit_FOO(), and make
the FOO * the first parameter instead of the last.

Rename the print helpers to print_FOO(), for consistency.  Also frees
up identifier prnat for the next commit.

While there, clean up an unused #define.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:52:26 +02:00
726b9380d1 Replace common pattern by new LIMIT_TO()
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-06 19:52:25 +02:00
edfb80a1f7 empdump: Don't abort() on unresolvable symbols
empdump flags them since commit 2a5d12b (v4.3.28), but still aborts.
Avoid the abort.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-06-01 10:42:39 +02:00
1253cccd76 client: Send login commands without trailing space
Cosmetical improvement; the server is just fine with trailing space.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-05-31 10:52:18 +02:00
1b07fd62c2 cutoff level: Add FIXME comments to narrow coordinate columns
When formatting coordinates for fixed-width output, the width should
be at least four characters.

cutoff was fine until 4.0.2 reduced coordinate width to three to make
space for civilian and military delivery thresholds.

level has always used width three.

Can't fix either without making lines too long or dropping
information, so just document the problem for now.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-05-27 08:09:23 +02:00
3abfde408d mission: Widen coordinate columns to four characters
When formatting coordinates for fixed-width output, the width should
be at least four characters.

Columns x,y and op-sect use three.  Has always been that way.  Widen
them both to four.  This cleans up output for world sizes between 200
and 1998.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-05-27 08:09:13 +02:00
3e7542a9ab sorder: Widen coordinate columns to four characters
When formatting coordinates for fixed-width output, the width should
be at least four characters.

Columns x,y, start and end use three.  Has always been that way,
except for end, which used two until commit e07fb30 (v4.2.13).

Widen them all to four.  This cleans up output for world sizes between
200 and 1998.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-05-27 08:05:38 +02:00
adc66a65a6 land: Separate columns x,y and a in output properly
Coordinates run into army when the y coordinate is wider than three
characters.  Has always been broken.  Insert a separating space.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-05-26 17:14:05 +02:00
48912d3c0b satmap: Separate and align columns in output properly
Land unit coordinates run into efficiency in output of satellite when
the y coordinate is wider than three characters.  Broken in Empire 2.
Restore the separating space.

Both ship and land unit table header aren't aligned with the table
body.  Affects recon and sweep with spy planes, and satellite.  Fix
the header.

Reported-by: William Fittge <ptkei2@gmail.com>
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-05-26 17:14:05 +02:00
51efb954d0 tcp_listen: Plug fd leak on OpenBSD with IPv6
Leaks one file descriptor per configured IPv6 address, which should be
pretty harmless.  Broken in commit da154ff, v4.3.31.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-05-26 17:14:05 +02:00
bb8169ba3a Put URIs and e-mail addresses in <angle brackets>
Also end URIs with '/' where appropriate.

Refrain from touching scripts/ and Stephen Crane's LWP authorship
note.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-05-26 09:48:16 +02:00
50f081176a version: Consistently end sentences with periods
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-05-26 09:48:02 +02:00
6f6bd9fbfe Bump version to 4.3.32
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-05-20 17:41:08 +02:00
809a4e2321 Fix read beyond end of conditional argument on missing operand
nstr_parse_val() interprets argument "" as (empty) identifier, then
returns a pointer right beyond the end of the string.

The argument points into player->argbuf[].  If another argument
follows the conditional, it gets appended to the conditional.  Else,
whatever's left there from previous commands gets appended.  If the
argument is at the very end of player->argbuf[], we parse beyond the
buffer, until we run into a syntax error, or a zero byte.

Since player->argbuf[] is followed by a bunch of pointers, a syntax
error is almost certain.  If we somehow manage to parse all the
pointers and player->lasttime, the runaway parse will end at
player->btused, because that's definitely zero when conditionals get
parsed.
2013-05-12 18:53:29 +02:00
9b0b0dc772 Permit ships that can drop depth charges, but not fire
No such ships exist in the stock game.
2013-05-08 20:43:54 +02:00
92a502df0b Consistently require guns for dropping depth charges
The fire command requires at least one gun for depth charging, but
missions and return fire don't.  Has always been that way, except
between 4.0.6 and commit a3ad623 (v4.3.12), when depth charging worked
exactly like gun fire, and guns were consistently required.

Require guns for all ways to drop depth charges.
2013-05-08 20:37:36 +02:00
b440ee4b84 Cover configure reporting "terminfo: no" in READMEs 2013-05-08 19:19:12 +02:00
afb4761a57 Cast time_t to long for printing with %ld
struct timeval member tv_sec used to be long, but POSIX made it
time_t.
2013-05-08 19:13:38 +02:00
fded50a09c Refresh autoconf macros from autoconf-archive-2013.04.06 2013-05-08 14:35:04 +02:00
81a3e4c4fb Change econfig key rollover_avail_max from 0 to 50
So you don't have to micromanage workers to maximize useful work.

The previous commit made the problem a bit worse.  If you had a few
workers too many before, you perhaps produced an extra unit.  Now, you
get to keep the extra work instead.  Useless, unless it rolls over.
2013-05-08 14:35:04 +02:00
6f7c93cdad Make sector production more predictable
produce() limits production to how many units the workers can produce,
rounding randomly.  It charges work for the units actually produced,
discarding fractions.

If you get lucky with the random rounding, you may get a bit of extra
work done for free.  Else, you get to keep the unused work, and may
even be undercharged a tiny bit of work.  Has always been that way.

The production command assumes the random rounding rounds up if and
only if the probability to do so is at least 50%.  Thus, it's
frequently off by one for sectors producing at their worker limit.

The budget command runs the update code, and is therefore also off by
one, only differently.

Rather annoying for tech and research centers, where a single unit
matters.  A tech center with full civilian population can produce 37.5
units in 60 etus.  Given enough materials, it'll fluctuate between 37
and 38.  Production consistently predicts 38, and budget randomly
predicts either 37 or 38.  Both are off by one half the time.

Fix this as follows: limit production to the amount the workers can
produce (no rounding).  Work becomes a hard limit, not subject to
random fluctuations.  Randomly round the work charged for actual
production.  On average, this charges exactly the work that's used.

More importantly, production and budget now predict how much gets
produced more accurately.  They're still not exact, as the amount of
work available for production remains slightly random.

This also "fixes" the smoke test on a i686 Debian 6 box for me.  The
root problem is that floating-point subexpressions may either be
computed in double precision or extended precision.  Different
machines (or different compilers, or even different compiler flags)
may use different precision, and get different results.

Example: producing 108 units at one work per unit, sector p.e. 0.4
needs to charge 108 / 0.4 work.  Computed in double precision, this
gets rounded to 270.0, then truncated to 270.  In 80 bit extended
precision, it gets rounded to 269.999999999, then truncated to 269.

With random rounding instead of truncation, the probability for a
different result is vanishingly small.  However, this commit
introduces truncation in another place.  It just happens not to mess
up the smoke test there.  I doubt this is the last time this kind of
problem upsets the smoke test.
2013-05-08 14:23:50 +02:00
739852dd3f Rearrange produce() and prod() a bit to make them more similar 2013-05-08 06:57:58 +02:00
ba2600e7db Factor prod_resource_limit() out of produce() and prod() 2013-05-08 06:57:58 +02:00
ec60098c36 Avoid double rounding materials when limiting products made
We can make actual = roundavg(material_consume * prodeff) products.

When we reduce actual, we have to reduce material_consume, too.  Code
does that like this:

    material_consume = roundavg(actual' * material_consume / actual)

Double rounding.  Do this instead:

    material_consume = roundavg(actual' / prodeff)
2013-05-08 06:57:58 +02:00
87b29f784d Use ITEM_MAX instead of 9999 as production material limit
No functional change, as ITEM_MAX is 9999, just cleaner.
2013-05-08 06:57:58 +02:00
f0927e7f64 prod() duplicates materials_cost(), clean up
Rename materials_cost() to prod_materials_cost(), give external
linkage, use it in prod().
2013-05-08 06:57:58 +02:00
ac60160355 Clean up redundant code in prod() 2013-05-08 06:57:58 +02:00
4884eddb51 Fix xdump nat column ip for connections from "long" IPv6 addresses
Broken in commit 3a7d7fa, which enlarged struct natstr member
nat_hostaddr[] from 32 to 46 characters, but neglected to update the
ca_len in nat_ca[].  Consequently, the address is truncated in xdump.
Can also break country * ?ip=... and such, but that's exotic.
2013-05-08 06:57:58 +02:00
c016c5fe76 Fix five year old show stopper bugs on big endian hosts
emp_server and empdump refuse to start on most big endian hosts,
because ef_verify_config() chokes on mdchr_ca[]:

Config meta uid 0 field type: value 0 is not in symbol table meta-type
Config meta uid 1 field type: value 0 is not in symbol table meta-type
Config meta uid 2 field type: value 0 is not in symbol table meta-type
Config meta uid 3 field type: value 0 is not in symbol table meta-type
Config meta uid 4 field type: value 0 is not in symbol table meta-type

Broken in commit 06a0036 (v4.3.12), which changed struct castr member
ca_type from packed_nsc_type (typedef'ed to char) to enum nsc_type,
but neglected to update the ca_type in mdchr_ca[].

On little endian hosts, the selector reads the least significant byte,
with sign extension.  Happens to work, because the type values are all
sufficiently small integers.

On big endian hosts, the selector reads the most signiciant byte.
which is always zero (NSC_NOTYPE).  Makes ef_verify_config() fail.

Except when sizeof(enum nsc_notype) == 1.  Then selector type works
fine, and ef_verify_config() succeeds, but we run into the next
problem: the same commit also changed member ca_flags from nsc_flags
(typedef'ed to unsigned char) to int without updating the ca_type in
mdchr_ca[].  This breaks "only" xdump meta column flags.

v4.3.12 was released in April 2008.  Either nobody has tried to run a
game on a big endian host since, or all who did gave up quietly,
without reporting the problem.

We clearly need to test on a wider range of machines.
2013-05-08 06:57:58 +02:00
347d3f3510 Fix xdump trade column type on big endian hosts
Broken in commit 14ea670 (v4.3.8), which changed struct trdstr member
trd_type from char to short, but neglected to update the ca_type in
trade_ca[].

On little endian hosts, the selector reads the least significant byte,
with sign extension.  Happens to work, because the type values are all
sufficiently small integers.

On big endian hosts, the selector reads the most signiciant byte,
which is always zero (EF_SECTOR).  Messes up xdump trade badly.
2013-05-08 06:57:58 +02:00
c64c756eef Fix xdump lost column type on big endian hosts
Broken in commit 09248d0 (v4.3.8), which changed struct loststr member
lost_type from char to short, but neglected to update the ca_type in
lost_ca[].

On little endian hosts, the selector reads the least significant byte,
with sign extension.  Happens to work, because the type values are all
sufficiently small integers.

On big endian hosts, the selector reads the most signiciant byte,
which is always zero (EF_SECTOR).  Messes up xdump lost badly.  Also
breaks lost * ?type=..., but that's exotic.
2013-05-08 06:57:58 +02:00
e8742793e6 Drop trailing space in output of financial 2013-05-08 06:57:57 +02:00
14b31911dc Clean up some trailing whitespace 2013-05-08 06:57:57 +02:00
37990f98b2 Include <process.h> in w32/unistd.h for getpid()
getpid() is used since commit 773019e.
2013-05-08 06:57:56 +02:00