Commit graph

4199 commits

Author SHA1 Message Date
7aa71376a0 Clean up info sect on highlighting
Don't say selected sectors "show up in reverse video", that depends on
the client.  Just say "will be highlighted", like we do for the other
commands that highlight, e.g. info survey.
2012-02-21 18:12:23 +01:00
c72e2cbf25 read can print telegram without header after deletion prompt
rea() loops if more telegrams arrive while we wait for the player to
confirm deletion.  If the first new one is a continuation of the last
old one, its header is suppressed.  Don't do that.

Broken in commit 17223e8f, v4.3.29.
2012-02-21 18:12:12 +01:00
330f8ca567 Fix 'm' in path argument of explore, move, transport
Two related bugs:

* It moans about deprecated argument syntax ('m' without a space
  before its argument) even when there's no argument.

* It uses the third instead of second argument for map flags (second
  argument is ignored): "m# s" doesn't show ships, and "m# s p" shows
  planes instead of ships.

Broken in commit 28d48474, v4.3.27.
2012-02-21 18:11:23 +01:00
9f3e9f833a Clarify buytax econfig doc string
Reported by Scott C. Zielinski.
2012-02-21 18:11:23 +01:00
c0d4ba57d6 Polish the bulletin the seller gets after a unit sale 2012-02-21 18:11:23 +01:00
87c3a853fd Make market command unavailable to visitors, and set C_MOD flag
The market command executes all trades that have become ready, by
calling check_market() and check_trade().  This modifies game state,
but market lacks C_MOD.  That's wrong.  But can it do harm?

Turns out yes.  check_trade() looks safe, but check_market() telexes
seller and buyer while holding a copy of the commodity struct.  If
this telexes the player who sent the market command, and he has
NF_INFORM on, the telegram notification may yield the processor.  It
then writes back its copy, triggering a generation oops.  Any updates
made by other threads meanwhile are wiped out, triggering a seqno
mismatch oops.

This can cause commodity trades to be executed multiple times,
multiplying the sold commodities.  Abuse seems tricky, but possible:
conspiring trade partners trade commodities back and forth to multiply
them.  One of them needs to get the output backlog just right to make
the telegram notification yield, and the timing right so that the
MarketUpdate thread or another player's buy, market, reset, sell, set
or trade command runs check_market() before his thread resumes.

Closely related bug: visitors can trigger execution of trades by means
of command market.  That's clearly inappropriate.

Broken in Empire 3.  Reported by Scott C. Zielinski.
2012-02-21 18:11:13 +01:00
78dc17c02c Clarify what happens when the player aborts commands 2012-02-21 18:11:13 +01:00
b4f076fc36 Fix market not to expropriate sellers of units
When a ship, plane, land unit or nuke is sold, the seller is replaced
by POGO: POGO gets the money, the telegrams and makes the news.
Likewise when a sale fails because the buyer can't pay.

Broken in commit 94a3108b, v4.3.17.  Reported by Scott C. Zielinski.
2012-02-21 18:11:13 +01:00
904822e344 Fix server shutdown to let player output drain properly
Commit 1e1dfc86 (v4.3.23) attempted to do this, but it's flawed.

Server shutdown makes the player command loops terminate.  Each player
thread then flushes buffered output and closes the server's end of the
connection.  The client eventually gets EOF, and closes its end of the
connection.  All is well.

However, if the client sends more input after the server closed its
end of the connection, but before it completed receiving server
output, it gets ECONNRESET, and the remaining output is lost.

Instead of closing the server's end of the connection, we need to shut
down its transmission direction, then wait for the client to close its
end, by receiving client input until EOF.  Do that in io_close().

The output flushing in player_login() is now superfluous.  Remove it.

Make shutdwn() wait for the io_close() to complete instead of output
queues to drain.  Without that, we could still close the server's end
of the connection prematurely, through program termination.  Change
player_delete() to keep the player in Players until after io_close()
completes, so that shutdwn() can detect completion.
2012-02-21 18:11:13 +01:00
8549efbc19 Clean up how quit and server shutdown trigger connection close
Simply set the player connection's EOF indicator.  Cleaner than
setting player->state to PS_SHUTDOWN from random places.

