| 672 | } |
| 673 | |
| 674 | static bool BuildInject(AppId_t appid) |
| 675 | { |
| 676 | if (!g_HaveSelfCached) return false; |
| 677 | |
| 678 | CMsgClientPersonaState msg; |
| 679 | if (!msg.ParseFromArray(g_SelfBody, g_cbSelfBody)) return false; |
| 680 | |
| 681 | // Find our entry (a self-push always contains it). |
| 682 | CMsgClientPersonaState::Friend* entry = nullptr; |
| 683 | for (int i = 0; i < msg.friends_size(); ++i) { |
| 684 | auto* f = msg.mutable_friends(i); |
| 685 | if (f->has_friendid() && f->friendid() == g_LocalSteamId) { |
| 686 | entry = f; |
| 687 | break; |
| 688 | } |
| 689 | } |
| 690 | if (!entry) return false; |
| 691 | |
| 692 | ApplyGameFields(msg, entry, appid); |
| 693 | |
| 694 | uint32 hdrSize = g_cbSelfHdr; |
| 695 | uint32 bodySize = static_cast<uint32>(msg.ByteSizeLong()); |
| 696 | uint32 total = sizeof(MsgHdr) + hdrSize + bodySize; |
| 697 | if (total > sizeof(g_InjectPkt) || bodySize > kMaxBodySize) { |
| 698 | LOG_RICHPRESENCE_WARN("Inject packet too large ({} bytes)", total); |
| 699 | return false; |
| 700 | } |
| 701 | |
| 702 | auto* mhdr = reinterpret_cast<MsgHdr*>(g_InjectPkt); |
| 703 | mhdr->eMsg = static_cast<EMsg>( |
| 704 | static_cast<uint32>(k_EMsgClientPersonaState) | kMsgHdrProtoFlag); |
| 705 | mhdr->headerLength = hdrSize; |
| 706 | memcpy(g_InjectPkt + sizeof(MsgHdr), g_SelfHdr, hdrSize); |
| 707 | if (!msg.SerializeToArray(g_InjectPkt + sizeof(MsgHdr) + hdrSize, bodySize)) |
| 708 | return false; |
| 709 | |
| 710 | g_cbInjectPkt = total; |
| 711 | LOG_RICHPRESENCE_INFO("Built inject for appid {} ({} bytes)", appid, total); |
| 712 | return true; |
| 713 | } |
| 714 | |
| 715 | // Decode outbound CMsgClientRichPresenceUpload into per-AppId KVs |
| 716 | // and stage a fresh PersonaState inject. |
no test coverage detected