Alut's pkg-config definition only adds the top-level include directory
containing the AL directory to the include paths. This works on most
platforms because OpenAL adds that AL directory. However, with nix,
these two directories are distinct and the build fails.
The optimizer is going to remove dead code anyway, and has the
additional advantage of doing syntax checking, so the code won't
silently break when someone changes something.
Scenario parameters are useful in a script-only context (such as the one
mape uses). C4AchievementGraphics introduces a dependency on C4Surface
which isn't available in that context.
Previously, it would just use first pixel of the texture image. With our
current textures, this is a pretty bad approximation. For example,
firestone ends up yellow rather than red.
Additionally, this helps tools like mape/ocmapgen which do not load any
texture graphics but just set the texture's average color.
This also fixes the sky color which was previously overwritten.
Previously, the SReq packet would only be sent after receiving an
ID from the netpuncher. Instead, we can send the request as soon as the
C4NetIOUDP connection setup finishes.
With the IPv6 support, hosts now often list around 20 addresses.
However, most of these are local only and thus rarely result in a
successful connection. With the introduction of address sorting in
7d5596220 ("Sort addresses used for initial host connection",
2017-02-26), the connection succeeds with the first few addresses most
of the time.
This commit changes the initial connection process to start with only
the first four addresses. After 100 ms, it proceeds with the next four
addresses and so on. This should reduce the packet volume significantly
as the connection should be established after only one or two steps.
We may want to tweak the parameters if this turns out to make joining
slower in practise. In a "normal" setup, the first four addresses should
be the IPv6 privacy and stable addresses, and the next four addresses
should include the IPv4 addresses from masterserver and netpuncher.
100 ms are long enough to get an answer from the host and short enough
to not bother the player too much.
Instead of "Compiler" and "Decompiler", which make me look up what's
even going on each time I see them, use the standard terms "serializer"
and "deserializer".
C4Language is the only consumer of GetRelativePath. It cannot handle
arbitrarily sized paths, so discourage new code from using it by moving
it to C4Language.cpp.
Also remove the buffer size parameter which was always defaulted anyway
and use template parameter deduction to always get the correct size.
With the addition of IPv6, some computers with lots of addresses are
reaching the old address limit of 20 addresses. We'll have to see how
this works out in practise. Maybe we'll have to do the connection in
stages to prevent sending out too many packets at once (like only
connecting to the first five addresses initially, then after a timeout
the next five, and so on).
Computers with multiple (possibly virtual) network adapters can have
tons of link-local fe80::/64 IPv6 addresses. Connections to those hosts
would run into a timeout before getting to public addresses behind the
link-local ones.
By sorting the address list, we can prioritize public IPv6 addresses if
supported by the client, then try IPv4 before working through the swamp
of link-local addresses.
After GameOver(), the global function CollectStatistics() is called
which in turn calls CollectStats() on all definitions and the Scenario.
The results are collected into a proplist and sent to the masterserver
as JSON.
The intended purpose is to collect statistics like weapon kill counts
and evaluate them across all online games to improve balancing.
Compilation without an associated ScriptHost happens in a call to eval,
in which case we'll fall back to the default warning settings (because
we don't have a location which we could get settings from).
Fixes#1891.
We don't benefit at all from privacy addresses as we're publishing all
local addresses in any case. By preferring stable addresses, we can
avoid reconnection issues after the preferred address changes.
This API is defined in RFC5014, but apparently only implemented in
Linux.
Yeah. Aul looks up function parameters before local variables when
trying to resolve an identifier. Usually this doesn't matter, but you'll
notice it if you have a local variable and a parameter with the same
name, because the variable should be initialized to nil yet you get the
value of the parameter.
This commit introduces a new Aul directive "#warning", which can be used
to enable or disable warnings for a particular piece of code.
"#warning enable" enables all warnings.
"#warning disable" disables all warnings.
"#warning enable empty_parameter_in_call" selectively enables one
specific warning while not affecting any other.
All warnings that used to be controlled by Developer.ExtraWarnings
remain disabled by default.
Aul will now emit a warning if you type something like
if (...); return true;
(note the semicolon right after the condition). It will also warn on an
empty 'else' branch. If you actually intended to have a no-op there, use
an empty block '{}'.
In contrast to getifaddrs(), /proc/net/if_inet6 allows filtering
deprecated privacy addresses. As these addresses generally won't be
useful for new connections, there's no reason to include them and they
only cause unnecessary connection attempts.
On Windows, we cannot resolve addresses using getaddrinfo() before
initializing Winsock. By storing the address as string, the address
parsed later on.
Forcing a static address does not work for IPv6 where everyone has
multiple addresses that change over time. For example, adding a new
connection would fail if the preferred privacy address changes during
a game.
On Linux, all IPv6 sockets are dual-stack per default; on Windows, they
are not. It's still a good idea to set the option on Linux as well as
the default value can be changed.
When connecting via TCP, C4NetIO still creates IPv4 sockets, so no dual
stack option is required there.
It's not actually used anywhere, but it's not broken now!
This also moves the low-level and OS-specific GetLocalAddresses code to
C4NetIO where it's fitting better than in C4Network2Client.
We use ff02::1 as discovery multicast address.
This "all nodes" multicast address is good enough for discovery in the
local network as packets there are likely broadcasted over ethernet
anyways.
When many PXS were at the same location (e.g. because of fast/multiple pumps pumping into a basin), only one PXS per frame could be inserted because insertion of one PXS would postpone insertion of additional PXS in the same frame until they finished their slide movement.
This caused some scenarios like Rapid Refining to become very frustrating, because adding extra pumps didn't actually do anything (unless you tricked the insertion by putting the output into the basin).
Now insert them directly if slide movement led to an insertion position.
This should not break anything because script players are created by scripts and one may expect sane behaviour. This is useful to block entry for normal players into a team.
C4Update needs to access some internal data of C4Group and uses a
special derived class (C4GroupEx). Make everything it doesn't want to
tamper with private so it's more obvious what is and isn't accessed from
outside the class.
The pByChild parameter to C4Group::AdvanceFilePtr was never used except
to pass it to itself recursively, and C4Group::ProcessOut was never used
at all.
Systems that don't come with getopt/getopt_long in their runtime library
need to link to our private copy; link that and use the right const-ness
for its prototype.
Instead of jumping forward and back repeatedly per iteration, we're
moving the incrementor past the body, which is when it's supposed to be
executed anyway.
Letting the constant resolver throw exceptions prevented us from doing
checking on later initializers anyway, so instead we'll send them to the
error handler. As a special bonus this makes it so we don't crash when
a global variable initializer has errors. Fixes#1850, #1855.
The material map is 1D texture that contains information about every
material-texture combination. There is no point in linear filtering,
i.e. trying to interpolate between two materials such as gold and granite
or whichever two materials happen to be adjacent in the material map texture.
This might or might not be relevant to #1841, but should be more correct
behavior in any case.
I don't know why the viewports are deleted with deleteLater(), but it leads
to an OpenGL context getting deselected behind our back, and so we don't know
when is a good time to re-select it. This leads to termination of the engine
when selecting File->Close (Ctrl+W) in the editor, because the graphics
re-initialization fails with no GL context active.
Instead, just delete the viewport widget immediately, which works fine at
least on Linux. This is also recommended by the Qt documentation at
http://doc.qt.io/qt-5/qopenglwidget.html.
When removing a viewport, then also remove it from the internal list of
viewports. Otherwise, we might attempt to delete it again later. Fixes
crash on editor shutdown on Linux.
This fixes a crash on Linux when exiting the editor. It was caused by
C4Console::~C4Console being called by the C++ runtime after after main()
returned. The C4Console destructor then goes and deletes all the Qt
resources (QApplication and friends), and that caused a segfault, maybe
because some of the static Qt structures have already been deallocated.
Fix this by making the destruction of the Qt components deterministic. Add
a function "DeleteConsoleWindow" which deletes all the Qt components, and
call this function in C4Console::Clear.