Commit graph

125 commits

Author SHA1 Message Date
phosit
a95579a046
Fix UI when connecting to a server fails
When the connection fails, it wasn't possible to close the progress
window.
Now `PollNetworkClient` also resolves the previous promise.
2026-05-17 17:20:37 +02:00
phosit
7758c98e7c
Remove IXmppClient.h
Some checks failed
checkrefs / lfscheck (push) Has been cancelled
checkrefs / checkrefs (push) Has been cancelled
lint / cppcheck (push) Has been cancelled
lint / copyright (push) Has been cancelled
lint / jenkinsfiles (push) Has been cancelled
pre-commit / build (push) Has been cancelled
This is now possible after 0a455fbe2d.
2026-04-14 19:38:05 +02:00
phosit
bc17e212bb
Launch session at construction of Net*
This way it's statically assured that the session aren't launched
multiple times.
2026-04-11 13:46:33 +02:00
phosit
578aea3b09
Remove CNetClient::SetupServerData
It has to be called before `SetupConnection` is called. Now the
server-data is setup during the constructor.
When connecting using the lobby, the data isn't known at construction
time. Then it is done at the start of  `TryToConnectWithSTUN`.
2026-04-11 13:41:43 +02:00
phosit
19c6977872
Request connection-data in the client constructor
This way it doesn't has to be requested manually and it can't be
requested to late.
2026-04-11 13:41:43 +02:00
phosit
dbe89d10ae
Pass the controllerSecret to the CNet* constructor
It wasn't clear when to call `SetControllerSecret` now it can't be done
wrong. Also the mutex has to be locked less often.
2026-04-11 13:41:23 +02:00
phosit
d33fb147bc
Pass the game password at construction to Net*
CNetClient and CNetServer are constructed for a single match. The
password of a game can not be changed after creating the match. When the
password is passed to the constructor it's not possible to invoke the
functions in the wrong order and the `ENSURE` can be "checked at
compile-time" so to say.
2026-04-11 13:38:58 +02:00
phosit
040e0b29a2
Initialize members in the class of CNet*
Sometimes the order was wrong.
2026-04-11 13:38:53 +02:00
phosit
6893654cfc
Do the gamestate compression in the task-manager
Some checks failed
checkrefs / lfscheck (push) Has been cancelled
checkrefs / checkrefs (push) Has been cancelled
lint / cppcheck (push) Has been cancelled
lint / copyright (push) Has been cancelled
lint / jenkinsfiles (push) Has been cancelled
pre-commit / build (push) Has been cancelled
This reduces the stutter when a client joins.
The decompression isn't put on the task manager. As the client would
have to wait for that either way. Also a new polling loop would have to
be introduced.

The compression code is moved to the file transferer so all data send
through it gits compressed.

Refs: #4210
2026-04-09 19:03:46 +02:00
phosit
262c5c037e
Use promises to fetch net messages
Refs: #5585
2026-03-13 18:07:56 +01:00
phosit
d29890efb0
Split NetSession into two files
Refs: #5212
2026-03-11 21:03:52 +01:00
phosit
cfb742c914
Return the value from GuiPoll 2025-12-17 13:39:17 +01:00
phosit
f23dde2f73
Use StructuredClone in m_GuiMessageQueue
The elements have to be cloned either way. Now they don't have to be
traced when they are in the queue.
2025-12-17 13:39:16 +01:00
phosit
f03be7b568
Initialize more members of CNetClient
The username and the jid have to be set before the client is connected.
With this commit it's not possible to initialize them to late.
2025-12-14 17:23:05 +01:00
Ralph Sennhauser
3647921bed
Fix some includes all over the place
Make include-what-you-use happy with some files in source and fix what
needs to be fixed.

Ref: #8086
Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
2025-08-13 19:38:21 +02:00
Ralph Sennhauser
3c1a37985a
Fix includes in source/network
Make include-what-you-use happy with files in source/network and
fix what needs to be fixed.

