diff --git a/.efrocachemap b/.efrocachemap
index 8cc23b4c..62a6959a 100644
--- a/.efrocachemap
+++ b/.efrocachemap
@@ -4072,26 +4072,26 @@
"build/assets/workspace/ninjafightplug.py": "https://files.ballistica.net/cache/ba1/18/4b/787a9267e17be3c49966072581a5",
"build/assets/workspace/onslaughtplug.py": "https://files.ballistica.net/cache/ba1/20/f6/4ce9bc3c1f3732f6adf8237fbe9b",
"build/assets/workspace/runaroundplug.py": "https://files.ballistica.net/cache/ba1/a5/30/9058181df0b1255bf6950cbc7813",
- "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/1e/dc/97e852e2bd553825887ae9852756",
- "build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/54/0c/cf1fc5786cd44bf50ef116e053c2",
- "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/15/b2/0fd773bb3bf55249e87360edcb61",
- "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/19/43/2aa331c03048ce000662de5713f1",
- "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/1a/bc/48fb516727c8774640794b5c345c",
- "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/de/da/6b4057aa7f583ef6a1f79bbdbdd6",
- "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/13/6d/0d13fe395db109730e9f48c84e53",
- "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/7a/b4/98a5e5ed423107e3aca585cea6a9",
- "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/36/f2/6127c27e229de21395fbe6ca3dbe",
- "build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/fe/bb/67e0a6b2b9b5f65b1521df2e977b",
- "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/2a/62/a298f381499bbb60131db027c0bd",
- "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/a8/ed/6ac901d41db9709042e0e1ec0c31",
- "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/93/c5/dc0b4a2031435986ddf853e1f36f",
- "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/1b/39/6acfd7fcd05139612ea277ce315e",
- "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/53/b3/d8df1a3269ea4c7a9254b3f6d5e7",
- "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/bc/46/d6c92388b06f42c7df1e20df72d9",
- "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/4f/0f/6344b046dfee6ed0ba404fd102bd",
- "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/88/a9/b49c302ced5e4d7463597a4bddab",
- "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/0e/be/e62bb97312b709ba28e1a3017e20",
- "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/91/3f/5594522e68d039e3113ebd61e458",
+ "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/fb/2b/e9b87e05c1b8021e897421b33c0f",
+ "build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/fe/88/d586906b71912924f6b5be68417f",
+ "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/b7/e5/6b2a939582e0fa0e5453f1b30379",
+ "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/dd/d0/7b8dfb5b436c0f7fa90397acbded",
+ "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/9f/6d/a996b63727ca2552cf2abc7a1770",
+ "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/75/37/09a2c4b1cd721c62c81df5d13864",
+ "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/59/3f/b32b06bc31e0622175c69bebc51d",
+ "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/0c/8d/ca80f75886f8e872b6cdb409aeac",
+ "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/60/77/a59b63bacdded8410a5a20f0edb7",
+ "build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/67/f2/55962dc83849e412d4205813c572",
+ "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/9f/d7/da3f63ac008515d3c8b5b101cde7",
+ "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/d1/ec/b23825d099644ba8497a548369f2",
+ "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/02/ce/6eaea9df32a8a2d83993342b216e",
+ "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/20/8a/958c0db70b01b8e8011b3b696cc4",
+ "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/6b/aa/8695595c3ae00f2201fae34d6fcc",
+ "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/33/14/c5e32d098f60c0255d3a8b73fab2",
+ "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/eb/84/0ec9699d6658f46ac84dd0dce984",
+ "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/1c/a2/8171dc09551a84b5d219e6edd49e",
+ "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/0f/4b/9df8e37c59530603c8c613126195",
+ "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/8e/3c/624bac9b4856fa5cc537f8ec28f4",
"build/prefab/lib/linux_arm64_gui/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/d9/56/b0a16db98621500b473844ec39d6",
"build/prefab/lib/linux_arm64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/57/f9/f304c67d9958574b6b35de2ad13d",
"build/prefab/lib/linux_arm64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/04/55/a41ad832c081ff421039827d16c1",
@@ -4108,14 +4108,14 @@
"build/prefab/lib/mac_x86_64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/88/1a/1ea680450c3c9bc97147df4bf99d",
"build/prefab/lib/mac_x86_64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/91/b3/31b980ca2a000871408cbc7923e3",
"build/prefab/lib/mac_x86_64_server/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/67/d1/8b98ad3d0d67bf6bc23c2c9167cf",
- "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/bf/a7/927941d5af60608348087bb7ecd2",
- "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/c6/5d/da70d2fa77eae532b1561c2c8115",
- "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/27/fe/52a04ab3e85736e41a545262121d",
- "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/8f/5d/c3eceee36e50f5344d5308c443eb",
- "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/37/66/0b7542b46e953e9f7261a59a1ec8",
- "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/07/7c/488129817dede65aec11d0240144",
- "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/ff/99/be91e7ce7f8755aa1cbcc1b40df5",
- "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/8b/2d/8bb91aa1677da94c21573e2bf43a",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/42/ca/e8c47da7bab3ec0bddd17b5d9d36",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/13/0c/f422781a8977146f4cfeb8f80747",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/09/0a/f480d906922d9961c10adc00e380",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/5e/ac/790ed8a49f55ab7e61ece370e99d",
+ "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/17/cf/d35c4d5cb692903b1f67705f9c43",
+ "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/4e/a7/93fad7afb34dee1924f92b58451f",
+ "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/cb/02/fc48ae8cac41433539acd048e9ed",
+ "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/6a/39/f3d0300f87aadf8bf64313b0d69e",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "https://files.ballistica.net/cache/ba1/52/c6/c11130af7b10d6c0321add5518fa",
"src/assets/ba_data/python/babase/_mgen/enums.py": "https://files.ballistica.net/cache/ba1/38/c3/1dedd5e74f2508efc5974c8815a1",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "https://files.ballistica.net/cache/ba1/ea/6a/6a4721b144e5e297b542d2a0eea2",
diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml
index cf48990b..3fb2152f 100644
--- a/.idea/dictionaries/ericf.xml
+++ b/.idea/dictionaries/ericf.xml
@@ -2363,6 +2363,7 @@
rcvs
rdict
rdir
+ rdynamic
readexactly
readline
readlines
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 896a997e..801dd964 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,4 @@
-### 1.7.20 (build 21112, api 8, 2023-06-14)
+### 1.7.20 (build 21114, api 8, 2023-06-15)
- This seems like a good time for a `refactoring` release in anticipation of
changes coming in 1.8. Basically this means that a lot of things will be
@@ -329,6 +329,9 @@
Please holler if not.
- (build 21111) Fixed a server crash when an individual client player leaves the
game but doesn't disconnect from the server.
+- (build 21113) Linux builds now use the '-rdynamic' flag which means stack
+ traces we capture in the engine are more readable; they at least show mangled
+ c++ symbols instead of just addresses.
### 1.7.19 (build 20997, api 7, 2023-01-19)
diff --git a/ballisticakit-cmake/.idea/dictionaries/ericf.xml b/ballisticakit-cmake/.idea/dictionaries/ericf.xml
index 884c233c..48d543ab 100644
--- a/ballisticakit-cmake/.idea/dictionaries/ericf.xml
+++ b/ballisticakit-cmake/.idea/dictionaries/ericf.xml
@@ -1360,6 +1360,7 @@
rcade
rcva
rcvs
+ rdynamic
reaaaly
readexactly
readset
diff --git a/ballisticakit-cmake/CMakeLists.txt b/ballisticakit-cmake/CMakeLists.txt
index c2a8b08c..f5763dfe 100644
--- a/ballisticakit-cmake/CMakeLists.txt
+++ b/ballisticakit-cmake/CMakeLists.txt
@@ -744,6 +744,10 @@ add_executable(ballisticakit
# AUTOGENERATED_PUBLIC_END
)
+# Gets -rdynamic added when linking gcc builds which exports all symbols
+# which gives us more meaningful stack traces using backtrace_symbols().
+set_target_properties(ballisticakit PROPERTIES ENABLE_EXPORTS 1)
+
if (HEADLESS)
set_target_properties(ballisticakit PROPERTIES OUTPUT_NAME "ballisticakit_headless")
endif ()
diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py
index af04bb4f..3a975626 100644
--- a/src/assets/ba_data/python/baenv.py
+++ b/src/assets/ba_data/python/baenv.py
@@ -28,7 +28,7 @@ if TYPE_CHECKING:
# Build number and version of the ballistica binary we expect to be
# using.
-TARGET_BALLISTICA_BUILD = 21112
+TARGET_BALLISTICA_BUILD = 21114
TARGET_BALLISTICA_VERSION = '1.7.20'
_g_env_config: EnvConfig | None = None
diff --git a/src/assets/ba_data/python/bascenev1lib/game/deathmatch.py b/src/assets/ba_data/python/bascenev1lib/game/deathmatch.py
index 5968e9c0..ccbadd8d 100644
--- a/src/assets/ba_data/python/bascenev1lib/game/deathmatch.py
+++ b/src/assets/ba_data/python/bascenev1lib/game/deathmatch.py
@@ -133,7 +133,7 @@ class DeathMatchGame(bs.TeamGameActivity[Player, Team]):
# Base kills needed to win on the size of the largest team.
self._score_to_win = self._kills_to_win_per_player * max(
- 1, max(len(t.players) for t in self.teams)
+ 1, max((len(t.players) for t in self.teams), default=0)
)
self._update_scoreboard()
diff --git a/src/ballistica/base/networking/network_reader.cc b/src/ballistica/base/networking/network_reader.cc
index 788c2251..62f53f3a 100644
--- a/src/ballistica/base/networking/network_reader.cc
+++ b/src/ballistica/base/networking/network_reader.cc
@@ -89,6 +89,91 @@ void NetworkReader::PokeSelf() {
}
}
+void NetworkReader::DoPoll(bool* can_read_4, bool* can_read_6) {
+ struct pollfd fds[2]{};
+ int i{};
+ int index_4{-1};
+ int index_6{-1};
+
+ if (sd4_ != -1) {
+ fds[i].fd = sd4_;
+ fds[i].events = POLLIN;
+ index_4 = i++;
+ }
+ if (sd6_ != -1) {
+ fds[i].fd = sd6_;
+ fds[i].events = POLLIN;
+ index_6 = i++;
+ }
+ if (i > 0) {
+ int result = BA_SOCKET_POLL(fds, i, -1);
+ if (result == BA_SOCKET_ERROR_RETURN) {
+ // No big deal if we get interrupted occasionally.
+ if (g_core->platform->GetSocketError() == EINTR) {
+ // Aint no thang.
+ } else {
+ // Let's complain for anything else though.
+ Log(LogLevel::kError,
+ "Error on select: " + g_core->platform->GetSocketErrorString());
+ }
+ } else {
+ *can_read_4 = index_4 != -1 && fds[index_4].revents & POLLIN;
+ *can_read_6 = index_6 != -1 && fds[index_6].revents & POLLIN;
+ }
+ } else {
+ BA_LOG_ONCE(LogLevel::kError, "DoPoll called with neither sd4 or sd6 set.");
+ }
+}
+
+void NetworkReader::DoSelect(bool* can_read_4, bool* can_read_6) {
+ fd_set readset;
+ FD_ZERO(&readset);
+ if (sd4_ != -1) {
+ if (!g_buildconfig.ostype_windows()) {
+ // Try to get a clean error instead of a crash if we exceed our
+ // open file descriptor limit (except on windows where FD_SETSIZE
+ // is apparently a dummy value).
+ CheckFDThreshold(sd4_);
+ if (sd4_ < 0 || sd4_ >= FD_SETSIZE) {
+ FatalError("Socket/File Descriptor Overflow (sd4="
+ + std::to_string(sd4_) + ", FD_SETSIZE="
+ + std::to_string(FD_SETSIZE) + "). Please report this.");
+ }
+ }
+
+ FD_SET(sd4_, &readset); // NOLINT
+ }
+ if (sd6_ != -1) {
+ if (!g_buildconfig.ostype_windows()) {
+ // Try to get a clean error instead of a crash if we exceed our
+ // open file descriptor limit (except on windows where FD_SETSIZE
+ // is apparently a dummy value).
+ CheckFDThreshold(sd6_);
+ if (sd6_ < 0 || sd6_ >= FD_SETSIZE) {
+ FatalError("Socket/File Descriptor Overflow (sd6="
+ + std::to_string(sd6_) + ", FD_SETSIZE="
+ + std::to_string(FD_SETSIZE) + "). Please report this.");
+ }
+ }
+ FD_SET(sd6_, &readset); // NOLINT
+ }
+ int maxfd = std::max(sd4_, sd6_);
+ int sresult = select(maxfd + 1, &readset, nullptr, nullptr, nullptr);
+ if (sresult == BA_SOCKET_ERROR_RETURN) {
+ // No big deal if we get interrupted occasionally.
+ if (g_core->platform->GetSocketError() == EINTR) {
+ // Aint no thang.
+ } else {
+ // Let's complain for anything else though.
+ Log(LogLevel::kError,
+ "Error on select: " + g_core->platform->GetSocketErrorString());
+ }
+ } else {
+ *can_read_4 = sd4_ != -1 && FD_ISSET(sd4_, &readset);
+ *can_read_6 = sd6_ != -1 && FD_ISSET(sd6_, &readset);
+ }
+}
+
void NetworkReader::CheckFDThreshold(int val) {
if (passed_fd_threshold_) {
return;
@@ -130,67 +215,67 @@ auto NetworkReader::RunThread() -> int {
while (true) {
sockaddr_storage from{};
socklen_t from_size = sizeof(from);
- fd_set readset;
- FD_ZERO(&readset);
- if (sd4_ != -1) {
- if (!g_buildconfig.ostype_windows()) {
- // Try to get a clean error instead of a crash if we exceed our
- // open file descriptor limit (except on windows where FD_SETSIZE
- // is apparently a dummy value).
- CheckFDThreshold(sd4_);
- if (sd4_ < 0 || sd4_ >= FD_SETSIZE) {
- FatalError("Socket/File Descriptor Overflow (sd4="
- + std::to_string(sd4_) + ", FD_SETSIZE="
- + std::to_string(FD_SETSIZE) + "). Please report this.");
- }
- }
- FD_SET(sd4_, &readset); // NOLINT
- }
- if (sd6_ != -1) {
- if (!g_buildconfig.ostype_windows()) {
- // Try to get a clean error instead of a crash if we exceed our
- // open file descriptor limit (except on windows where FD_SETSIZE
- // is apparently a dummy value).
- CheckFDThreshold(sd6_);
- if (sd6_ < 0 || sd6_ >= FD_SETSIZE) {
- FatalError("Socket/File Descriptor Overflow (sd6="
- + std::to_string(sd6_) + ", FD_SETSIZE="
- + std::to_string(FD_SETSIZE) + "). Please report this.");
- }
- }
- FD_SET(sd6_, &readset); // NOLINT
- }
- int maxfd = std::max(sd4_, sd6_);
- int sresult = select(maxfd + 1, &readset, nullptr, nullptr, nullptr);
- if (sresult == -1) {
- // No big deal if we get interrupted occasionally.
- if (g_core->platform->GetSocketError() == EINTR) {
- // Aint no thang.
- } else {
- // Let's complain for anything else though.
- Log(LogLevel::kError,
- "Error on select: " + g_core->platform->GetSocketErrorString());
- }
+ bool can_read_4{};
+ bool can_read_6{};
+
+ // A bit of history here: Had been using select() to wait for input
+ // here, but recently I've started seeing newer versions of android
+ // crashing due to file descriptor counts going over the standard set
+ // limit size of ~1000 or whatnot. So switching to poll() instead which
+ // sounds like it
+ if (explicit_bool(true)) {
+ DoPoll(&can_read_4, &can_read_6);
} else {
- // Wait for any data on either of our sockets.
- for (int sd : {sd4_, sd6_}) {
- if (sd == -1 || !(FD_ISSET(sd, &readset))) {
- continue;
+ DoSelect(&can_read_4, &can_read_6);
+ }
+
+ for (int s_index : {0, 1}) {
+ int sd;
+ bool can_read;
+ if (s_index == 0) {
+ sd = sd4_;
+ can_read = can_read_4;
+ } else if (s_index == 1) {
+ sd = sd6_;
+ can_read = can_read_6;
+ } else {
+ FatalError("Should not get here.");
+ sd = -1;
+ can_read = false;
+ }
+ if (!can_read) {
+ continue;
+ }
+ ssize_t rresult =
+ recvfrom(sd, buffer, sizeof(buffer), 0,
+ reinterpret_cast(&from), &from_size);
+ if (rresult == 0) {
+ Log(LogLevel::kError,
+ "NetworkReader Recv got length 0; this shouldn't "
+ "happen");
+ } else if (rresult == -1) {
+ // This needs to be locked during any sd changes/writes.
+ std::scoped_lock lock(sd_mutex_);
+
+ // If either of our sockets goes down lets close *both* of
+ // them.
+ if (sd4_ != -1) {
+ g_core->platform->CloseSocket(sd4_);
+ sd4_ = -1;
}
- ssize_t rresult =
- recvfrom(sd, buffer, sizeof(buffer), 0,
- reinterpret_cast(&from), &from_size);
- if (rresult == 0) {
- Log(LogLevel::kError,
- "NetworkReader Recv got length 0; this shouldn't "
- "happen");
- } else if (rresult == -1) {
+ if (sd6_ != -1) {
+ g_core->platform->CloseSocket(sd6_);
+ sd6_ = -1;
+ }
+ } else {
+ assert(from_size >= 0);
+ auto rresult2{static_cast(rresult)};
+ // If we get *any* data while paused, kill both our
+ // sockets (we ping ourself for this purpose).
+ if (paused_) {
// This needs to be locked during any sd changes/writes.
std::scoped_lock lock(sd_mutex_);
-
- // If either of our sockets goes down lets close *both* of
- // them.
if (sd4_ != -1) {
g_core->platform->CloseSocket(sd4_);
sd4_ = -1;
@@ -199,118 +284,101 @@ auto NetworkReader::RunThread() -> int {
g_core->platform->CloseSocket(sd6_);
sd6_ = -1;
}
- } else {
- assert(from_size >= 0);
- auto rresult2{static_cast(rresult)};
- // If we get *any* data while paused, kill both our
- // sockets (we ping ourself for this purpose).
- if (paused_) {
+ break;
+ }
+ switch (buffer[0]) {
+ case BA_PACKET_POKE:
+ break;
+ case BA_PACKET_SIMPLE_PING: {
// This needs to be locked during any sd changes/writes.
std::scoped_lock lock(sd_mutex_);
- if (sd4_ != -1) {
- g_core->platform->CloseSocket(sd4_);
- sd4_ = -1;
- }
- if (sd6_ != -1) {
- g_core->platform->CloseSocket(sd6_);
- sd6_ = -1;
+ char msg[1] = {BA_PACKET_SIMPLE_PONG};
+ sendto(sd, msg, 1, 0, reinterpret_cast(&from),
+ from_size);
+ break;
+ }
+ case BA_PACKET_JSON_PING: {
+ if (rresult2 > 1) {
+ std::vector s_buffer(rresult2);
+ memcpy(s_buffer.data(), buffer + 1, rresult2 - 1);
+ s_buffer[rresult2 - 1] = 0; // terminate string
+ std::string response =
+ g_base->app_mode()->HandleJSONPing(s_buffer.data());
+ if (!response.empty()) {
+ std::vector msg(1 + response.size());
+ msg[0] = BA_PACKET_JSON_PONG;
+ memcpy(msg.data() + 1, response.c_str(), response.size());
+ std::scoped_lock lock(sd_mutex_);
+ sendto(
+ sd, msg.data(),
+ static_cast_check_fit(msg.size()),
+ 0, reinterpret_cast(&from), from_size);
+ }
}
break;
}
- switch (buffer[0]) {
- case BA_PACKET_POKE:
- break;
- case BA_PACKET_SIMPLE_PING: {
- // This needs to be locked during any sd changes/writes.
- std::scoped_lock lock(sd_mutex_);
- char msg[1] = {BA_PACKET_SIMPLE_PONG};
- sendto(sd, msg, 1, 0, reinterpret_cast(&from),
- from_size);
- break;
- }
- case BA_PACKET_JSON_PING: {
- if (rresult2 > 1) {
- std::vector s_buffer(rresult2);
- memcpy(s_buffer.data(), buffer + 1, rresult2 - 1);
- s_buffer[rresult2 - 1] = 0; // terminate string
- std::string response =
- g_base->app_mode()->HandleJSONPing(s_buffer.data());
- if (!response.empty()) {
- std::vector msg(1 + response.size());
- msg[0] = BA_PACKET_JSON_PONG;
- memcpy(msg.data() + 1, response.c_str(), response.size());
- std::scoped_lock lock(sd_mutex_);
- sendto(
- sd, msg.data(),
- static_cast_check_fit(msg.size()),
- 0, reinterpret_cast(&from), from_size);
- }
+ case BA_PACKET_JSON_PONG: {
+ if (rresult2 > 1) {
+ std::vector s_buffer(rresult2);
+ memcpy(s_buffer.data(), buffer + 1, rresult2 - 1);
+ s_buffer[rresult2 - 1] = 0; // terminate string
+ cJSON* data = cJSON_Parse(s_buffer.data());
+ if (data != nullptr) {
+ cJSON_Delete(data);
}
- break;
}
- case BA_PACKET_JSON_PONG: {
- if (rresult2 > 1) {
- std::vector s_buffer(rresult2);
- memcpy(s_buffer.data(), buffer + 1, rresult2 - 1);
- s_buffer[rresult2 - 1] = 0; // terminate string
- cJSON* data = cJSON_Parse(s_buffer.data());
- if (data != nullptr) {
- cJSON_Delete(data);
- }
- }
- break;
- }
- case BA_PACKET_REMOTE_PING:
- case BA_PACKET_REMOTE_PONG:
- case BA_PACKET_REMOTE_ID_REQUEST:
- case BA_PACKET_REMOTE_ID_RESPONSE:
- case BA_PACKET_REMOTE_DISCONNECT:
- case BA_PACKET_REMOTE_STATE:
- case BA_PACKET_REMOTE_STATE2:
- case BA_PACKET_REMOTE_STATE_ACK:
- case BA_PACKET_REMOTE_DISCONNECT_ACK:
- case BA_PACKET_REMOTE_GAME_QUERY:
- case BA_PACKET_REMOTE_GAME_RESPONSE:
- // These packets are associated with the remote app; let the
- // remote server handle them.
- if (remote_server_) {
- remote_server_->HandleData(
- sd, reinterpret_cast(buffer), rresult2,
- reinterpret_cast(&from),
- static_cast(from_size));
- }
- break;
-
- case BA_PACKET_CLIENT_REQUEST:
- case BA_PACKET_CLIENT_ACCEPT:
- case BA_PACKET_CLIENT_DENY:
- case BA_PACKET_CLIENT_DENY_ALREADY_IN_PARTY:
- case BA_PACKET_CLIENT_DENY_VERSION_MISMATCH:
- case BA_PACKET_CLIENT_DENY_PARTY_FULL:
- case BA_PACKET_DISCONNECT_FROM_CLIENT_REQUEST:
- case BA_PACKET_DISCONNECT_FROM_CLIENT_ACK:
- case BA_PACKET_DISCONNECT_FROM_HOST_REQUEST:
- case BA_PACKET_DISCONNECT_FROM_HOST_ACK:
- case BA_PACKET_CLIENT_GAMEPACKET_COMPRESSED:
- case BA_PACKET_HOST_GAMEPACKET_COMPRESSED: {
- // These messages are associated with udp host/client
- // connections.. pass them to the logic thread to wrangle.
- std::vector msg_buffer(rresult2);
- memcpy(msg_buffer.data(), buffer, rresult2);
- PushIncomingUDPPacketCall(msg_buffer, SockAddr(from));
- break;
- }
-
- case BA_PACKET_HOST_QUERY: {
- g_base->app_mode()->HandleGameQuery(buffer, rresult2, &from);
-
- // HandleGameQuery(buffer, rresult2, &from);
- break;
- }
-
- default:
- break;
+ break;
}
+ case BA_PACKET_REMOTE_PING:
+ case BA_PACKET_REMOTE_PONG:
+ case BA_PACKET_REMOTE_ID_REQUEST:
+ case BA_PACKET_REMOTE_ID_RESPONSE:
+ case BA_PACKET_REMOTE_DISCONNECT:
+ case BA_PACKET_REMOTE_STATE:
+ case BA_PACKET_REMOTE_STATE2:
+ case BA_PACKET_REMOTE_STATE_ACK:
+ case BA_PACKET_REMOTE_DISCONNECT_ACK:
+ case BA_PACKET_REMOTE_GAME_QUERY:
+ case BA_PACKET_REMOTE_GAME_RESPONSE:
+ // These packets are associated with the remote app; let the
+ // remote server handle them.
+ if (remote_server_) {
+ remote_server_->HandleData(
+ sd, reinterpret_cast(buffer), rresult2,
+ reinterpret_cast(&from),
+ static_cast(from_size));
+ }
+ break;
+
+ case BA_PACKET_CLIENT_REQUEST:
+ case BA_PACKET_CLIENT_ACCEPT:
+ case BA_PACKET_CLIENT_DENY:
+ case BA_PACKET_CLIENT_DENY_ALREADY_IN_PARTY:
+ case BA_PACKET_CLIENT_DENY_VERSION_MISMATCH:
+ case BA_PACKET_CLIENT_DENY_PARTY_FULL:
+ case BA_PACKET_DISCONNECT_FROM_CLIENT_REQUEST:
+ case BA_PACKET_DISCONNECT_FROM_CLIENT_ACK:
+ case BA_PACKET_DISCONNECT_FROM_HOST_REQUEST:
+ case BA_PACKET_DISCONNECT_FROM_HOST_ACK:
+ case BA_PACKET_CLIENT_GAMEPACKET_COMPRESSED:
+ case BA_PACKET_HOST_GAMEPACKET_COMPRESSED: {
+ // These messages are associated with udp host/client
+ // connections.. pass them to the logic thread to wrangle.
+ std::vector msg_buffer(rresult2);
+ memcpy(msg_buffer.data(), buffer, rresult2);
+ PushIncomingUDPPacketCall(msg_buffer, SockAddr(from));
+ break;
+ }
+
+ case BA_PACKET_HOST_QUERY: {
+ g_base->app_mode()->HandleGameQuery(buffer, rresult2, &from);
+
+ // HandleGameQuery(buffer, rresult2, &from);
+ break;
+ }
+
+ default:
+ break;
}
}
}
diff --git a/src/ballistica/base/networking/network_reader.h b/src/ballistica/base/networking/network_reader.h
index a1dcd946..d5e81c22 100644
--- a/src/ballistica/base/networking/network_reader.h
+++ b/src/ballistica/base/networking/network_reader.h
@@ -34,6 +34,8 @@ class NetworkReader {
private:
void CheckFDThreshold(int val);
+ void DoSelect(bool* can_read_4, bool* can_read_6);
+ void DoPoll(bool* can_read_4, bool* can_read_6);
void OpenSockets();
void PokeSelf();
auto RunThread() -> int;
diff --git a/src/ballistica/scene_v1/support/scene_v1_app_mode.cc b/src/ballistica/scene_v1/support/scene_v1_app_mode.cc
index 2ac0915b..28572833 100644
--- a/src/ballistica/scene_v1/support/scene_v1_app_mode.cc
+++ b/src/ballistica/scene_v1/support/scene_v1_app_mode.cc
@@ -926,14 +926,10 @@ auto SceneV1AppMode::GetNetworkDebugString() -> std::string {
return net_info_str;
}
auto SceneV1AppMode::GetDisplayPing() -> std::optional {
- float ping{};
- char ping_str[32];
if (ConnectionToHost* connection_to_host =
connections()->connection_to_host()) {
if (connection_to_host->can_communicate()) {
return connection_to_host->current_ping();
- // snprintf(ping_str, sizeof(ping_str), "%.0f ms", ping);
- // return ping_str;
}
}
return {};
diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc
index cf23ce19..af7f9257 100644
--- a/src/ballistica/shared/ballistica.cc
+++ b/src/ballistica/shared/ballistica.cc
@@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
namespace ballistica {
// These are set automatically via script; don't modify them here.
-const int kEngineBuildNumber = 21112;
+const int kEngineBuildNumber = 21114;
const char* kEngineVersion = "1.7.20";
auto MonolithicMain(const core::CoreConfig& core_config) -> int {
diff --git a/src/ballistica/shared/buildconfig/buildconfig_common.h b/src/ballistica/shared/buildconfig/buildconfig_common.h
index 11caaa7c..35e175e0 100644
--- a/src/ballistica/shared/buildconfig/buildconfig_common.h
+++ b/src/ballistica/shared/buildconfig/buildconfig_common.h
@@ -185,6 +185,18 @@ namespace ballistica {
#define BA_ARCADE_BUILD 0
#endif
+#ifndef BA_SOCKET_POLL_FD
+#define BA_SOCKET_POLL_FD pollfd
+#endif
+
+#ifndef BA_SOCKET_ERROR_RETURN
+#define BA_SOCKET_ERROR_RETURN -1
+#endif
+
+#ifndef BA_SOCKET_POLL
+#define BA_SOCKET_POLL poll
+#endif
+
#ifndef BA_SOCKET_SEND_DATA_TYPE
#define BA_SOCKET_SEND_DATA_TYPE uint8_t
#endif
diff --git a/src/ballistica/shared/buildconfig/buildconfig_windows_common.h b/src/ballistica/shared/buildconfig/buildconfig_windows_common.h
index 2f745cce..86654b77 100644
--- a/src/ballistica/shared/buildconfig/buildconfig_windows_common.h
+++ b/src/ballistica/shared/buildconfig/buildconfig_windows_common.h
@@ -39,6 +39,11 @@
#define BA_SOCKET_SEND_LENGTH_TYPE int
#define BA_SOCKET_SETSOCKOPT_VAL_TYPE char
+#define BA_SOCKET_POLL WSAPoll
+#define BA_SOCKET_POLL_FD POLLFD
+
+#define BA_SOCKET_ERROR_RETURN SOCKET_ERROR
+
// On windows we always bundle python.
#define BA_CONTAINS_PYTHON_DIST 1
diff --git a/src/ballistica/shared/networking/networking_sys.h b/src/ballistica/shared/networking/networking_sys.h
index 9e2ccbbf..f0a11d64 100644
--- a/src/ballistica/shared/networking/networking_sys.h
+++ b/src/ballistica/shared/networking/networking_sys.h
@@ -15,6 +15,7 @@
#include
#include
#include
+#include
#include
#include
#include