Commit Graph
180 Commits
Author SHA1 Message Date
Goober5000 ef73e2572d unlimited mission titles
Some code refactoring to allow mission titles to be strings of any length.  Titles that are too long to actually display (based on string width) will be visibly truncated using `font::force_fit_string`, but the underlying title will not be affected.  Multiplayer is still subject to the 31-character length limit, so titles sent over the network will still have characters truncated.

Also removes some redundant calls to `gr_get_string_size`, since `font::force_fit_string` returns the fitted string width.
2026-05-12 11:31:20 -04:00
Cliff GordonandClaude Opus 4.6 c8201660d5 Fix multi sync screen showing wrong player status for non-host players (#7359)
Net_player[idx] (pointer arithmetic from current player) was used instead
of Net_players[idx] (global array index), causing the status display to
read from wrong offsets. This coincidentally worked for the host at index 0
but showed incorrect status for all other players — most visibly on
standalone servers where no client is at index 0.

Fixes #7358

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-04-07 13:23:57 -04:00
Cliff GordonandClaude Opus 4.6 cfd9e0087c Fix multiplayer standalone crash: client stats race + host accept code (#7319)
* Fix multiplayer standalone crash: client stats race + host accept code

Fixes a crash in multiplayer PXO/tracker games hosted on a standalone
server where clients crash at debrief close after scoring a kill:

  pilotfile.cpp:295: Ship kills of '<ship class>' not found,
  should have been added by pilotfile::update_stats

Two independent root causes were found, both of which must be fixed for
correct behavior:

--- Root cause 1: race condition in multi_sexp_end_mission() (sexp.cpp) ---

The previous code called send_debrief_event() before
multi_handle_end_mission_request() as a "hack" to skip the warp-out
sequence when an end-mission SEXP fires. On standalone servers this is
a race condition: scoring_eval_kill only runs on the master, and the
master hasn't broadcast m_okKills to clients yet at the point
multi_sexp_end_mission() is called. Entering debrief this early causes
scoring_level_close() to run with zeroed m_okKills, so
Pilot.update_stats() creates no kill entries for that session.
When debrief_close() later calls scoring_backout_accept() it cannot
find those entries and hits the UNREACHABLE.

Fix: Remove the send_debrief_event() call entirely. The normal flow
via multi_handle_end_mission_request() has the server broadcast stats
first and then send MISSION_END, which causes the client to enter
debrief with correct kill data already populated. The master enters
debrief through sexp_end_mission() -> send_debrief_event() as before.

The behavioral side-effect of removing this hack: clients that go
through the normal warp-out sequence will no longer skip it on
end-mission. Clients in a state where they cannot warp still receive
immediate debrief via multi_handle_sudden_mission_end().

--- Root cause 2: host accept code never set on PXO standalone (multiui.cpp) ---

In multi_debrief_accept_hit() and multi_debrief_esc_hit(), when the
game is a PXO/tracker game and the local player is the game host
(NETINFO_FLAG_GAME_HOST), the code calls send_store_stats_packet() to
tell clients to record their stats. It then sets
Multi_debrief_stats_accept_code = 1 via the per-client response path
inside the NETINFO_FLAG_AM_MASTER block.

On a standalone server the game host is NOT the master
(NETINFO_FLAG_AM_MASTER is false for the client-side host). The
NETINFO_FLAG_AM_MASTER block is skipped entirely, and
send_store_stats_packet() uses multi_io_send_to_all_reliable() which
skips the local player — so the host never receives its own packet.
Multi_debrief_stats_accept_code stays at -1 (unset).

When debrief_close() checks this value and sees it is not 1, it
assumes stats were tossed or the window was closed without accepting,
and runs scoring_backout_accept() unconditionally. With fix 1 in place
this no longer crashes (entries exist), but silently strips all session
kill credit from the host's pilot record.

Fix: After the send_store_stats_packet() block, call
multi_debrief_stats_accept() unconditionally for the game host so the
accept code is set locally regardless of whether the host is also the
standalone master.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

* Preserve end-mission warp-out skip via deferred debrief entry

The previous fix removed send_debrief_event() from
multi_sexp_end_mission() entirely, which was correct for the stats
race condition but had a side effect: clients would no longer skip the
warp-out sequence when an end-mission SEXP fires.  The warp-out skip
was an intentional feature — process_endgame_packet() checks whether
the client is already in debrief state and, if so, bypasses
multi_warpout_all_players().

Restore the original behavior by deferring the send_debrief_event()
call to process_endgame_packet() rather than eliminating it.
multi_sexp_end_mission() now sets Multi_sexp_end_mission_pending=true
before calling multi_handle_end_mission_request().  When the client
receives the MISSION_END packet, process_endgame_packet() checks the
flag, calls send_debrief_event() there, then falls through to the
debrief-state check which skips the warp-out exactly as before.

This is safe because send_endgame_packet() calls multi_broadcast_stats()
before sending MISSION_END.  Both use reliable delivery, so stats are
guaranteed to be received and applied before MISSION_END is processed,
meaning scoring_level_close() now sees correct kill data when
send_debrief_event() fires.

Alt-J-initiated mission ends are unaffected: the flag is never set,
so the warp-out proceeds normally for those paths.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

* Revert multiui.cpp accept code change — tracker master owns stats

The previous change added multi_debrief_stats_accept() calls for the
game host in multi_debrief_accept_hit() and multi_debrief_esc_hit() to
work around Multi_debrief_stats_accept_code staying -1 on a standalone
server.  This was based on incorrect analysis.

In PXO tracker games the standalone master is intentionally the sole
authority for stat storage (via multi_fs_std_tracker_store_stats() in
multi_standalone_postgame_close()).  The host and clients must not save
stats to their local pilot files independently.  Multi_debrief_stats_
accept_code remaining -1 and triggering scoring_backout_accept() on the
host is correct behavior: kills are backed out of the local pilot file
because the tracker holds the authoritative record, not the local file.

The race condition fix (deferred send_debrief_event()) is sufficient to
prevent the crash: Pilot.update_stats() now creates kill entries with
correct m_okKills data, so scoring_backout_accept() can find and remove
them cleanly rather than hitting the UNREACHABLE.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

* Move Multi_sexp_end_mission_pending from multiutil to multi and reset in multi_vars_init()

Addresses review feedback: the flag has no relation to multiutil, and
resetting it in multi_vars_init() ensures it is always cleared between
missions regardless of which code path was taken.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Claude Sonnet 4.6 <[email protected]>
2026-04-03 09:26:23 -04:00
Taylor Richards 99585310b6 fix memory error when culling active games list (#7332) 2026-03-30 17:34:34 -04:00
Goober5000 c428a22150 Merge pull request #7097 from Goober5000/snprintf_size
fix the size parameter of snprintf and vsnprintf
2026-02-13 00:50:38 -05:00
Goober5000 306f34a574 update force_fit_string and bounds in calling functions (#7161)
Rewrite `force_fit_string` to be more robust and to remove the potential for memory access violations.  Also audit all of the length parameters in the calling functions - some of them were the buffer size, not the length.  This should fix the mysterious crash in the mission log screen.
2025-12-25 08:08:46 +09:00
Goober5000 5f8e2c9475 fix the size parameter of snprintf and vsnprintf
These functions accept a size parameter that *includes* the null terminator, so tweak function calls accordingly.
2025-10-23 12:41:44 -04:00
Taylor Richards a12c1de012 fix memory access error with active games list (#6964)
During maintenance of the active games list it's possible for the list to be
cleared before a stale item is removed leading to a access violation. So we
need to confirm the list isn't empty when attemping to erase the stale  entry.

This also fixes a bug where the list entry index is incremented even when an
entry is removed which can cause an improper selection index being used.
2025-08-22 07:18:38 -04:00
Taylor Richards 5fd06b40fe fix multi crash loading campaigns (#6871)
A minor bug in #6077 resulted in a crash loading campaigns on the multi ui.
The bug itself was not fatal, however it triggered a cascade of poor error
handling which led to a crash. A lot of these issues date back to retail.
This fixes the minor bug, and hopefully adds enough error handling to
preemptively squash a repeat of the crash problem.
2025-07-25 21:15:31 -04:00
Taylor Richards 552f9990d9 remove support for memory mapped files (#6748)
FSO doesn't appear to use this any longer. And even when it was enabled the
requirements made it largely useless anyway. Removing to clean up cfile a
bit and so we don't have to keep maintaining it.
2025-06-05 17:53:13 -04:00
Taylor Richards f288ef7101 fix issues with get_text() and set_text() for INPUTBOX (#6089) 2024-04-08 19:19:03 -04:00
Mike Nelson 6b1d9304ed Multi general api (#6078) 2024-04-07 16:45:51 -04:00
Mike Nelson 052b4b29e9 Multi sync API (#6077)
* multi host settings ui initial setup

(cherry picked from commit bcb31c327653329e62e4430815fe1e981751f9dc)

* Finish the rest of the API

* include enums

* set these

* Close game needed

* Handle accepting the host setup

* Don't need to be master to set these and add ways to check master and self

* add client ui to this PR because

* Allow getting the player state string

* Multi sync api methods

* unused variables

* Fix state checking

(cherry picked from commit fcde973cdf)

* typo

* address feedback

(cherry picked from commit ecb33e7cc6)
2024-04-02 17:34:06 +00:00
Mike Nelson ea8e356b63 Multi Start Game UI API (#6068)
* methods for the Multi Start Game UI API

* missed a comma

* properly close the session

* name instead of password
2024-04-02 16:56:56 +00:00
Mike Nelson 9bba53c3e8 Multi Join API (#6059)
* methods required for the multi join ui api

* Move color setting because the API doesn't need it either
2024-04-02 12:19:20 -04:00
mjn-mixael 8dfeca4ac3 address feedback 2024-02-26 22:30:59 -06:00
mjn-mixael bb4898cb04 assertion error 2024-02-26 22:30:59 -06:00
mjn-mixael 6e38656658 Convert Active_games_head to an SCP_list to prepare for the SCPUI API 2024-02-26 22:30:59 -06:00
mjn-mixael 7ce3217f17 multi login info & ip address list API 2023-12-06 12:49:38 -06:00
mjn-mixael 33a1b1f8ca clean up and fix 2023-12-06 09:59:36 -06:00
mjn-mixael 95baa85750 remove the cd checks that always returned true anyway 2023-11-29 11:27:31 -06:00
Goober5000 ae89ed2b9d convert some instances of frand_range to Random::next
Some of the `frand_range` calls were used for integer calculations, so we can use `Random::next` now.

This also reduces the number of C-style casts in the codebase.
2023-11-06 01:48:29 -05:00
JohnAFernandez 2cb12b8ff7 Merge pull request #5593 from MjnMixael/rank_display_names
Rank display name and title
2023-11-03 14:34:55 -04:00
John Fernandez 2bb22a2153 Return to avoid nullptr dereference
For coverity 1093461.  If this is null, the function is done at this point.
2023-10-23 10:24:13 -04:00
John Fernandez 018c22eee1 Make sure Net_player is not null here
For coverity 1093460. Net_player should never be null here, but it is C++ after all.
2023-10-23 10:24:13 -04:00
mjn-mixael 52b7a3d198 rank display name and title 2023-09-09 10:54:04 -05:00
Goober5000 15daaf2633 additional cleanup from PR 5462
Some streamlining and constifying of the readyroom popup list and associated functions.

Followup to #5462.
2023-07-13 01:54:25 -04:00
MjnMixael fbb209ef6b Modular rank table (#4854)
* vectorize ranks

* Add modular table parsing

* int

* comments

* prevent field overwriting if tbm is used

* address feedback

* off by one
2023-02-14 17:25:52 +09:00
JohnAFernandez 4e8203a066 Patch in-game joining crashes
Patches multiple things about in-game joining to allow it to be enabled by default.
2022-11-14 10:30:27 -05:00
MjnMixael ef850ad302 Handle errors from create_wings() in an API friendly way (#4730) 2022-09-30 16:46:45 +09:00
Taylor Richards df6cf572ac convert multi timestamp()'s to ui_timestamp() where appropriate
A bit overkill for some of this but just covering the bases.

 * fix issues with in-game join
 * fix multi messaging and multi pause screen
 * make sure maintenance stuff (pings, voice, file xfer, etc.) isn't
   affected by pausing or time compression
2022-05-17 07:50:50 -04:00
Goober5000 8e2e825204 add UI_TIMESTAMP type and switch some timestamps to use it 2022-02-12 19:01:15 -05:00
wookieejedi 0f3f19d5d8 fix spelling 2022-01-08 15:29:20 -05:00
wookieejedi 7f8957ba0d Fix text overflow on multi-related screen
Multiplayer screens such as PXO lobby, chat boxes, and multi-game setup screens had hard coded values for the number of lines to display. These would only work correctly with the default .vf font01 from retail. If a mod or user used a TTF or other .vf font than text would spill over. This PR makes these values take into the account the font used.

Tested and works as expected with TTF fonts and the retail fonts.  Marking as draft to see what others think.
2022-01-08 13:57:58 -05:00
Goober5000 5e7a6ece52 log when missions are skipped due to XSTR mismatch
As a follow-up to #2343, users might wonder why their mission isn't showing up in the tech room, so log a friendly message.
2021-07-16 22:17:36 -04:00
Taylor Richards 2e30674823 Merge pull request #3386 from notimaginative/add_firewall_status
add firewall status
2021-05-30 10:15:43 -04:00
JohnAFernandez 9d7acbcc9d Update Function Name and comment to describe what it actually is (#3451)
Change find_player_id to find_player_index, since that is what it does
2021-05-29 19:21:36 -04:00
BMagnu 6c2ebab01c Fix erroneous line break generation for non-ASCII string and high resolutions (#3439)
* Added a byte limit for line length in split function

* Fix call error

* Ádd missing limits import

* Change hardcoded values into defines

* Cleanup default argument
2021-05-24 17:38:58 -04:00
Joshua Glatt 144d484c85 Replace rand() calls with a Random class (#3332) 2021-05-04 18:26:06 -07:00
Taylor Richards 9e4ab292ac fix game announcement issue causing first firewall check to fail 2021-04-16 18:35:46 -04:00
JohnAFernandez 5bb934119c Limit instances of Client Collisions to Avoid Instant Death (#3164)
* Limit instances of Client Collisions to Avoid Instant Death

* Set timestamps correctly (take 2)

* Handle server check the same everywhere

* Clearer Logic Here
2021-03-18 17:24:08 -04:00
Taylor Richards 0e55c36877 update netgame_descript_packet()
(based on PR 2109 by Cyborg17)

 - support compaign descriptions (Mantis 1826)
 - allow sending multiple packets to get entire description
 - update description of selected game on join screen if needed
2020-12-24 09:38:23 -05:00
Taylor Richards 088f4422db set HEADER_LENGTH to a fixed size
This should *never* be something that can be changed
at runtime
2020-12-24 09:38:23 -05:00
Taylor Richards c5356c6af7 Merge pull request #2895 from notimaginative/mdns
Replace multicast code with mDNS/DNS-SD
2020-12-08 20:32:28 -05:00
JohnAFernandez 5e4c42426f Cleaner of Multi stats (#2918) 2020-11-26 12:13:35 -05:00
Taylor Richards 3e7fedd997 avoid doing mdns stuff in incompatible states 2020-11-24 10:06:27 -05:00
Taylor Richards cd5e1c297b replace old multicast code with mdns/dns-sd 2020-11-21 00:57:03 -05:00
Taylor Richards fb249d35cc add new NETPLAYER states
- Cutscenes
 - Fiction Viewer
 - Command Briefings
 - Red Alert
2020-11-07 16:44:11 -05:00
Taylor Richards 92be33ad9c first pass at IPv6 support 2020-08-30 00:01:00 -04:00
JohnAFernandez f832b5baf1 Go back to login if you're trying to use PXO 2020-07-16 22:33:47 -04:00