Ref: #8086
Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
2025-07-23 18:18:47 +02:00
phosit
dd26f3a802 Restrict param type of FSM events
Previously the param type was `void*` now the type has to be specified
as template parameter of the `CFsm`.
With this commit some casts can be removed.
2025-06-26 16:42:04 +02:00
Paul Robinson
5b98a647dc Adding Engine Version and Mod name/version checks to multiplayer handshake.
Incrementing protocol version as handshake messages have changed.
2025-01-25 07:39:32 +01:00
Daniel Roschka
274500eb37
Always use STUN for hosting games using the lobby
This makes using STUN mandatory for games hosted using the multiplayer
lobby. The motivation for that is a reduction in complexity, because
right now if STUN is disabled we use a home-grown STUN-like logic, which
got implemented before Pyrogenesis got STUN support.

That home-grown logic relies on a custom ejabberd module (mod_ipstamp),
which inserts the external IP-address of a host in the response messages
when a host registers a game. Originally mod_ipstamp was also used to
inform all potential players of a hosts IP-address, however that has
already been removed to let hosts to only share their IP-address with
players actually joining their game.

Removing the home-grown logic and instead always relying on STUN removes
complexity in Pyrogenesis and the lobby server and also eases hosting
games for players, as they don't have to figure out anymore whether they
need to enable STUN or not.

These changes shouldn't negatively impact the ability of Pyrogenesis to
handle different types of NAT or broken networks. There is one
difference though: While the custom logic using mod_ipstamp utilized TCP
as transport protocol, the STUN implementation in Pyrogenesis currently
uses UDP. That doesn't allow hosts with UDP-connectivity issues to
resolve their external IP-address anymore, however without
UDP-connectivity they aren't able to successfully host games anyway, as
the actual game updates are transferred using UDP as well.
2025-01-20 06:52:14 +01:00
phosit
e04506814a Multicast chat messages
Only the sender and the recipients receive the chat messages.
This commit only has an affecto on messages where the addressee(s) are
selected through the dropdown. Addressee(s) selected with a "/" command
are still sent to evevyone and filteret by the receiver.
2024-12-27 19:32:03 +01:00
phosit
b90280855f Multiplayer saved games
Enables to save multiplayer games.
When the savegame is loaded, the settings are frozen (except the non-AI-player assignment settings).
2024-12-19 21:36:51 +01:00
phosit
20b4937ffd Enable multiple RequestTypes 2024-12-19 21:36:51 +01:00
Vantha
960bd5eace Unique network transmission handling of flares
This patch addresses issues concerning a1796ed71f:

Allow for a more elegant implementation of observer flares.
And still display flares even if the sender is lagging behind:
Split off flares from simulation commands.
Remove the new, problematic 'observer commands' entirely.
Provide an engine function 'SendNetworkFlare' to the JS interface.
-> which sets off the (pretty ordinary) transmission process.
Add a new type of net messages exclusively for flares
-> contains the flare's position and its sender's GUID.
2024-12-16 18:03:25 +01:00
phosit
3a5ad160f7 Make CFsm a template
The context doesn't have to be converted to `void*` and back.


Differential Revision: https://code.wildfiregames.com/D5253
This was SVN commit r28074.
2024-05-04 16:13:02 +00:00
phosit
78652aa92c Use std::function instead of inhereting from CNetFileReceiveTask
The user doesn't have to fiddle with `std::shared_ptr`.
And two (more unrelated) things: use `std::unordered_map`, use a
`std::find_if` in the callback.

Comments By: @vladislavbelov, @Stan
Differential Revision: https://code.wildfiregames.com/D5239
This was SVN commit r28048.
2024-03-09 14:31:43 +00:00
vladislavbelov
ffc4a56b9f Revert non-ASCII characters from source and configuration files introduced in 157c6af18e.
Fixes #6846

Differential Revision: https://code.wildfiregames.com/D5185
This was SVN commit r27965.
2023-12-03 00:30:12 +00:00
bb
157c6af18e Make the space in 0 A.D. non-breaking throughout the codebase.
Avoid cases of filenames
Update years in terms and other legal(ish) documents
Don't update years in license headers, since change is not meaningful

