diff --git a/src/Features/Demo/NetworkGhostPlayer.cpp b/src/Features/Demo/NetworkGhostPlayer.cpp index 20a288a80..75f560e44 100644 --- a/src/Features/Demo/NetworkGhostPlayer.cpp +++ b/src/Features/Demo/NetworkGhostPlayer.cpp @@ -370,7 +370,7 @@ void NetworkManager::Connect(sf::IpAddress ip, unsigned short int port, bool spe sf::Packet connection_packet; connection_packet << HEADER::CONNECT << this->udpSocket.getLocalPort() << this->name.c_str() << DataGhost{{0, 0, 0}, {0, 0, 0}, 0, false} << this->modelName.c_str() << engine->GetCurrentMapName().c_str() << ghost_TCP_only.GetBool() << GhostEntity::set_color << spectator; - this->tcpSocket.send(connection_packet); + SendPacketTCP(connection_packet); { sf::SocketSelector tcpSelector; @@ -470,7 +470,7 @@ void NetworkManager::Disconnect() { sf::Packet packet; packet << HEADER::DISCONNECT << this->ID; - this->tcpSocket.send(packet); + SendPacketTCP(packet); this->selector.clear(); this->tcpSocket.disconnect(); @@ -557,9 +557,9 @@ void NetworkManager::SendPlayerData() { } if (!ghost_TCP_only.GetBool()) { - this->udpSocket.send(packet, this->serverIP, this->serverPort); + SendPacketUDP(packet); } else { - this->tcpSocket.send(packet); + SendPacketTCP(packet); } } @@ -590,9 +590,9 @@ void NetworkManager::SendPlayerData() { packet.append(buffer, sizeof(msg) + nBytesWritten); if (!ghost_TCP_only.GetBool()) { - this->udpSocket.send(packet, this->serverIP, this->serverPort); + SendPacketUDP(packet); } else { - this->tcpSocket.send(packet); + SendPacketTCP(packet); } } } @@ -623,7 +623,7 @@ void NetworkManager::NotifyMapChange() { ghostLeaderboard.GhostLoad(this->ID, this->splitTicksTotal, ghost_sync.GetBool()); packet << HEADER::MAP_CHANGE << this->ID << engine->GetCurrentMapName().c_str() << this->splitTicks << this->splitTicksTotal; - this->tcpSocket.send(packet); + SendPacketTCP(packet); } void NetworkManager::NotifySpeedrunFinished(const bool CM) { @@ -648,14 +648,14 @@ void NetworkManager::NotifySpeedrunFinished(const bool CM) { packet << time.c_str(); - this->tcpSocket.send(packet); + SendPacketTCP(packet); } void NetworkManager::SendMessageToAll(std::string msg) { addToNetDump("send-message", msg.c_str()); sf::Packet packet; packet << HEADER::MESSAGE << this->ID << msg.c_str(); - this->tcpSocket.send(packet); + SendPacketTCP(packet); std::string name = this->name; if (this->spectator) name += " (spectator)"; this->PrintMessage(name.c_str(), GhostEntity::set_color, msg); @@ -738,7 +738,7 @@ void NetworkManager::SendPing() { addToNetDump("send-ping", nullptr); sf::Packet packet; packet << HEADER::PING << this->ID; - this->tcpSocket.send(packet); + SendPacketTCP(packet); this->pingClock.restart(); } @@ -915,10 +915,10 @@ void NetworkManager::Treat(sf::Packet &packet, bool udp) { response << HEADER::HEART_BEAT << this->ID << token; if (udp) { addToNetDump("send-heartbeat", Utils::ssprintf("UDP;%X", token).c_str()); - this->udpSocket.send(response, this->serverIP, this->serverPort); + SendPacketUDP(response); } else { addToNetDump("send-heartbeat", Utils::ssprintf("TCP;%X", token).c_str()); - this->tcpSocket.send(response); + SendPacketTCP(response); } break; } @@ -954,7 +954,7 @@ void NetworkManager::Treat(sf::Packet &packet, bool udp) { sf::Packet confirm_packet; confirm_packet << HEADER::COUNTDOWN << this->ID << uint8_t(1); addToNetDump("send-countdown", "1"); - this->tcpSocket.send(confirm_packet); + SendPacketTCP(confirm_packet); } else if (step == 1) { // Exec this->StartCountdown(); } @@ -1135,6 +1135,24 @@ void NetworkManager::Treat(sf::Packet &packet, bool udp) { } } +void NetworkManager::SendPacketTCP(sf::Packet &packet) { + Scheduler::OnMainThread([=]() mutable { + auto status = this->tcpSocket.send(packet); + if (status != sf::Socket::Status::Done) { + console->Print("Failed to send packet to server: %d\n", status); + } + }); +} + +void NetworkManager::SendPacketUDP(sf::Packet &packet) { + Scheduler::OnMainThread([=]() mutable { + auto status = this->udpSocket.send(packet, this->serverIP, this->serverPort); + if (status != sf::Socket::Status::Done) { + console->Print("Failed to send packet to server: %d\n", status); + } + }); +} + void NetworkManager::UpdateGhostsPosition() { // Copy the pool since rendering via Lerp tries to lock the pool // further down in processing @@ -1180,7 +1198,7 @@ void NetworkManager::UpdateModel(const std::string modelName) { sf::Packet packet; addToNetDump("send-model-change", modelName.c_str()); packet << HEADER::MODEL_CHANGE << this->ID << this->modelName.c_str(); - this->tcpSocket.send(packet); + SendPacketTCP(packet); } } @@ -1190,7 +1208,7 @@ void NetworkManager::UpdateColor() { addToNetDump("send-color-change", Utils::ssprintf("%02X%02X%02X", col.r, col.g, col.b).c_str()); sf::Packet packet; packet << HEADER::COLOR_CHANGE << this->ID << col; - this->tcpSocket.send(packet); + SendPacketTCP(packet); } void NetworkManager::NotifyTaunt(const std::string name) { @@ -1198,7 +1216,7 @@ void NetworkManager::NotifyTaunt(const std::string name) { addToNetDump("send-taunt", name.c_str()); sf::Packet packet; packet << HEADER::TAUNT << this->ID << name.c_str(); - this->tcpSocket.send(packet); + SendPacketTCP(packet); } void NetworkManager::NotifyLocator(Vector position, Vector normal) { @@ -1206,7 +1224,7 @@ void NetworkManager::NotifyLocator(Vector position, Vector normal) { addToNetDump("send-locator", Utils::ssprintf("%d;%.1f,%.1f,%.1f;%.1f,%.1f,%.1f", this->ID, position.x, position.y, position.z, normal.x, normal.y, normal.z).c_str()); sf::Packet packet; packet << HEADER::LOCATOR << this->ID << position << normal; - this->tcpSocket.send(packet); + SendPacketTCP(packet); } bool NetworkManager::AreAllGhostsAheadOrSameMap() { diff --git a/src/Features/Demo/NetworkGhostPlayer.hpp b/src/Features/Demo/NetworkGhostPlayer.hpp index 892b43d67..f02943202 100644 --- a/src/Features/Demo/NetworkGhostPlayer.hpp +++ b/src/Features/Demo/NetworkGhostPlayer.hpp @@ -173,6 +173,8 @@ class NetworkManager { void SendPing(); void ReceiveUDPUpdates(std::vector &buffer); void Treat(sf::Packet &packet, bool udp); + void SendPacketTCP(sf::Packet &packet); + void SendPacketUDP(sf::Packet &packet); void UpdateGhostsPosition(); std::shared_ptr GetGhostByID(uint32_t ID); diff --git a/src/Features/Speedrun/SpeedrunTimer.cpp b/src/Features/Speedrun/SpeedrunTimer.cpp index 3b8fbfeb2..78563ca4f 100644 --- a/src/Features/Speedrun/SpeedrunTimer.cpp +++ b/src/Features/Speedrun/SpeedrunTimer.cpp @@ -192,6 +192,7 @@ static void handleCoopPacket(const void *data, size_t size) { g_timerInterface->total = SpeedrunTimer::GetTotalTicks(); switch (t) { + case PacketType::ID_REQUEST: case PacketType::SYNC: break; case PacketType::START: diff --git a/src/Features/Tas/TasTools/SetAngleTool.cpp b/src/Features/Tas/TasTools/SetAngleTool.cpp index a140dfe85..d7a5e262a 100644 --- a/src/Features/Tas/TasTools/SetAngleTool.cpp +++ b/src/Features/Tas/TasTools/SetAngleTool.cpp @@ -53,7 +53,7 @@ std::shared_ptr SetAngleTool::ParseParams(std::vectorGetLevelNameShort(engine->engineClient->ThisPtr()); + if (!currentMap || mapName != currentMap) return; + + auto manager = GetPortalLeaderboardManager(); + if (manager && Client::GetLeaderboard(manager, mapName.c_str())) return; + + // The native panel retries while Steam or another leaderboard request is busy. + if (attempts < 600) { + Scheduler::InHostTicks(1, [mapName, generation, attempts]() { + PreloadChallengeLeaderboard(mapName, generation, attempts + 1); + }); + } +} + DETOUR_COMMAND(Client::openleaderboard) { Client::openleaderboard_callback(args); if (args.ArgC() == 2 && !strcmp(args[1], "4") && client->GetChallengeStatus() == CMStatus::CHALLENGE) { + if (sar_disable_challenge_stats_hud.GetInt() == -1 && GetPortalLeaderboardManager && Client::GetLeaderboard) { + auto mapName = engine->GetLevelNameShort(engine->engineClient->ThisPtr()); + if (mapName && mapName[0]) { + PreloadChallengeLeaderboard(mapName, ++challengeLeaderboardPreloadGeneration); + } + } + client->g_leaderboardOpen = true; auto ticks = 6; if (sar_disable_challenge_stats_hud.GetInt() > 1) ticks = sar_disable_challenge_stats_hud.GetInt(); @@ -1189,6 +1217,12 @@ bool Client::Init() { if (sar.game->Is(SourceGame_Portal2)) { Client::CalcViewModelLag = (decltype(Client::CalcViewModelLag))Memory::Scan(client->Name(), Offsets::CalcViewModelLag); + + GetPortalLeaderboardManager = (decltype(GetPortalLeaderboardManager))Memory::Scan(client->Name(), Offsets::CPortalLeaderboardManager_Get); + Client::GetLeaderboard = (decltype(Client::GetLeaderboard))Memory::Scan(client->Name(), Offsets::CPortalLeaderboardManager_GetLeaderboard); + if (!GetPortalLeaderboardManager || !Client::GetLeaderboard) { + console->DevWarning("Failed to initialize challenge leaderboard preload\n"); + } } g_CalcViewModelLagHook.SetFunc(Client::CalcViewModelLag); diff --git a/src/Offsets/Portal 2 10090.hpp b/src/Offsets/Portal 2 10090.hpp index 58c7367b1..70304f00f 100644 --- a/src/Offsets/Portal 2 10090.hpp +++ b/src/Offsets/Portal 2 10090.hpp @@ -425,6 +425,10 @@ SIGSCAN_DEFAULT(GetNumChapters, "55 8B EC 80 7D 08 00 57 74 0C", "55 89 E5 56 80 7D") SIGSCAN_DEFAULT(CPortalLeaderboardPanel_OnThink, "55 8B EC A1 ? ? ? ? 81 EC ? ? ? ? 53 56 32 DB", "55 89 E5 57 56 53 81 EC ? ? ? ? 65 A1 ? ? ? ? 89 45 E4 31 C0 A1 ? ? ? ? 8B 5D 08 8B 70 30") +SIGSCAN_DEFAULT(CPortalLeaderboardManager_Get, "B8 ? ? ? ? C3 CC CC CC CC CC CC CC CC CC CC 8B C1 8B 0D", + "B8 ? ? ? ? C3 8D B4 26 ? ? ? ? 8D 76 ? 57 56 53 8B 7C 24 ? 8B 4F") +SIGSCAN_DEFAULT(CPortalLeaderboardManager_GetLeaderboard, "55 8B EC 51 A1 ? ? ? ? 53 8B D9", + "55 89 E5 57 56 53 83 EC ? A1 ? ? ? ? 8B 5D ? 85 C0 74") SIGSCAN_DEFAULT(OnEvent, "55 8B EC 57 8B F9 8B 4D 08 E8", "55 89 E5 57 56 53 83 EC 1C 8B 45 0C 8B 7D 08 89 04 24 E8 ? ? ? ? C7 04 24") SIGSCAN_DEFAULT(OnCommand, "55 8B EC 56 57 8B 7D 08 57 68 ? ? ? ? 8B F1 E8 ? ? ? ? 83 C4 08 85 C0 0F 84", diff --git a/src/Utils/Memory.cpp b/src/Utils/Memory.cpp index 0c8d9626b..cb49d10ed 100644 --- a/src/Utils/Memory.cpp +++ b/src/Utils/Memory.cpp @@ -297,7 +297,7 @@ bool Memory::Patch::Execute(uintptr_t location, unsigned char *bytes, size_t siz return true; } bool Memory::Patch::Restore() { - if (!this || !this->location || !this->original) { + if (!this->location || !this->original) { return false; } if (!this->isPatched) return true; // already restored