Commit graph

4049 commits

Author SHA1 Message Date
5d7f011900 Use int instead of long to count people
Code dealing with counting people mixes int and long pretty
haphazardly.  Harmless, because practical populations fit into int
easily on any machine capable of running the server.  Clean up anyway.
2013-05-08 06:57:54 +02:00
948757cb0c Use int instead of signed char for pln_flags
Just for consistency with other flags members.  Rearrange struct
plnstr to avoid holes.
2013-05-08 06:57:54 +02:00
e51b3fb842 Use int instead of long for flags
As long as symbol_by_value(), show_capab() and togg() support only
int, flags need to fit into int.

Not a problem in practice, because no machine capable of running
Empire has int narrower than 32 bits, and 32 bits suffice.

Some flags members are long instead of int: struct lchrstr member
l_flags, struct natstr member nat_flags, struct mchrstr member m_flags
are long.  Waste of space on machines with long wider than int.
Change them to int.

Rearrange struct lchrstr and struct natstr to avoid holes.
2013-05-08 06:57:51 +02:00
77f8846273 Abridge a few overly verbose declarations 2013-05-08 06:55:21 +02:00
199ea0cb39 Clean up redundant forward declarations 2013-05-08 06:55:21 +02:00
bc14b41c65 Fix crash on edit s, p, u key 'U' with negative argument
ef_ensure_space() oopses on negative ID, but succeeds anyway.  edit()
proceeds to ef_write(), which neglects to check for negative ID.
Since the ID isn't in the cache, it then passes a NULL old element to
callback prewrite(), which crashes.

Fix ef_ensure_space() to fail on negative ID.  Commit 5173f8cd
(v4.3.0) made it oops, but neglected to make it fail.

Fix ef_write() to oops and fail on negative ID.

ef_write() still passes NULL old element to prewrite() when the ID
isn't in the cache.  Doesn't actually happen, because we use
prewrite() callbacks only with fully cached tables.  Fragile.  Make
ef_open() fail when that assumption is violated.
2013-05-08 06:55:21 +02:00
9da83c54c0 Unify owner of units built by deities in foreign sectors
Newly built ships and land units are given to the player, planes and
nukes to the sector owner.  Matters only for deities, because only
deities can build in foreign sectors.  Stupid all the same.

This has always been inconsistent.  Empire 1 gave ships and nukes to
the player, and planes to the sector owner.  Chainsaw 3 added land
units, and gave them to the player.  Empire 2 changed build to give
nukes to the sector owner.

Building doesn't work when the unit built is given to POGO, because
giving a unit to POGO destroys it.  When build gives to the sector
owner, deities can't build in unowned sectors.  When build gives to
the player, POGO can't build at all.  That's more limiting, so change
build to always give to the sector owner.
2013-05-08 06:55:21 +02:00
ba67bd1f9e Use unsigned instead of unsigned long for fairland's random seed
seed_prng() wants unsigned.  Server uses unsigned already.
2013-05-08 06:55:21 +02:00
1bbbd5e27f Remove a blank line before "fairland rips open"
One blank line before and after now, looks better.
2013-05-08 06:55:21 +02:00
4dcfa968ce Don't reprint "fairland rips open" and PRNG seed on each retry 2013-05-08 06:55:21 +02:00
9102ecce54 Fix PRNG seeding to resist guessing
We seed it with value of time().  It's the traditional way, but it
provides only a few bits of effective entropy when an attacker has a
rough idea when the program started.

Instead, seed with a kernel random number.  If we can't get one, fall
back to a hash of gettimeofday() and getpid().  This should happen
only on old systems or Windows.  Far worse than a kernel random
number, but far better than using time().

Note that fairland used to seed with time() + getpid() until commit
331aac2a (v4.2.20) dropped the getpid(), claiming it didn't improve
the randomness.  Perhaps it didn't under Windows then, but it
certainly did elsewhere, so it was a regression.
2013-05-08 06:55:21 +02:00
39c26f4238 Switch PRNG from BSD random() to Mersenne Twister
random() may yield different pseudo-random number sequences for the
same seed on another system.  For instance, at least some versions of
MinGW provide a random() in -liberty that differs from traditional BSD
(see commit c8231b12).  Rather inconvenient for regression testing.