Will add linter rule in seperate commit

Happy recompiling everyone!

Original Patch By: Nescio
Comment By: Gallaecio
Differential Revision: D2620
This was SVN commit r27786.
2023-07-27 20:54:46 +00:00
phosit
80bcf944bc Don't convert actions to void*
Accepted By: @vladislavbelov
Differential Revision: https://code.wildfiregames.com/D5044
This was SVN commit r27783.
2023-07-25 07:50:33 +00:00
Itms
ef71533d70 Use a lower default MTU for ENet hosts, and make it configurable.
This fixes packet loss issues on some VPN solutions.

Patch By: sera
Differential Revision: https://code.wildfiregames.com/D4967
This was SVN commit r27599.
2023-04-10 08:21:07 +00:00
Angen
8cec96270b Don't create thread on failed connection
Differential revision: D4545
Fixes: #6442

This was SVN commit r26649.
2022-03-14 17:19:42 +00:00
Stan
b6012ec606 Fix false positive; undefined variable in NetworkClient.cpp
refs #6321 for further cleanups.
Discussed with: @wraitii
Differential Revision: https://code.wildfiregames.com/D4258
This was SVN commit r25908.
2021-09-09 18:00:17 +00:00
vladislavbelov
d9d19543b5 Adds std namespace to shared_ptr usages in network and engine.
This was SVN commit r25527.
2021-05-22 19:28:40 +00:00
wraitii
d7a4fb7c20 Try to punch a hole through local firewalls, and fallback to localhost.
Fixes (probably rare) regression in 2034136560.

Differential Revision: https://code.wildfiregames.com/D3999
This was SVN commit r25515.
2021-05-22 08:34:00 +00:00
wraitii
7bfcd9f78b Additional entropy when hashing match passwords.
The purpose of our client-side hashing for lobby game passwords is to
prevent malicious hosts from getting valuable passwords from clients
(e.g. accidentally typing their lobby password instead of the game, or
even their email password, etc).
However, the hashing was deterministic (and rather simple), making it
possible to compute rainbow tables and recover user passwords anyways.

By adding more variation, including some that cannot so easily be
controlled by the host (the client name), this becomes impractical. The
password hashing function used is rather fast, but given the base low
probability of mistypes, this seems fine.

Differential Revision: https://code.wildfiregames.com/D3459
This was SVN commit r25459.
2021-05-18 14:47:36 +00:00
wraitii
895e4e6aa6 StunClient code cleanup: use enet functions, endianness
Instead of using platform-specific sockets, use enet_socket* functions
(which ends up doing the same).
Clean up some confusing APIs, removing the distinction between finding
the public IP for the host/join.

Fix endianness support & use simpler code.

Refs D364 / 61261d14fc (and some subsequent fixing diffs).

Differential Revision: https://code.wildfiregames.com/D3970
This was SVN commit r25453.
2021-05-17 15:14:10 +00:00
wraitii
2034136560 Implement a workaround for routers without NAT loopback.
This allows joining a lobby game hosted on the same network (behind the
same NAT gateway).
This is relatively primitive to keep things simple: if the server and
the client have the same public IP, it is assumed that they are on the
same network and the client instead requests the local IP.

Differential Revision: https://code.wildfiregames.com/D3944
This was SVN commit r25448.
2021-05-16 15:34:38 +00:00
wraitii
4f972bc623 Split off JSON-related function from ScriptInterface, clean up headers.
Follows 34b1920e7b.

JSON functions and ToString are movec to their own headers.
Also clean out a few PersistentRooted usage to use the 2-phase init to
clean up scriptInterface usage.

With these functions split off, we can finally clean out headers and
remove ScriptInterface.h from most of them, in favour of smaller and
more precise headers.


Take the opportunity to clarify some comments regarding Mutability.

Differential Revision: https://code.wildfiregames.com/D3961
This was SVN commit r25434.
2021-05-14 10:18:03 +00:00
wraitii
0f60bf3a97 Split off Object-related functions from ScriptInterface
Follows 34b1920e7b.

