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