|
1 | 1 | #include "NetworkGhostPlayer.hpp" |
2 | 2 |
|
3 | 3 | #include "DemoGhostPlayer.hpp" |
4 | | -#include "GhostLeaderboard.hpp" |
5 | 4 | #include "Event.hpp" |
6 | | -#include "Scheduler.hpp" |
7 | 5 | #include "Features/Hud/Toasts.hpp" |
8 | 6 | #include "Features/NetMessage.hpp" |
9 | 7 | #include "Features/Session.hpp" |
10 | 8 | #include "Features/Speedrun/SpeedrunTimer.hpp" |
11 | 9 | #include "GhostEntity.hpp" |
| 10 | +#include "GhostLeaderboard.hpp" |
12 | 11 | #include "Modules/Client.hpp" |
13 | 12 | #include "Modules/Console.hpp" |
14 | 13 | #include "Modules/Engine.hpp" |
| 14 | +#include "Modules/Scheme.hpp" |
15 | 15 | #include "Modules/Server.hpp" |
| 16 | +#include "Modules/SteamAPI.hpp" |
16 | 17 | #include "Modules/Surface.hpp" |
17 | | -#include "Modules/Scheme.hpp" |
| 18 | +#include "Scheduler.hpp" |
18 | 19 |
|
19 | 20 | #include <chrono> |
20 | 21 | #include <functional> |
@@ -532,20 +533,54 @@ void NetworkManager::RunNetwork() { |
532 | 533 | } |
533 | 534 |
|
534 | 535 | void NetworkManager::SendPlayerData() { |
535 | | - sf::Packet packet; |
536 | | - packet << HEADER::UPDATE << this->ID; |
537 | | - auto player = client->GetPlayer(GET_SLOT() + 1); |
538 | | - if (player) { |
539 | | - bool grounded = player->ground_entity(); |
540 | | - packet << DataGhost{client->GetAbsOrigin(player), engine->GetAngles(engine->IsOrange() ? 0 : GET_SLOT()), client->GetViewOffset(player).z, grounded}; |
541 | | - } else { |
542 | | - packet << DataGhost::Invalid(); |
| 536 | + { |
| 537 | + sf::Packet packet; |
| 538 | + packet << HEADER::UPDATE << this->ID; |
| 539 | + auto player = client->GetPlayer(GET_SLOT() + 1); |
| 540 | + if (player) { |
| 541 | + bool grounded = player->ground_entity(); |
| 542 | + packet << DataGhost{client->GetAbsOrigin(player), engine->GetAngles(engine->IsOrange() ? 0 : GET_SLOT()), client->GetViewOffset(player).z, grounded}; |
| 543 | + } else { |
| 544 | + packet << DataGhost::Invalid(); |
| 545 | + } |
| 546 | + |
| 547 | + if (!ghost_TCP_only.GetBool()) { |
| 548 | + this->udpSocket.send(packet, this->serverIP, this->serverPort); |
| 549 | + } else { |
| 550 | + this->tcpSocket.send(packet); |
| 551 | + } |
543 | 552 | } |
544 | 553 |
|
545 | | - if (!ghost_TCP_only.GetBool()) { |
546 | | - this->udpSocket.send(packet, this->serverIP, this->serverPort); |
547 | | - } else { |
548 | | - this->tcpSocket.send(packet); |
| 554 | + // voice. |
| 555 | + { |
| 556 | + // read local microphone input. |
| 557 | + uint32_t nBytesAvailable = 0; |
| 558 | + EVoiceResult res = steam->SteamUser()->GetAvailableVoice(&nBytesAvailable, NULL, 0); |
| 559 | + |
| 560 | + if (res == k_EVoiceResultOK && nBytesAvailable > 0) { |
| 561 | + uint32_t nBytesWritten = 0; |
| 562 | + MsgVoiceChatData_t msg; |
| 563 | + |
| 564 | + // don't send more than 1 KB at a time. |
| 565 | + uint8_t buffer[1024 + sizeof(msg)]; |
| 566 | + |
| 567 | + res = steam->SteamUser()->GetVoice(true, buffer + sizeof(msg), 1024, &nBytesWritten, false, NULL, 0, NULL, 0); |
| 568 | + |
| 569 | + if (res == k_EVoiceResultOK && nBytesWritten > 0) { |
| 570 | + msg.SetDataLength(nBytesWritten); |
| 571 | + memcpy(buffer, &msg, sizeof(msg)); |
| 572 | + |
| 573 | + sf::Packet packet; |
| 574 | + packet << HEADER::VOICE << this->ID; |
| 575 | + packet.append(buffer, sizeof(msg) + nBytesWritten); |
| 576 | + |
| 577 | + if (!ghost_TCP_only.GetBool()) { |
| 578 | + this->udpSocket.send(packet, this->serverIP, this->serverPort); |
| 579 | + } else { |
| 580 | + this->tcpSocket.send(packet); |
| 581 | + } |
| 582 | + } |
| 583 | + } |
549 | 584 | } |
550 | 585 | } |
551 | 586 |
|
@@ -705,6 +740,9 @@ void NetworkManager::ReceiveUDPUpdates(std::vector<sf::Packet> &buffer) { |
705 | 740 | } while (status == sf::Socket::Done); |
706 | 741 | } |
707 | 742 |
|
| 743 | +uint8_t g_pbUncompressedVoice[11025 * 2]; |
| 744 | +uint32_t g_numUncompressedBytes; |
| 745 | + |
708 | 746 | void NetworkManager::Treat(sf::Packet &packet, bool udp) { |
709 | 747 | HEADER header; |
710 | 748 | sf::Uint32 ID; |
@@ -999,6 +1037,27 @@ void NetworkManager::Treat(sf::Packet &packet, bool udp) { |
999 | 1037 | } |
1000 | 1038 | break; |
1001 | 1039 | } |
| 1040 | + case HEADER::VOICE: { |
| 1041 | + console->Warning("voice packet.\n"); |
| 1042 | + |
| 1043 | + const auto pMessage = (uintptr_t)(packet.getData()) + 5; |
| 1044 | + |
| 1045 | + const MsgVoiceChatData_t *pMsgVoiceData = (const MsgVoiceChatData_t *)pMessage; |
| 1046 | + |
| 1047 | + uint8_t pbUncompressedVoice[11025 * 2]; |
| 1048 | + uint32_t numUncompressedBytes = 0; |
| 1049 | + const uint8_t *pVoiceData = (const uint8_t *)pMessage; |
| 1050 | + pVoiceData += sizeof(MsgVoiceChatData_t); |
| 1051 | + |
| 1052 | + EVoiceResult res = steam->SteamUser()->DecompressVoice(pVoiceData, pMsgVoiceData->GetDataLength(), pbUncompressedVoice, sizeof(pbUncompressedVoice), &numUncompressedBytes, 11025); |
| 1053 | + |
| 1054 | + if (res == k_EVoiceResultOK && numUncompressedBytes > 0) { |
| 1055 | + memcpy(g_pbUncompressedVoice, pbUncompressedVoice, sizeof(pbUncompressedVoice)); |
| 1056 | + g_numUncompressedBytes = numUncompressedBytes; |
| 1057 | + } |
| 1058 | + |
| 1059 | + break; |
| 1060 | + } |
1002 | 1061 | default: |
1003 | 1062 | break; |
1004 | 1063 | } |
@@ -1322,6 +1381,9 @@ ON_EVENT(FRAME) { |
1322 | 1381 | } |
1323 | 1382 | } |
1324 | 1383 |
|
| 1384 | +Command ghost_voice_on("+ghost_voice", +[](const CCommand &args) { steam->SteamUser()->StartVoiceRecording(); }, "+ghost_voice - push to talk in voice chat\n"); |
| 1385 | +Command ghost_voice_off("-ghost_voice", +[](const CCommand &args) { steam->SteamUser()->StopVoiceRecording(); }, "-ghost_voice - push to talk in voice chat\n"); |
| 1386 | + |
1325 | 1387 | CON_COMMAND(ghost_chat, "ghost_chat - open the chat HUD for messaging other players\n") { |
1326 | 1388 | if (g_chatType == 0 && networkManager.isConnected) { |
1327 | 1389 | g_wasChatType = 0; |
|
0 commit comments