This splits off the object-related functions, such as
[Set/Get/Has]Property, CreateObject, CreateArray, FreezeObject.

It also puts the definitions in the header itself, which might end up
with faster code here & there, though perhaps slower compilation time
(somewhat doubtful since we already included most things anyways).

Differential Revision: https://code.wildfiregames.com/D3956
This was SVN commit r25430.
2021-05-13 17:23:52 +00:00
wraitii
e94faf7827 Don't hardcode the "0ad" resource into lobby XMPP & hosting
XMPP JID has a concept of 'resources', which can be used to
differentiate multiple clients of the same account.

We currently hardcode this 'resource' to '0ad' in two places:
- The 0 A.D. client always uses '0ad'
- The network code expects a host resource to be '0ad' when connecting.

As noted in 0fd8aa2a77#31215, it is less effort to store the JI
D directly. This patch does that. It also makes 0 A.D. use a different
resource each time.
Note that resources ought not contain particular information, as the
XMPP server is free to
 clobber it. I keep '0ad-' here for debug purposes.

This allows:
- multiple 0 A.D. instances to log on the lobby at the same time (not
massively useful, but good for debugging sometimes)
- hosting a game with a custom resource, which will potentially make it
easier to have dedi
cated servers on one account.

Note that hosting multiple games on one account is currently not
supported and will have weird behaviour on the lobbybots side. They
should be upgraded independently of this.

Refs #3556

Differential Revision: https://code.wildfiregames.com/D3500
This was SVN commit r25407.
2021-05-09 12:51:32 +00:00
wraitii
87fc52b780 MP: don't enforce game init attributes synchronization in PREGAME.
The NetServer stored a complete copy of the game Init Attributes, which
it sent to new clients on updates from the controller. This worked well,
but prevents incremental updates and other unrelated messages from being
sent.

This changes the system so that:
- in PREGAME state, the server does not update its copy of the game init
attributes
- the server forwards game setup messages from the controller to all
clients
- Joining clients get a full copy of the Settings, when joining, from
the controller (this is a js-driven behaviour - other situations might
not need do it).
- Make the StartNetworkGame message take a copy of the final init
attributes, to ensure synchronization (and simplify some logic).

In practice, this:
- makes it possible to send different types of gamesetup messages (this
introduces two: a regular update and the full 'initial-update' for new
clients).
- moves some C++ hardcoding into JS - here in essence the PREGAME server
state is now init-attributes-agnostic.
- does not change much for readiness control - the server already needed
to force a change at game start to set random elements.

Note that the loading page is currently still receiving the 'local' game
attributes, which assumes that all clients are correctly synchronized
(they should be).

Refs #3806, #3049

Differential Revision: https://code.wildfiregames.com/D3714
This was SVN commit r25099.
2021-03-22 10:13:27 +00:00
wraitii
d4c2cf4430 Increase MP Command delay to 4 turns, decrease MP turns to 200ms.
To hide network latency, MP turns send commands not for the next turn
but N turns after that (introduced in c684c211a2).
Further, MP turn length was increased to 500ms compared to 200ms SP
turns (introduced in 6a15b78c98).
Unfortunately, increasing MP turn length has negative consequences:
- makes pathfinding/unit motion much worse & unit behaviour worse in
general.
- makes the game more 'lag-spikey', since computations are done less
often, but thus then can take more time.

This diff essentially reverts 6a15b78c98, instead increasing
COMMAND_DELAY from 2 to 4 in MP. This:
- Reduces the 'inherent command lag' in MP from 1000ms to 800ms
- Increases the lag range at which MP will run smoothtly from 500ms to
600ms
- makes SP and MP turns behave identically again, removing the
hindrances described above.

As a side effect, single-player was not actually using COMMAND_DELAY,
this is now done (can be used to simulate MP command lag).

Refs #3752