MT19937 Mersenne Twister is a proven, high-quality PRNG.  Actual code
is reference code provided by the inventors[*].  Quick tests show
performance comparable to random().

Like random(), MT is not cryptographically secure: observing enough of
its output permits guessing its state, and thus its future output.  I
don't think players can do that.

Drop the copy of BSD random() we added for Windows.

Like the previous commit, this changes the server's die rolls, and
makes fairland create a different random map for the same seed.  Update
expected smoke test results accordingly.

[*] mt19937ar.sep.tgz downloaded from
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
2013-05-08 06:55:21 +02:00
b5d8806eb1 Fix tiny error in distribution of die rolls
"random() % n" is sound only when n is a power of two.  The error is
hardly relevant in Empire, because random() yields 31 bits, and our n
are always much smaller than 2^31.  Fix it anyway.

Use smallest the 2^m >= n instead of n, and discard numbers exceeding
n.

Bonus: faster for me even in the worst case n = 2^m+1.

Like the recent change to damage(), this changes some of the server's
die rolls, only this time the effect is pretty pervasive.  Worse,
fairland now creates a completely different random map for the same
seed.  Update expected smoke test results accordingly.
2013-05-08 06:55:20 +02:00
54ddcd0f5a New pct_chance(), for clarity, and symmetry with chance() 2013-05-08 06:55:20 +02:00
1cf6b5e6bb Make move_ground() use roundavg()
No functional change.
2013-05-08 06:55:20 +02:00
c53158eee0 Make damage() use roundavg()
Turns damage() into a one-liner.

damage() now uses random() % 32768 in chance() instead of random() %
100 inline, therefore can round differently for the same pseudo-random
number.  Update expected smoke test results accordingly.

Aside: "random() % n" distributes evenly only when n is a power of
two.  100 isn't.  However, because random() yields at least 31 bits,
and 100 is so much smaller than 2^31, the error is vanishingly small.
2013-05-08 06:55:20 +02:00
c3be487479 Replace "roll0(N) + M" by "roll(N) + M-1" 2013-05-08 06:55:20 +02:00
fce1393017 Fairland's rnd() wrapper is trivial now, drop it 2013-05-08 06:55:20 +02:00
866859e912 Encapsulate direct use of random(), srandom() in chance.c
Wrap roll0() around random(), and seed_prng() around srandom().  In
preparation of replacing the PRNG.
2013-05-08 06:55:20 +02:00
8eb78a5a80 Move declarations for chance.c to new chance.h 2013-05-08 06:55:20 +02:00
3c470925b6 Fix prod_eff() function comment
It returns product's level p.e. time sector type p.e, not just the
level p.e.  See "info Products".
2013-05-08 06:55:20 +02:00
5507ff3116 Clean up land unit retreat chance and fix its documentation
Change chance in percent lnd_retreat - lnd_effic - 1 to lnd_retreat -
lnd_effic.  It's been that way since Empire 2, but I can't bring
myself to document the silly -1.

"info morale" wasn't updated when the retreat chance was changed in
Empire 2.  Fix that.
2013-05-08 06:55:19 +02:00
f18c46824d Clean up and document nuclear damage's chance to destroy nuke
Change chance in percent from damage-1 to damage.  It's always been
damage-1, but I can't bring myself to document the silly -1.
2013-05-08 06:55:19 +02:00
b288f62538 Clean up launch_sat() random direction pick
Use DIR_FIRST rather than literal 1.
2013-05-08 06:55:19 +02:00
780ca1ae62 Enlarge news cache from 5 to 8 entries per country 2013-05-08 06:55:19 +02:00
5738e399c4 Make news item merging deterministic and safe for year 2038
News reporting merges news items into recent items with same contents.
For that purpuse, we keep a small cache of recent items.  When a new
item can't be merged into an item in the cache, the oldest item gets
evicted to make space for the new one.

ncache() evicts the first item with the smallest timestamp (struct
nwsstr member nws_when).  Timestamps are in seconds, therefore clashes
are common, and eviction depends on exact timing.  Such indeterminism
can make the smoke test fail.

Moreover, ncache() assumes timestamps cannot exceed 0x7fffffff.  If
they do, it always evicts the slot 0.  They will in 2038.