Move the assignment of PS_PLAYING from player_main() to its caller
play_cmd(), so that player->state is exclusively controlled in
login.c.
2012-02-21 18:11:13 +01:00
0a7306a5ac Fix login command quit to really quit
quit_cmd() calls io_shutdown() to make player_login()'s next command
read detect EOF.  io_shutdown() drains the input queue and shuts down
the socket with shutdown().  player_login()'s next io_gets() fails all
right, but then io_input() *can* read more from the socket on my Linux
box, at least when I send plenty of input fast.  Thus, we ignore
whatever input after quit was already queued, then resume reading
commands, not necessarily at the beginning of a line.

Fix by setting the EOF indicator instead.
2012-02-21 18:11:13 +01:00
ca7578f1b8 Fix idle timeout during execute
Timeout during execute gets handled just like an EOF cookie: end the
batch file, resume reading normal commands.  That's wrong, we need to
close the connection.

A real EOF is recorded in the player's connection's EOF indicator.
Let's use that for all "connection needs to be closed" conditions, so
they all work the same.  Create io_set_eof() to provide access.

Make recvclient() set the player connection's EOF indicator on
timeout.  This makes the timeout "stick".  Record receipt of an EOF
cookie in new struct player member got_ctld.  Also abort the command,
as before.  This leaves further interpretation of the EOF cookie to
the command loops.

Make player_main() set the player connection's EOF indicator on
got_ctld.  Player connection gets closed on on EOF cookie, as before.

Change execute() to break the batch command loop when got_ctld is set,
then reset it.  Ends the batch file on EOF cookie, as before.

Change status() back to checking EOF and error indicators (partial
revert of commit 9c5854c8, v4.3.16), and drop struct player member
eof.
2012-02-21 18:10:52 +01:00
d78d9cac1d Make execute yield the processor after every command
A player sending execute script contents quickly could theoretically
get an unfair share of the server.  Missed in commit db6fd8da
(v4.2.22), which made only the normal command loop yield.
2012-02-20 07:44:21 +01:00
5585dda091 Simplify recvclient() to return -1 for all failures
Callers don't care.  Also fix some comments.
2012-02-20 07:44:21 +01:00
16879f3db2 Don't lose output when client shuts down input transmission
player_login() skips sending C_EXIT and flushing server output when
io_eof() is true.  That's the case after a read from the socket
returned zero, which means the client has shut down transmission on
his socket, or closed it.  If it's the former, then dropping output
like that is bad.  Our client never does that, but others might.

Condition was introduced in Empire 2, don't know why.
2012-02-20 07:44:21 +01:00
bdc1c40f0a Show treasury status on EOF, quit, shutdown
status() informs the player of non-trivial command costs and earnings,
and when he goes broke or becomes solvent.  However, this is skipped
when the command gets aborted by the player signalling EOF, or by
server shutdown, and after a quit command.

Fix by moving the check for EOF or shutdown down to the may_play_now()
check.

This looks a bit like it would also fix charging of play time.  But
that's not broken, because player_main() charges, too.
2012-02-20 07:43:23 +01:00
8342618450 Fix client's command abort at beginning of first input line
Commit 3cceb59b (v4.3.26) fixed the client to abort commands reliably
on ^C, even when it arrives at the beginning of an input line.  Except
it didn't work at the beginning of the first input line, because
input_eol was initialized to zero.

Easily fixed, but "end of line" isn't quite right there.  Revert sense
and rename to partial_line_sent.
2012-02-20 07:34:35 +01:00
a89af8c64d Simplify journal_entry_pr(), rename to journal_entry_write()
journal_entry_pr(S, N) writes up to N characters from zero-terminated
string S.  journal_input() passes -1 for N to write all characters.
Unclean.  SIZE_MAX would do, but it's C99, and MSC doesn't provide it.

Simplify journal_entry_pr() to write exactly N characters.  This makes
it more similar to write() than to pr(), therefore rename.
2012-02-20 07:34:34 +01:00
f7533451d0 Put home page URL into configure --help 2012-02-20 07:34:34 +01:00
39c4e957a4 Bump version to 4.3.30 2012-02-20 07:34:32 +01:00
1c24a812e8 Final change log polish for 4.3.29 2012-01-20 20:21:51 +01:00
46d36f1975 Update change log for 4.3.29 2012-01-15 19:47:04 +01:00
90a263d5ef drop and fly from carrier can fail to load last civ or mil
pln_equip() refuses to abandon its base sector.  Unfortunately, it
checks even when flying off carriers, and refuses to load the last
civilian or military depending on what happens to be in uninitialized
variable sect.