Differential Revision: https://code.wildfiregames.com/D3275
This was SVN commit r25001.
2021-03-03 21:02:57 +00:00
wraitii
113fefeeb7 Netcode: Identify controller client via a secret key
The 'controller' of an MP game (the host in general, though dedicated
servers would change that) is currently whoever first tells the server
that it is. This can be abused since it relies on trusting the clients.

This changes that logic: the server defines a 'controller secret', and
the first client to sent the correct controller secret is the
controller. This is safe assuming the secret is unknowable enough (the
current solution wouldn't pass strict cryptography tests, but it's
likely good enough).

Reverts 1a3fb29ff3, which introduced the 'trust the clients' mechanic,
as a change over 'the first local IP is controller'.

Necessary step towards dedicated server, if we want to use the regular
gamesetup (Refs #3556)

Differential Revision: https://code.wildfiregames.com/D3075
This was SVN commit r24952.
2021-02-27 17:44:59 +00:00
wraitii
4cc824d620 Net Server: Verify password in Authenticate
Follows 1a8de6d2b8.
Validate the password when a client joins a game, so even a player that
knows the connection data cannot join.

Refs #3556, Refs #5913

Differential Revision: https://code.wildfiregames.com/D3438
This was SVN commit r24775.
2021-01-23 18:04:36 +00:00
Angen
1a8de6d2b8 Hide ip and port from users until they want to join, add optional password
Current issue with the lobby, is that we make ips of hosts public for
anyone to read. This patch consists of 3 parts.
1.) Removing ips and ports from lobby javascript
2.) Removing need of script on the server to attach public ips to game
stanza by asking the host using xmppclient as proxy.
3.) Implementing password protected matches, to deny this information to
not trusted players.

Further description:
Do not send ports and stunip to the bots.

Removed from stanza.
Do not send ip to the lobby.

Removed from mapping gamelist from backend to gui (still on the backend
side, because it is done by script on 0ad server).
Get ip and ports on request when trying to connect.

On the host side, ask stun server what is host's public ip and remember
it.
On the client side, send iq through xmppclient to the hosting player and
ask for ip, port and if Stun is used, then if answer is success,
continue
   with connecting, else fail.
Add optional password for matches.

Add password required identifier to the stanza.
Allow host to setup password for the match. Hash it on the host side and
store inside Netserver. If no password is given, matches will behave
as it is not required.
On the client side, if password for the match is required, show
additional window before trying to connect and ask for password, then
hash it
and send with iq request for ip, port and stun.
Server will answer with ip, port and stun only if passwords matches,
else will asnwer with error string.
Some security:
Passwords are hashed before sending, so it is not easy to guess what
users typed. (per wraitii)
Hashes are using different salt as lobby hashing and not using usernames
as salt (as that is not doable), so they are different even typing the
same password as for the lobby account.
Client remembers which user was asked for connection data and iq's id of
request. If answer doesn't match these things, it is ignored. (thnx
user1)
Every request for connection data is logged with hostname of the
requester to the mainlog file (no ips).
If user gets iq to send connection data and is not hosting the match,
will respond with error string "not_server".
If server gets iq::result with connection data, request is ignored.

Differential revision: D3184
Reviewed by: @wraitii
Comments by: @Stan, @bb, @Imarok, @vladislavbelov
Tested in lobby

This was SVN commit r24728.
2021-01-20 18:31:39 +00:00
wraitii
5ee8354e99 Fix windows SEH hook when crashing in an std::thread
Follows 107d3d461f and other 'pthread->std::thread' diffs.

Windows uses Structured Exception Handling to allow reporting errors
(both C++ and hardware) nicely. This works by wrapping the code in a
__try __catch block.
The pthread wrapper did this automatically, but we now need to do it
explicitly for std::thread.

Tested by: Stan
Differential Revision: https://code.wildfiregames.com/D3261
This was SVN commit r24530.
2021-01-10 08:39:54 +00:00
wraitii
2d40068cd1 Thread the NetClient session.
This threads the netclient session, which avoids timeouts when the
main-thread is not polling (map creation, very long simulation frames).