Fix by evicting round robin.  This always evicts the oldest item.
2013-05-08 06:55:19 +02:00
49b2b13a90 New make target check
Just a smoke test so far, extracted from src/scripts/nightly/.  This
makes the existing smoke test more easily accessible.  Noteworthy
differences:

* Instead of patching the code to make output more stable, postprocess
  the output to normalize it.

* Compare actual results to expected results instead of the previous
  test run's results.

* Much faster.  The old test harness used sleep liberally to "ensure"
  things always happen in the same order.

Known shortcomings:

* The smoke test hangs when the server fails to complete startup, or
  fails to terminate.

* Normalization of xdump hardcodes columns instead of getting them
  from xdump meta.

* Normalization of time values in xdump is an ugly hack.

* xdump meta column type isn't normalized.  Actual values can vary
  between systems, because the width of enumeration types is
  implementation-defined.  The smoke test works only when they're
  represented as int, which is the case on common systems.

* Currently expected to work only with thread package LWP and a
  random() that behaves exactly like the one on my development system,
  because:

  - Thread scheduling is reliably deterministic only with LWP

  - The PRN sequence produced by random() isn't portable

  - Shell builtin kill appears not to do the job in MinGW

  - The Windows server tries to run as service when -d isn't
    specified

Further work is needed to address these shortcomings.

Getting C programs behave exactly the same on all systems is hard.
We'll likely run into system-dependent differences that upset the
smoke test.  Floating-point computation seems particularly vulnerable.

Instead of updating src/scripts/nightly/ to use "make check", retire
it.  It hasn't been used in quite a while.  Investing more into our
homegrown auto-builder doesn't make sense, as canned auto-builders
such as Travis CI and Jenkins are readily available.

The shell scripts src/scripts/nightly/tests/?? become Empire batch
files tests/smoke/.  The shell scripts are actually shell boilerplate
around Empire batch files.  To make sure git recognizes the move, this
commit moves them unchanged.  tests/smoke-test strips the boilerplate
before it feeds the batch files to the client.  The next commit will
get rid fo that.
2013-05-08 06:55:11 +02:00
2fefdaed15 Don't put file descriptor values in thread names
The names are logged.  Loging file descriptor values gets in the way
of regression testing, such as the smoke test that'll be committed
shortly.
2013-01-12 17:57:42 +01:00
d794738fd8 Don't log threads initialization 2013-01-12 17:57:42 +01:00
d068259487 Simplify lnd_take_casualty()'s land unit retreat code
Bonus: avoids "may be used uninitialized" compiler warnings (the code
was safe despite the warning).
2013-01-12 17:56:39 +01:00
75619c3732 Simplify head_meanwhile()
No functional change.
2013-01-12 17:56:39 +01:00
bcff368909 Take ship cost into account when picking missile interdiction target
Due to a typo, shp_missile_interdiction() picks the admissible target
with highest efficiency instead of the one with highest efficiency *
build cost.

Broken in commit cd8d7423, v4.3.8.
2013-01-12 17:56:39 +01:00
bfea79a72d Really fix setsector and setres not to wipe out concurrent updates
setsector() and setres() continue after check_sect_ok() fails.
Clobbers the updates that made check_sect_ok() fail, triggering a
seqno mismatch oops.

Commit 04a332a8 (v4.3.27) claimed to fix this, but actually only
suppressed the generation oops.
2013-01-12 17:56:34 +01:00
c4c4413ea5 Really fix give not to wipe out concurrent updates
give() continues after check_sect_ok() fails.  Clobbers the updates
that made check_sect_ok() fail, triggering a seqno mismatch oops.

Commit b58c37e2 (v4.3.27) claimed to fix this, but actually only
suppressed the generation oops.
2013-01-12 17:56:26 +01:00
efa4ecdc4d Drop resnoise()'s second parameter
All callers pass the same argument.
2013-01-12 17:56:26 +01:00
eb4adc93ff Fix setsector not to disclose number of landmines to occupier
When the deity sets the number of mines with setsector, the sector
owner (if any) is told the resulting number of mines.  Even for
occupied sectors, where mines belong to the old owner, and thus
shouldn't be disclosed.  Oops.

