mirror of
https://git.citron-emu.org/citron/emulator
synced 2026-02-02 07:33:36 +00:00
fix: Multiplayer network fixes and airplane mode
- Auto-select network interface for direct connect/host room - Always recreate ENet client on join for fresh bindings - Add airplane mode toggle (Desktop & Android) - Fix JWT verification with empty verify_uid - Improve content-type handling for JWT endpoints Signed-off-by: Zephyron <zephyron@citron-emu.org>
This commit is contained in:
@@ -52,6 +52,7 @@ enum class ErrorModule : u32 {
|
||||
Util = 33,
|
||||
TIPC = 35,
|
||||
ANIF = 37,
|
||||
Module38 = 38, // Unknown/Undefined module - stubbed for multiplayer compatibility
|
||||
CRT = 39,
|
||||
ETHC = 100,
|
||||
I2C = 101,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Citron Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <array>
|
||||
@@ -65,16 +66,30 @@ enum class FatalType : u32 {
|
||||
|
||||
static void GenerateErrorReport(Core::System& system, Result error_code, const FatalInfo& info) {
|
||||
const auto title_id = system.GetApplicationProcessProgramID();
|
||||
const auto module = static_cast<u32>(error_code.GetModule());
|
||||
const auto description = static_cast<u32>(error_code.GetDescription());
|
||||
|
||||
// Check if this is module 38 (undefined/unknown module)
|
||||
std::string module_note;
|
||||
if (module == 38) {
|
||||
module_note = fmt::format(
|
||||
"\n⚠️ WARNING: Error module 38 is undefined/unknown!\n"
|
||||
"This error may be game-generated or from an unimplemented service.\n"
|
||||
"Error code: 2038-{:04d} (0x{:08X})\n"
|
||||
"If you're experiencing multiplayer issues, this may be a stubbing issue.\n\n",
|
||||
description, error_code.raw);
|
||||
}
|
||||
|
||||
std::string crash_report = fmt::format(
|
||||
"Citron {}-{} crash report\n"
|
||||
"Title ID: {:016x}\n"
|
||||
"Result: 0x{:X} ({:04}-{:04d})\n"
|
||||
"Set flags: 0x{:16X}\n"
|
||||
"Program entry point: 0x{:16X}\n"
|
||||
"{}"
|
||||
"\n",
|
||||
Common::g_scm_branch, Common::g_scm_desc, title_id, error_code.raw,
|
||||
2000 + static_cast<u32>(error_code.GetModule()),
|
||||
static_cast<u32>(error_code.GetDescription()), info.set_flags, info.program_entry_point);
|
||||
2000 + module, description, info.set_flags, info.program_entry_point, module_note);
|
||||
if (info.backtrace_size != 0x0) {
|
||||
crash_report += "Registers:\n";
|
||||
for (size_t i = 0; i < info.registers.size(); i++) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
@@ -24,4 +25,13 @@ constexpr Result ResultLocalCommunicationIdNotFound{ErrorModule::LDN, 97};
|
||||
constexpr Result ResultLocalCommunicationVersionTooLow{ErrorModule::LDN, 113};
|
||||
constexpr Result ResultLocalCommunicationVersionTooHigh{ErrorModule::LDN, 114};
|
||||
|
||||
// Module 38 error codes - Unknown/undefined module
|
||||
// These are stubbed to prevent crashes during multiplayer
|
||||
// Error code format: 2038-XXXX where XXXX is the description
|
||||
constexpr Result ResultModule38Error2618{ErrorModule::Module38, 2618}; // Reported during multiplayer
|
||||
constexpr Result ResultModule38Generic{ErrorModule::Module38, 0}; // Generic module 38 error
|
||||
constexpr Result ResultModule38NetworkError{ErrorModule::Module38, 100}; // Network-related
|
||||
constexpr Result ResultModule38ConnectionFailed{ErrorModule::Module38, 200}; // Connection failure
|
||||
constexpr Result ResultModule38Timeout{ErrorModule::Module38, 300}; // Operation timeout
|
||||
|
||||
} // namespace Service::LDN
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Citron Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <algorithm>
|
||||
@@ -187,6 +188,11 @@ std::vector<NetworkInterface> GetAvailableNetworkInterfaces() {
|
||||
#endif
|
||||
|
||||
std::optional<NetworkInterface> GetSelectedNetworkInterface() {
|
||||
// If airplane mode is enabled, return no interface (similar to Switch's airplane mode)
|
||||
if (Settings::values.airplane_mode.GetValue()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const auto& selected_network_interface = Settings::values.network_interface.GetValue();
|
||||
const auto network_interfaces = Network::GetAvailableNetworkInterfaces();
|
||||
if (network_interfaces.empty()) {
|
||||
|
||||
Reference in New Issue
Block a user