| 156 | constexpr const char* kIPCChannel = "ipc"; |
| 157 | |
| 158 | bool Load(const std::string& steamclientPath) |
| 159 | { |
| 160 | g_registry.Clear(); |
| 161 | |
| 162 | RemoteToml::Result r = RemoteToml::Fetch({ |
| 163 | kIPCChannel, |
| 164 | "steamclient", |
| 165 | steamclientPath, |
| 166 | }); |
| 167 | |
| 168 | if (!r.ok) { |
| 169 | ShowMissingPopup(r.sha256.empty() ? "(hash failed)" : r.sha256); |
| 170 | return false; |
| 171 | } |
| 172 | |
| 173 | toml::table root; |
| 174 | try { |
| 175 | root = toml::parse(r.body); |
| 176 | } catch (const toml::parse_error& e) { |
| 177 | LOG_WARN("IPCLoader: TOML parse error: {}", e.description()); |
| 178 | ShowMissingPopup(r.sha256); |
| 179 | return false; |
| 180 | } |
| 181 | |
| 182 | for (auto& [key, val] : root) { |
| 183 | if (!val.is_table()) continue; |
| 184 | Interface iface; |
| 185 | if (!ParseInterfaceTable(key.str(), *val.as_table(), iface)) continue; |
| 186 | |
| 187 | g_registry.Add(std::move(iface)); |
| 188 | } |
| 189 | |
| 190 | LOG_INFO("IPCLoader: loaded {} methods across {} interfaces ({})", |
| 191 | MethodCount(), InterfaceCount(), |
| 192 | r.fromCache ? "cache fallback" : "remote"); |
| 193 | return true; |
| 194 | } |
| 195 | |
| 196 | const Method* Find(EIPCInterface interfaceID, uint32_t funcHash) |
| 197 | { |
nothing calls this directly
no test coverage detected