Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba470b9434 | ||
|
|
fb208396fd | ||
|
|
907e9a4484 |
No files matched your search
@@ -512,10 +512,11 @@ protected:
|
||||
|
||||
class IManagerForApplication final : public ServiceFramework<IManagerForApplication> {
|
||||
public:
|
||||
explicit IManagerForApplication(Core::System& system_, Common::UUID user_id_)
|
||||
explicit IManagerForApplication(Core::System& system_,
|
||||
const std::shared_ptr<ProfileManager>& profile_manager_)
|
||||
: ServiceFramework{system_, "IManagerForApplication"},
|
||||
ensure_token_id{std::make_shared<EnsureTokenIdCacheAsyncInterface>(system)},
|
||||
user_id{user_id_} {
|
||||
profile_manager{profile_manager_} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IManagerForApplication::CheckAvailability, "CheckAvailability"},
|
||||
@@ -545,7 +546,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushRaw<u64>(user_id.Hash());
|
||||
rb.PushRaw<u64>(profile_manager->GetLastOpenedUser().Hash());
|
||||
}
|
||||
|
||||
void EnsureIdTokenCacheAsync(Kernel::HLERequestContext& ctx) {
|
||||
@@ -575,17 +576,20 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushRaw<u64>(user_id.Hash());
|
||||
rb.PushRaw<u64>(profile_manager->GetLastOpenedUser().Hash());
|
||||
}
|
||||
|
||||
void StoreOpenContext(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
|
||||
profile_manager->StoreOpenedUsers();
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
std::shared_ptr<EnsureTokenIdCacheAsyncInterface> ensure_token_id{};
|
||||
Common::UUID user_id{};
|
||||
std::shared_ptr<ProfileManager> profile_manager;
|
||||
};
|
||||
|
||||
// 6.0.0+
|
||||
@@ -790,7 +794,7 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushIpcInterface<IManagerForApplication>(system, profile_manager->GetLastOpenedUser());
|
||||
rb.PushIpcInterface<IManagerForApplication>(system, profile_manager);
|
||||
}
|
||||
|
||||
void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx) {
|
||||
@@ -854,17 +858,14 @@ void Module::Interface::LoadOpenContext(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
// This is similar to GetBaasAccountManagerForApplication
|
||||
// This command is used concurrently with ListOpenContextStoredUsers
|
||||
// TODO: Find the differences between this and GetBaasAccountManagerForApplication
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushIpcInterface<IManagerForApplication>(system, profile_manager->GetLastOpenedUser());
|
||||
}
|
||||
|
||||
void Module::Interface::ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
|
||||
// TODO(ogniK): Handle open contexts
|
||||
ctx.WriteBuffer(profile_manager->GetOpenUsers());
|
||||
ctx.WriteBuffer(profile_manager->GetStoredOpenedUsers());
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
@@ -261,6 +261,31 @@ UUID ProfileManager::GetLastOpenedUser() const {
|
||||
return last_opened_user;
|
||||
}
|
||||
|
||||
/// Gets the list of stored opened users.
|
||||
UserIDArray ProfileManager::GetStoredOpenedUsers() const {
|
||||
UserIDArray output{};
|
||||
std::ranges::transform(stored_opened_profiles, output.begin(), [](const ProfileInfo& p) {
|
||||
if (p.is_open)
|
||||
return p.user_uuid;
|
||||
return Common::InvalidUUID;
|
||||
});
|
||||
std::stable_partition(output.begin(), output.end(),
|
||||
[](const UUID& uuid) { return uuid.IsValid(); });
|
||||
return output;
|
||||
}
|
||||
|
||||
/// Captures the opened users, which can be queried across process launches with
|
||||
/// ListOpenContextStoredUsers.
|
||||
void ProfileManager::StoreOpenedUsers() {
|
||||
size_t profile_index{};
|
||||
stored_opened_profiles = {};
|
||||
std::for_each(profiles.begin(), profiles.end(), [&](const auto& profile) {
|
||||
if (profile.is_open) {
|
||||
stored_opened_profiles[profile_index++] = profile;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Return the users profile base and the unknown arbitary data.
|
||||
bool ProfileManager::GetProfileBaseAndData(std::optional<std::size_t> index, ProfileBase& profile,
|
||||
UserData& data) const {
|
||||
|
||||
@@ -86,6 +86,8 @@ public:
|
||||
UserIDArray GetOpenUsers() const;
|
||||
UserIDArray GetAllUsers() const;
|
||||
Common::UUID GetLastOpenedUser() const;
|
||||
UserIDArray GetStoredOpenedUsers() const;
|
||||
void StoreOpenedUsers();
|
||||
|
||||
bool CanSystemRegisterUser() const;
|
||||
|
||||
@@ -101,6 +103,7 @@ private:
|
||||
bool RemoveProfileAtIndex(std::size_t index);
|
||||
|
||||
std::array<ProfileInfo, MAX_USERS> profiles{};
|
||||
std::array<ProfileInfo, MAX_USERS> stored_opened_profiles{};
|
||||
std::size_t user_count{};
|
||||
Common::UUID last_opened_user{};
|
||||
};
|
||||
|
||||
@@ -487,7 +487,7 @@ void LANDiscovery::ReceivePacket(const Network::LDNPacket& packet) {
|
||||
std::scoped_lock lock{packet_mutex};
|
||||
switch (packet.type) {
|
||||
case Network::LDNPacketType::Scan: {
|
||||
LOG_INFO(Frontend, "Scan packet received!");
|
||||
LOG_DEBUG(Frontend, "Scan packet received!");
|
||||
if (state == State::AccessPointCreated) {
|
||||
// Reply to the sender
|
||||
SendPacket(Network::LDNPacketType::ScanResp, network_info, packet.local_ip);
|
||||
@@ -495,7 +495,7 @@ void LANDiscovery::ReceivePacket(const Network::LDNPacket& packet) {
|
||||
break;
|
||||
}
|
||||
case Network::LDNPacketType::ScanResp: {
|
||||
LOG_INFO(Frontend, "ScanResp packet received!");
|
||||
LOG_DEBUG(Frontend, "ScanResp packet received!");
|
||||
|
||||
NetworkInfo info{};
|
||||
std::memcpy(&info, packet.data.data(), sizeof(NetworkInfo));
|
||||
@@ -611,13 +611,6 @@ MacAddress LANDiscovery::GetFakeMac() const {
|
||||
|
||||
Result LANDiscovery::GetNodeInfo(NodeInfo& node, const UserConfig& userConfig,
|
||||
u16 localCommunicationVersion) {
|
||||
const auto network_interface = Network::GetSelectedNetworkInterface();
|
||||
|
||||
if (!network_interface) {
|
||||
LOG_ERROR(Service_LDN, "No network interface available");
|
||||
return ResultNoIpAddress;
|
||||
}
|
||||
|
||||
node.mac_address = GetFakeMac();
|
||||
node.is_connected = 1;
|
||||
std::memcpy(node.user_name.data(), userConfig.user_name.data(), UserNameBytesMax + 1);
|
||||
|
||||
@@ -150,7 +150,7 @@ public:
|
||||
}
|
||||
|
||||
~IUserLocalCommunicationService() {
|
||||
if (is_initialized) {
|
||||
if (is_network_available) {
|
||||
if (auto room_member = room_network.GetRoomMember().lock()) {
|
||||
room_member->Unbind(ldn_packet_received);
|
||||
}
|
||||
@@ -193,7 +193,7 @@ public:
|
||||
NetworkInfo network_info{};
|
||||
const auto rc = lan_discovery.GetNetworkInfo(network_info);
|
||||
if (rc.IsError()) {
|
||||
LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw);
|
||||
LOG_DEBUG(Service_LDN, "NetworkInfo is not valid {}", rc.raw);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(rc);
|
||||
return;
|
||||
@@ -205,6 +205,14 @@ public:
|
||||
}
|
||||
|
||||
void GetIpv4Address(Kernel::HLERequestContext& ctx) {
|
||||
if (!is_network_available) {
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushRaw(Ipv4Address{127, 0, 0, 1});
|
||||
rb.PushRaw(Ipv4Address{255, 255, 255, 0});
|
||||
return;
|
||||
}
|
||||
|
||||
const auto network_interface = Network::GetSelectedNetworkInterface();
|
||||
|
||||
if (!network_interface) {
|
||||
@@ -342,6 +350,13 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_network_available) {
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push(0);
|
||||
return;
|
||||
}
|
||||
|
||||
u16 count = 0;
|
||||
std::vector<NetworkInfo> network_infos(network_info_size);
|
||||
Result rc = lan_discovery.Scan(network_infos, count, scan_filter);
|
||||
@@ -488,18 +503,18 @@ public:
|
||||
}
|
||||
|
||||
void Initialize(Kernel::HLERequestContext& ctx) {
|
||||
const auto rc = InitializeImpl(ctx);
|
||||
if (rc.IsError()) {
|
||||
LOG_ERROR(Service_LDN, "Network isn't initialized, rc={}", rc.raw);
|
||||
}
|
||||
InitializeImpl(ctx);
|
||||
|
||||
// Initialize always returns success
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(rc);
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Finalize(Kernel::HLERequestContext& ctx) {
|
||||
if (auto room_member = room_network.GetRoomMember().lock()) {
|
||||
room_member->Unbind(ldn_packet_received);
|
||||
if (is_network_available) {
|
||||
if (auto room_member = room_network.GetRoomMember().lock()) {
|
||||
room_member->Unbind(ldn_packet_received);
|
||||
}
|
||||
}
|
||||
|
||||
is_initialized = false;
|
||||
@@ -519,22 +534,25 @@ public:
|
||||
}
|
||||
|
||||
Result InitializeImpl(Kernel::HLERequestContext& ctx) {
|
||||
lan_discovery.Initialize([&]() { OnEventFired(); });
|
||||
is_initialized = true;
|
||||
is_network_available = false;
|
||||
|
||||
const auto network_interface = Network::GetSelectedNetworkInterface();
|
||||
if (!network_interface) {
|
||||
LOG_ERROR(Service_LDN, "No network interface is set");
|
||||
return ResultAirplaneModeEnabled;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
if (auto room_member = room_network.GetRoomMember().lock()) {
|
||||
ldn_packet_received = room_member->BindOnLdnPacketReceived(
|
||||
[this](const Network::LDNPacket& packet) { OnLDNPacketReceived(packet); });
|
||||
is_network_available = true;
|
||||
} else {
|
||||
LOG_ERROR(Service_LDN, "Couldn't bind callback!");
|
||||
return ResultAirplaneModeEnabled;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
lan_discovery.Initialize([&]() { OnEventFired(); });
|
||||
is_initialized = true;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
@@ -547,6 +565,7 @@ public:
|
||||
Network::RoomMember::CallbackHandle<Network::LDNPacket> ldn_packet_received;
|
||||
|
||||
bool is_initialized{};
|
||||
bool is_network_available{};
|
||||
};
|
||||
|
||||
class LDNS final : public ServiceFramework<LDNS> {
|
||||
|
||||
@@ -149,9 +149,10 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext&
|
||||
return port_result.Code();
|
||||
}
|
||||
auto& port = port_result.Unwrap();
|
||||
SCOPE_EXIT({ port->GetClientPort().Close(); });
|
||||
|
||||
kernel.RegisterServerObject(&port->GetServerPort());
|
||||
SCOPE_EXIT({
|
||||
port->GetClientPort().Close();
|
||||
port->GetServerPort().Close();
|
||||
});
|
||||
|
||||
// Create a new session.
|
||||
Kernel::KClientSession* session{};
|
||||
|
||||
@@ -28,23 +28,36 @@ void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) {
|
||||
void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service, "called");
|
||||
|
||||
auto& process = *ctx.GetThread().GetOwnerProcess();
|
||||
auto& parent_session = *ctx.Session()->GetParent();
|
||||
auto& parent_port = parent_session.GetParent()->GetParent()->GetClientPort();
|
||||
auto& session_manager = parent_session.GetServerSession().GetSessionRequestManager();
|
||||
auto& session_handler = session_manager->SessionHandler();
|
||||
|
||||
// Create a session.
|
||||
Kernel::KClientSession* session{};
|
||||
const Result result = parent_port.CreateSession(std::addressof(session), session_manager);
|
||||
if (result.IsError()) {
|
||||
LOG_CRITICAL(Service, "CreateSession failed with error 0x{:08X}", result.raw);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(result);
|
||||
}
|
||||
// FIXME: this is duplicated from the SVC, it should just call it instead
|
||||
// once this is a proper process
|
||||
|
||||
// Reserve a new session from the process resource limit.
|
||||
Kernel::KScopedResourceReservation session_reservation(&process,
|
||||
Kernel::LimitableResource::Sessions);
|
||||
ASSERT(session_reservation.Succeeded());
|
||||
|
||||
// Create the sessionn.
|
||||
Kernel::KSession* session = Kernel::KSession::Create(system.Kernel());
|
||||
ASSERT(session != nullptr);
|
||||
|
||||
// Initialize the session.
|
||||
session->Initialize(nullptr, parent_session.GetName(), session_manager);
|
||||
|
||||
// Commit the session reservation.
|
||||
session_reservation.Commit();
|
||||
|
||||
// Register the session.
|
||||
session_handler.ClientConnected(&session->GetServerSession());
|
||||
|
||||
// We succeeded.
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushMoveObjects(session);
|
||||
rb.PushMoveObjects(session->GetClientSession());
|
||||
}
|
||||
|
||||
void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
@@ -199,7 +199,7 @@ std::optional<NetworkInterface> GetSelectedNetworkInterface() {
|
||||
});
|
||||
|
||||
if (res == network_interfaces.end()) {
|
||||
LOG_ERROR(Network, "Couldn't find selected interface \"{}\"", selected_network_interface);
|
||||
LOG_DEBUG(Network, "Couldn't find selected interface \"{}\"", selected_network_interface);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
||||
@@ -912,7 +912,6 @@ void GMainWindow::InitializeWidgets() {
|
||||
statusBar()->addPermanentWidget(label);
|
||||
}
|
||||
|
||||
// TODO (flTobi): Add the widget when multiplayer is fully implemented
|
||||
statusBar()->addPermanentWidget(multiplayer_state->GetStatusText(), 0);
|
||||
statusBar()->addPermanentWidget(multiplayer_state->GetStatusIcon(), 0);
|
||||
|
||||
|
||||
Reference in new issue
Block a user