Unlike the NetServer, which should be as independent as possible from
the main thread, the NetClient is fundamentally tied to the game thread.
Therefore, this only threads the session object.
To ensure good performance and ease-of-use, lock-free queues for
in/out-going messages are used.

This fixes artificial timeouts, while also improving actual ping reports
(since frame-time is no longer a factor).
It effectively reverts D1513/eda236522c and 2e7e1c0b2b, all hacks around
lag-timeouts (and bits of 1a3fb29ff3).

Based on a patch by: Stan
Comments by: Vladislavbelov
Fixes #3700, refs #3373

Differential Revision: https://code.wildfiregames.com/D2848
This was SVN commit r24518.
2021-01-06 15:26:11 +00:00
Stan
e009d322cc Add missing files in 4942cabab5
This was SVN commit r24488.
2020-12-31 14:27:02 +00:00
wraitii
fd8f5abd2e [SM52 2/2] Update to Spidermonkey 52 APIs.
No particularly noteworthy changes, as most complex API changes were
already supported in SM45 and done.
The addition of JSStructuredCloneData allows to remove our custom class.

Changes:
- InformalValueTypeName is back in the API, so remove our
implementation.
- Stop using JSRuntime entirely in favour of JSContext*
- JSPropertyDescriptor is renamed.
- CompartmentOptions are tweaked slightly (no functional changes)
- JS::Construct - API update.
- JSClass split - API update.
- A js.msg error message was removed, so we had to use a different one.
- Tests fix: fix comparison of union instances
- Disable warning in spidermonkey Vector.h
- Update error reporting to SM52 (minor API updates)
- Ignore warnings about unused return values (would come from OOM, which
isn't recoverable)

Most of the patching was done by Itms.

Tested by: Stan, Freagarach
Fixes #4893

Differential Revision: https://code.wildfiregames.com/D3095
This was SVN commit r24203.
2020-11-18 14:39:04 +00:00
wraitii
25490bfec3 Improve JS Exception handling.
- Check for pending exceptions after function calls and script
executions.
- Call LOGERROR instead of JS_ReportError when there is a conversion
error in FromJSVal, since that can only be called from C++ (where JS
errors don't really make sense). Instead, C++ callers of FromJSVal
should handle the failure and, themselves, either report an error or
simply do something else.
- Wrap JS_ReportError since that makes updating it later easier.

This isn't a systematical fix since ToJSVal also ought return a boolean
for failures, and we probably should trigger errors instead of warnings
on 'implicit' conversions, rather a preparation diff.

Part of the SM52 migration, stage: SM45 compatible (actually SM52
incompatible, too).

Based on a patch by: Itms
Comments by: Vladislavbelov, Stan`
Refs #742, #4893

Differential Revision: https://code.wildfiregames.com/D3093
This was SVN commit r24187.
2020-11-15 18:29:17 +00:00
wraitii
ee0d204bf6 Wrap JSAutoRequest and replace usage of JSContext* with the wrapper.
JSAutoRequest is required before calling into most JSAPI methods, for GC
reasons.
Calling it is required and fragile as one must not forget.
Further, SM52 and later make manipulating JSContext* dangerous as that
can cross Compartment(Realm in SM68) barriers (and ScriptInterface now
matches a Compartment).

The solution to both problems is to avoid using JSContext* in 0 A.D.
itself. To achieve this, a Request class is introduced, and must be used
to access a JSContext* from a scriptInterface. Further, Request is
passed to other ScriptInterface functions isntead of JSContext*, making
it obvious that the caller has already called it, reducing errors and
redundant JSAutoRequest calls.
Only JSNative functions now get a naked JSContext* without protection,
but the likelihood of forgetting a request is lower since many
ScriptInterface functions now expect it.

JSContext* is directly passed to JSAPI functions only.

Part of the SM52 migration, stage: SM45 compatible

Based on a patch by: Itms
Tested By: Freagarach
Refs #4893

Differential Revision: https://code.wildfiregames.com/D3088
This was SVN commit r24176.
2020-11-13 13:18:22 +00:00