Broken in commit 91139692, v4.3.0.
2011-12-29 11:47:07 +01:00
213501cabb Clean up journal_open() to open the journal write-only
We don't actually need update mode.
2011-12-29 11:47:07 +01:00
421907fcb8 Clean up read to open telegram file read-only
Update mode hasn't been necessary since 4.0.11 dropped use of
ftruncate().
2011-12-29 11:47:07 +01:00
cda63a40d8 Check for mailbox creation failure
Deity command add logs the failure, utility program files reports it
and exits unsuccessfully.  Before, this failure was silently ignored.
2011-12-29 11:47:07 +01:00
c4337f7aec Factor mailbox_create() out of nat_reset() and files.c 2011-12-29 11:47:07 +01:00
8b7591f5d7 Change read and wire to never delete a corrupt mailbox
Before, rea() deleted the mailbox regardless of errors.  Acceptable
only when the user gets a chance to avoid that after the problem is
reported.  Not the case for "read y".

Not an issue for announcements, but treat them the same for
simplicity.
2011-12-29 11:47:07 +01:00
b6f666cff9 Clean up how read deals with new telegram arrivals
Fooling around with the file size is silly.  It works only because
read has flag C_MOD set, so they can only arrive while we're sitting
at the delete confirmation prompt, not during reading.

Simply try to read more telegrams instead.
2011-12-29 11:47:07 +01:00
43f562145e Change wire not to read more after confirming deletion
Telegram deletion deletes the mailbox.  If more telegrams arrive while
we wait for the player to confirm deletion, the mailbox again contains
unread telegrams, so we can't just delete it.  Instead, rea() loops to
read the new telegrams.

Announcements worked the same until Empire 3 put them in a single file
shared by all.  Since then, deleting announcements merely updates
nat_annotim, and there's no need to read new announcements after
getting the player's confirmation.  So don't.
2011-12-29 11:47:07 +01:00
5acdcfec63 Limit telegram squashing to 5s total
Before, only the time between adjacent telegrams was limited, not the
total time.
2011-12-29 11:47:07 +01:00
4d046738fd Don't lie "You have a new telegram" after read with inform off
Here's how telegram notification works with NF_INFORM off: typed_wu()
increments the telegram recipient's nat_tgms.  status(), running right
before command prompts, notifies the player when nat_tgms > 0, and
resets it.  Thus, we tell the player how many telegrams arrived since
the previous command prompt.

However, what we really want is something else, namely the number of
"new telegrams waiting".  That's what the notification message says,
after all.  Telegrams already printed by read shouldn't count, even
when they arrived since the previous command prompt.

Make them not count by clearing pending telegrams on read regardless
of toggle inform.

Same for announcements.
2011-12-29 11:47:07 +01:00
e8f0495950 Fix telegram notifications during read (toggle inform on)
Reset number of pending telegrams before delete prompt instead of
after.

Before, the client claimed pending telegrams at that prompt, because
it wasn't C_INFORMed of the read, yet.  Worse, if more telegrams
arrived while sitting at the prompt, the reset clobbered their number
and sent a bogus clear C_INFORM message, effectively hiding the new
arrivals from the player.
2011-12-29 11:47:07 +01:00
a0e91cbc5e Fix wire not to clear pending telegrams with toggle inform on
Broken since Empire 2 introduced toggle inform.
2011-12-29 11:47:07 +01:00
b98a806d82 Fix pending anno count for annos squashed together
Adjacent announcements are squashed together when the sender is the
same and the timestamp is "close enough".  Except typed_wu()
increments natstr member nat_ann regardless.  Fix that to work exactly
like nat_tgms.
2011-12-29 11:47:07 +01:00
17223e8fe2 Fix read not to split production report when update is slow
Adjacent telegrams are squashed together if type and sender are the
same, and the timestamp is "close enough".  This is done in two
places: rea() and typed_wu().  They're inconsistent: typed_wu()
ignores the timestamp for production reports since Empire 2, but rea()
doesn't.