Fix setsector not to tell the sector owner anything then.
2013-01-12 17:56:26 +01:00
6fbc291272 anti, give, grind take <SECTS> argument, fix their documentation 2013-01-12 17:56:26 +01:00
f2e5e467c0 Make capital fail more nicely when sector is unsuitable
The command fails without an explanation then.  Change it to print
something like "X,Y is not a capital or mountain owned by you."
2013-01-12 17:56:26 +01:00
3783652d7a Change capital to take a single sector as argument
Capital takes a <SECTS> argument, and picks the first suitable sector
it finds there.  It fails if none can be found, or if the first one
found already is the capital (even when more suitable sectors follow).
Has always worked that way, but never documented.

I don't think the search feature is really useful, and documenting it
isn't worth my while.  Change the command to take a <SECT> argument
instead, as documented.
2013-01-12 17:51:22 +01:00
df4925d696 Update copyright notice 2013-01-12 17:45:01 +01:00
c300dc7055 Change GODNEWS reports not to affect headlines and relations
Option GODNEWS controls news reports give's N_GIFT, N_TAKE, and edit's
and setsector's N_AIDS, N_HURTS.

They affect news headlines because of their non-zero r_good_will.
N_TAKE and N_HURTS can downgrade relations because of their negative
r_good_will.  All tolerable, except N_TAKE has actor and victim
reverted: the deity running the give command is the victim, and the
sector owner is the actor.  Because of that, give with a negative
amount downgrades the deity's relations towards the sector owner.
Inappropriate.

Has always been that way.  Chainsaw disabled these news at
compile-time; to enable you had to define GODNEWS (not documented
anywhere).  Empire 4.2.0 made GODNEWS a proper option, enabled by
default.

Fix by setting their r_good_will to zero.
2012-08-12 09:36:07 +02:00
0f1e14f0f3 Fix flying commands for destination equal to assembly point
bomb, drop, fly, paradrop, recon and sweep fail when given a
destination sector equal to the assembly point.  Broken in commit
404a76f7, v4.3.27.  Reported by Tom Johnson.

Before that commit, getpath() returned NULL on error, "" when input is
an empty path, "h" when it's coordinates of the assembly point, and a
non-empty path otherwise.

The commit accidentally changed it to return "" instead of "h".

Instead of changing it back, make it return NULL when input is an
empty path, and change bomb() & friends to accept empty flight paths.

This also affects sail: it now fails when you give it an empty path,
just like bomb & friends.  Path "h" still works.
2012-08-12 09:34:49 +02:00
efc3a8e6e2 Open journal before daemonizing, so we can fail in foreground
Just like we open server.log.  Also permits calling journal_prng()
right where we seed the PRNG.
2012-08-05 09:26:08 +02:00
fc64b4fa83 Permit empth_self() before empth_init()
Next commit wants this.
2012-08-05 09:24:57 +02:00
30dbd609bc Forbid selling conquered populace
Only relevant when the deity allows selling civilians by customizing
table item, which is probably a bad idea.
2012-07-13 20:15:34 +02:00
324109ae45 Forbid selling units with unsalable cargo, permit selling military
Deities can customize which commodities can be sold in table item.
Default is to allow anything but civilians and military.  However,
this applies only to the commodity market, not to the unit market:
cargo of ships and land units is not restricted.

Make the two markets consistent: permit selling military by default,
forbid selling units carrying unsalable commodities.  This outlaws
selling units carrying civilians by default.
2012-07-13 20:15:34 +02:00
6c086a8110 Drop trade_desc()'s first argument 2012-07-13 20:15:34 +02:00
4f3d6792e3 Drop unclean assignments in trade_desc()
Assigning to tp->trd_owner is unclean.  Can be dropped safely, because
it has no effect: prior check_trade() drops all trades where the
assignment would change anything.
2012-07-13 20:15:34 +02:00
d9cafc156c Clean up use of union empobj_storage * as parameter type
Use it only for functions that assign objects through a pointer
parameter.  Anything else can and should use struct empobj *.
2012-07-13 20:15:33 +02:00
f75544ee70 Replace trade_check_item_ok() by check_obj_ok()
Relaxes the sanity check of the argument's ef_type.  Could be avoided,
but not worth the bother.
2012-07-13 20:15:33 +02:00