Record typed_wu()'s decision in new telstr member tel_cont.  Use it in
rea().
2011-12-29 11:47:06 +01:00
a0b82b8d46 Simplify how typed_wu() counts telegrams
typed_wu() counts telegrams to update nat_tgms and, since Empire 2,
send C_INFORM messages.  Adjacent telegrams are squashed together if
type and sender are the same, and the timestamp is within TEL_SECONDS.

typed_wu() increments nat_tgms when it sends a telegram that read
doesn't squash into the previous one.

Since Empire 2, it also sends a C_INFORM message then.  Inexplicably,
it fails to use the same condition: it tests just new_tele, not
new_tele || np->nat_tgms == 0.  C_INFORM messages got missed, until
4.0.18 made rea() call clear_telegram_is_new().  Convoluted.

Send C_INFORM exactly when incrementing nat_tgms, and back out
4.0.18's fix.
2011-12-29 11:47:06 +01:00
a5bcb63b85 Fix clear_telegram_is_new() for TEL_NORM from POGO at the epoch
Purely theoretical, of course.
2011-12-29 11:47:06 +01:00
35e897f70b Clean up how telegram_is_new() detects production report
Test for TEL_UPDATE, not update_running.
2011-12-29 11:47:06 +01:00
ac5dac0690 Move clear_telegram_is_new() call to beginning of update
The call was added in 4.2.5 "so that the next telegram is flagged as
new and not part of the update".  Since the update sends only
TEL_UPDATE telegrams (the previous commit restored that property), and
nothing else does, the next telegram is flagged as new automatically,
except when it's from the next update.  Document that, and move the
call to a more natural place.
2011-12-29 11:47:06 +01:00
d46b168663 Ensure the update's production report isn't split by bulletins
During the update, wu() sends TEL_UPDATE telegrams ("Production
Report") instead of TEL_BULLETIN telegrams, but typed_wu() has no such
logic.  It's used by tele(), which doesn't run during the update, and
mpr(), which may, e.g. called from ship or mission code used by
autonav or sail.  This inserts bulletins in the middle of the
production report, splitting it apart.

Happens since mpr() was added in Empire 2.  Before, only tele() used
typed_wu() directly, and everything else wu().

Change mpr() to use wu().
2011-12-29 11:47:06 +01:00
9f9cbfb20c Saner error handling in typed_wu()
Leave nat_ann, nat_tgm alone and return -1 on all errors.  Before,
only failed open was handled that way.  Failed write and close were
logged and ignored.  While there, improve the log messages a bit.

Note: the return value fix has little effect.  It makes tele() log the
failure, which is redundant.  Everything else goes through wu() and
ignores the value.
2011-12-29 11:47:06 +01:00
0b2b51bbcb Drop superfluous fseek() from rea() 2011-12-29 11:47:06 +01:00
6d98cd3134 Make add require confirmation for unadvisable actions
Deleting a country in state STAT_SANCT, STAT_ACTIVE or STAT_GOD is
risky, because any references to this country become dangling, which
makes ef_verify() unhappy.  For a reason: we may well have code that
isn't prepared for dangling references, and breaks.

Replacing a country that is being used is risky, because it can get us
into weird states.  For instance, replacing a player by a visitor can
result in a visitor that owns stuff.
2011-12-29 11:47:06 +01:00
d2057af7a2 Make add refuse to touch a country while it's being played
I suspect player code could get terminally confused by country state
changing unexpectedly.  Not worth the risk.
2011-12-29 11:47:06 +01:00
881b6fbd2b Fix add not to crash on negative country number 2011-12-29 11:47:06 +01:00
b36727e7fb Don't bother giving POGO BTUs in files
Deity's BTUs get reset to maximum on login anyway.
2011-12-29 11:47:06 +01:00
37e9b6aa9c Create all deities with $123456789, not just POGO 2011-12-29 11:47:06 +01:00
ad308c5de8 Move setting nat_cnam, nat_pnam into nat_reset() 2011-12-29 11:47:06 +01:00
bb442abdcd Use nat_reset() for POGO in files.c
Requires moving it from subs/natsub.c to common/nat.c.
2011-12-29 11:47:06 +01:00