core, yuzu: Address first part of review comments

This commit is contained in:
FearlessTobi 2022-08-01 22:47:39 +02:00
parent a5cd639cb6
commit 6d41088153
9 changed files with 70 additions and 71 deletions

View File

@ -31,7 +31,7 @@ AnnounceMultiplayerSession::AnnounceMultiplayerSession(Network::RoomNetwork& roo
} }
WebService::WebResult AnnounceMultiplayerSession::Register() { WebService::WebResult AnnounceMultiplayerSession::Register() {
std::shared_ptr<Network::Room> room = room_network.GetRoom().lock(); auto room = room_network.GetRoom().lock();
if (!room) { if (!room) {
return WebService::WebResult{WebService::WebResult::Code::LibError, return WebService::WebResult{WebService::WebResult::Code::LibError,
"Network is not initialized", ""}; "Network is not initialized", ""};
@ -102,7 +102,7 @@ void AnnounceMultiplayerSession::UpdateBackendData(std::shared_ptr<Network::Room
void AnnounceMultiplayerSession::AnnounceMultiplayerLoop() { void AnnounceMultiplayerSession::AnnounceMultiplayerLoop() {
// Invokes all current bound error callbacks. // Invokes all current bound error callbacks.
const auto ErrorCallback = [this](WebService::WebResult result) { const auto ErrorCallback = [this](WebService::WebResult result) {
std::lock_guard<std::mutex> lock(callback_mutex); std::lock_guard lock(callback_mutex);
for (auto callback : error_callbacks) { for (auto callback : error_callbacks) {
(*callback)(result); (*callback)(result);
} }
@ -120,7 +120,7 @@ void AnnounceMultiplayerSession::AnnounceMultiplayerLoop() {
std::future<WebService::WebResult> future; std::future<WebService::WebResult> future;
while (!shutdown_event.WaitUntil(update_time)) { while (!shutdown_event.WaitUntil(update_time)) {
update_time += announce_time_interval; update_time += announce_time_interval;
std::shared_ptr<Network::Room> room = room_network.GetRoom().lock(); auto room = room_network.GetRoom().lock();
if (!room) { if (!room) {
break; break;
} }

View File

@ -381,6 +381,7 @@ void IGeneralService::GetCurrentIpAddress(Kernel::HLERequestContext& ctx) {
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
rb.PushRaw(*ipv4); rb.PushRaw(*ipv4);
} }
void IGeneralService::CreateTemporaryNetworkProfile(Kernel::HLERequestContext& ctx) { void IGeneralService::CreateTemporaryNetworkProfile(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_NIFM, "called"); LOG_DEBUG(Service_NIFM, "called");

View File

@ -352,8 +352,8 @@ std::optional<IPv4Address> GetHostIPv4Address() {
return {}; return {};
} }
char ip_addr[16] = {}; std::array<char, 16> ip_addr = {};
ASSERT(inet_ntop(AF_INET, &interface->ip_address, ip_addr, sizeof(ip_addr)) != nullptr); ASSERT(inet_ntop(AF_INET, &interface->ip_address, ip_addr.data(), sizeof(ip_addr)) != nullptr);
return TranslateIPv4(interface->ip_address); return TranslateIPv4(interface->ip_address);
} }
@ -402,9 +402,9 @@ Socket::Socket(Socket&& rhs) noexcept {
} }
template <typename T> template <typename T>
Errno Socket::SetSockOpt(SOCKET _fd, int option, T value) { Errno Socket::SetSockOpt(SOCKET fd_, int option, T value) {
const int result = const int result =
setsockopt(_fd, SOL_SOCKET, option, reinterpret_cast<const char*>(&value), sizeof(value)); setsockopt(fd_, SOL_SOCKET, option, reinterpret_cast<const char*>(&value), sizeof(value));
if (result != SOCKET_ERROR) { if (result != SOCKET_ERROR) {
return Errno::SUCCESS; return Errno::SUCCESS;
} }

View File

@ -30,19 +30,19 @@ void ProxySocket::HandleProxyPacket(const ProxyPacket& packet) {
closed) { closed) {
return; return;
} }
std::lock_guard<std::mutex> guard(packets_mutex); std::lock_guard guard(packets_mutex);
received_packets.push(packet); received_packets.push(packet);
} }
template <typename T> template <typename T>
Errno ProxySocket::SetSockOpt(SOCKET _fd, int option, T value) { Errno ProxySocket::SetSockOpt(SOCKET fd_, int option, T value) {
socket_options[option] = reinterpret_cast<const char*>(&value); socket_options[option] = reinterpret_cast<const char*>(&value);
return Errno::SUCCESS; return Errno::SUCCESS;
} }
Errno ProxySocket::Initialize(Domain domain, Type type, Protocol socket_protocol) { Errno ProxySocket::Initialize(Domain domain, Type type, Protocol socket_protocol) {
protocol = socket_protocol; protocol = socket_protocol;
socket_options[0x1008] = reinterpret_cast<const char*>(&type); SetSockOpt(fd, SO_TYPE, type);
return Errno::SUCCESS; return Errno::SUCCESS;
} }
@ -101,7 +101,7 @@ std::pair<s32, Errno> ProxySocket::RecvFrom(int flags, std::vector<u8>& message,
ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max())); ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
{ {
std::lock_guard<std::mutex> guard(packets_mutex); std::lock_guard guard(packets_mutex);
if (received_packets.size() > 0) { if (received_packets.size() > 0) {
return ReceivePacket(flags, message, addr, message.size()); return ReceivePacket(flags, message, addr, message.size());
} }
@ -115,7 +115,7 @@ std::pair<s32, Errno> ProxySocket::RecvFrom(int flags, std::vector<u8>& message,
return {-1, Errno::AGAIN}; return {-1, Errno::AGAIN};
} }
std::lock_guard<std::mutex> guard(packets_mutex); std::lock_guard guard(packets_mutex);
if (received_packets.size() > 0) { if (received_packets.size() > 0) {
return ReceivePacket(flags, message, addr, message.size()); return ReceivePacket(flags, message, addr, message.size());
} }

View File

@ -14,7 +14,7 @@ namespace Network {
class ProxySocket : public SocketBase { class ProxySocket : public SocketBase {
public: public:
ProxySocket(RoomNetwork& room_network_) noexcept; explicit ProxySocket(RoomNetwork& room_network_) noexcept;
~ProxySocket() override; ~ProxySocket() override;
ProxySocket(const ProxySocket&) = delete; ProxySocket(const ProxySocket&) = delete;
@ -82,6 +82,7 @@ public:
bool IsOpened() const override; bool IsOpened() const override;
private:
bool broadcast = false; bool broadcast = false;
bool closed = false; bool closed = false;
u32 send_timeout = 0; u32 send_timeout = 0;

View File

@ -32,7 +32,7 @@ public:
std::unique_ptr<SocketBase> socket; std::unique_ptr<SocketBase> socket;
SockAddrIn sockaddr_in; SockAddrIn sockaddr_in;
}; };
virtual ~SocketBase() {} virtual ~SocketBase() = default;
virtual SocketBase& operator=(const SocketBase&) = delete; virtual SocketBase& operator=(const SocketBase&) = delete;
@ -89,11 +89,7 @@ public:
virtual void HandleProxyPacket(const ProxyPacket& packet) = 0; virtual void HandleProxyPacket(const ProxyPacket& packet) = 0;
#if defined(_WIN32)
SOCKET fd = INVALID_SOCKET; SOCKET fd = INVALID_SOCKET;
#elif YUZU_UNIX
int fd = -1;
#endif
}; };
class Socket : public SocketBase { class Socket : public SocketBase {

View File

@ -44,28 +44,30 @@
#endif #endif
static void PrintHelp(const char* argv0) { static void PrintHelp(const char* argv0) {
std::cout << "Usage: " << argv0 LOG_INFO(Network,
<< " [options] <filename>\n" "Usage: {}"
"--room-name The name of the room\n" " [options] <filename>\n"
"--room-description The room description\n" "--room-name The name of the room\n"
"--port The port used for the room\n" "--room-description The room description\n"
"--max_members The maximum number of players for this room\n" "--port The port used for the room\n"
"--password The password for the room\n" "--max_members The maximum number of players for this room\n"
"--preferred-game The preferred game for this room\n" "--password The password for the room\n"
"--preferred-game-id The preferred game-id for this room\n" "--preferred-game The preferred game for this room\n"
"--username The username used for announce\n" "--preferred-game-id The preferred game-id for this room\n"
"--token The token used for announce\n" "--username The username used for announce\n"
"--web-api-url yuzu Web API url\n" "--token The token used for announce\n"
"--ban-list-file The file for storing the room ban list\n" "--web-api-url yuzu Web API url\n"
"--log-file The file for storing the room log\n" "--ban-list-file The file for storing the room ban list\n"
"--enable-yuzu-mods Allow yuzu Community Moderators to moderate on your room\n" "--log-file The file for storing the room log\n"
"-h, --help Display this help and exit\n" "--enable-yuzu-mods Allow yuzu Community Moderators to moderate on your room\n"
"-v, --version Output version information and exit\n"; "-h, --help Display this help and exit\n"
"-v, --version Output version information and exit\n",
argv0);
} }
static void PrintVersion() { static void PrintVersion() {
std::cout << "yuzu dedicated room " << Common::g_scm_branch << " " << Common::g_scm_desc LOG_INFO(Network, "yuzu dedicated room {} {} Libnetwork: {}", Common::g_scm_branch,
<< " Libnetwork: " << Network::network_version << std::endl; Common::g_scm_desc, Network::network_version);
} }
/// The magic text at the beginning of a yuzu-room ban list file. /// The magic text at the beginning of a yuzu-room ban list file.
@ -76,7 +78,7 @@ static constexpr char token_delimiter{':'};
static std::string UsernameFromDisplayToken(const std::string& display_token) { static std::string UsernameFromDisplayToken(const std::string& display_token) {
std::size_t outlen; std::size_t outlen;
std::array<unsigned char, 512> output; std::array<unsigned char, 512> output{};
mbedtls_base64_decode(output.data(), output.size(), &outlen, mbedtls_base64_decode(output.data(), output.size(), &outlen,
reinterpret_cast<const unsigned char*>(display_token.c_str()), reinterpret_cast<const unsigned char*>(display_token.c_str()),
display_token.length()); display_token.length());
@ -87,7 +89,7 @@ static std::string UsernameFromDisplayToken(const std::string& display_token) {
static std::string TokenFromDisplayToken(const std::string& display_token) { static std::string TokenFromDisplayToken(const std::string& display_token) {
std::size_t outlen; std::size_t outlen;
std::array<unsigned char, 512> output; std::array<unsigned char, 512> output{};
mbedtls_base64_decode(output.data(), output.size(), &outlen, mbedtls_base64_decode(output.data(), output.size(), &outlen,
reinterpret_cast<const unsigned char*>(display_token.c_str()), reinterpret_cast<const unsigned char*>(display_token.c_str()),
display_token.length()); display_token.length());
@ -99,13 +101,13 @@ static Network::Room::BanList LoadBanList(const std::string& path) {
std::ifstream file; std::ifstream file;
Common::FS::OpenFileStream(file, path, std::ios_base::in); Common::FS::OpenFileStream(file, path, std::ios_base::in);
if (!file || file.eof()) { if (!file || file.eof()) {
std::cout << "Could not open ban list!\n\n"; LOG_ERROR(Network, "Could not open ban list!");
return {}; return {};
} }
std::string magic; std::string magic;
std::getline(file, magic); std::getline(file, magic);
if (magic != BanListMagic) { if (magic != BanListMagic) {
std::cout << "Ban list is not valid!\n\n"; LOG_ERROR(Network, "Ban list is not valid!");
return {}; return {};
} }
@ -137,7 +139,7 @@ static void SaveBanList(const Network::Room::BanList& ban_list, const std::strin
std::ofstream file; std::ofstream file;
Common::FS::OpenFileStream(file, path, std::ios_base::out); Common::FS::OpenFileStream(file, path, std::ios_base::out);
if (!file) { if (!file) {
std::cout << "Could not save ban list!\n\n"; LOG_ERROR(Network, "Could not save ban list!");
return; return;
} }
@ -153,8 +155,6 @@ static void SaveBanList(const Network::Room::BanList& ban_list, const std::strin
for (const auto& ip : ban_list.second) { for (const auto& ip : ban_list.second) {
file << ip << "\n"; file << ip << "\n";
} }
file.flush();
} }
static void InitializeLogging(const std::string& log_file) { static void InitializeLogging(const std::string& log_file) {
@ -202,6 +202,8 @@ int main(int argc, char** argv) {
{0, 0, 0, 0}, {0, 0, 0, 0},
}; };
InitializeLogging(log_file);
while (optind < argc) { while (optind < argc) {
int arg = getopt_long(argc, argv, "n:d:p:m:w:g:u:t:a:i:l:hv", long_options, &option_index); int arg = getopt_long(argc, argv, "n:d:p:m:w:g:u:t:a:i:l:hv", long_options, &option_index);
if (arg != -1) { if (arg != -1) {
@ -256,52 +258,53 @@ int main(int argc, char** argv) {
} }
if (room_name.empty()) { if (room_name.empty()) {
std::cout << "room name is empty!\n\n"; LOG_ERROR(Network, "Room name is empty!");
PrintHelp(argv[0]); PrintHelp(argv[0]);
return -1; return -1;
} }
if (preferred_game.empty()) { if (preferred_game.empty()) {
std::cout << "preferred game is empty!\n\n"; LOG_ERROR(Network, "Preferred game is empty!");
PrintHelp(argv[0]); PrintHelp(argv[0]);
return -1; return -1;
} }
if (preferred_game_id == 0) { if (preferred_game_id == 0) {
std::cout << "preferred-game-id not set!\nThis should get set to allow users to find your " LOG_ERROR(Network,
"room.\nSet with --preferred-game-id id\n\n"; "preferred-game-id not set!\nThis should get set to allow users to find your "
"room.\nSet with --preferred-game-id id");
} }
if (max_members > Network::MaxConcurrentConnections || max_members < 2) { if (max_members > Network::MaxConcurrentConnections || max_members < 2) {
std::cout << "max_members needs to be in the range 2 - " LOG_ERROR(Network, "max_members needs to be in the range 2 - {}!",
<< Network::MaxConcurrentConnections << "!\n\n"; Network::MaxConcurrentConnections);
PrintHelp(argv[0]); PrintHelp(argv[0]);
return -1; return -1;
} }
if (port > 65535) { if (port > UINT16_MAX) {
std::cout << "port needs to be in the range 0 - 65535!\n\n"; LOG_ERROR(Network, "Port needs to be in the range 0 - 65535!");
PrintHelp(argv[0]); PrintHelp(argv[0]);
return -1; return -1;
} }
if (ban_list_file.empty()) { if (ban_list_file.empty()) {
std::cout << "Ban list file not set!\nThis should get set to load and save room ban " LOG_ERROR(Network, "Ban list file not set!\nThis should get set to load and save room ban "
"list.\nSet with --ban-list-file <file>\n\n"; "list.\nSet with --ban-list-file <file>");
} }
bool announce = true; bool announce = true;
if (token.empty() && announce) { if (token.empty() && announce) {
announce = false; announce = false;
std::cout << "token is empty: Hosting a private room\n\n"; LOG_INFO(Network, "Token is empty: Hosting a private room");
} }
if (web_api_url.empty() && announce) { if (web_api_url.empty() && announce) {
announce = false; announce = false;
std::cout << "endpoint url is empty: Hosting a private room\n\n"; LOG_INFO(Network, "Endpoint url is empty: Hosting a private room");
} }
if (announce) { if (announce) {
if (username.empty()) { if (username.empty()) {
std::cout << "Hosting a public room\n\n"; LOG_INFO(Network, "Hosting a public room");
Settings::values.web_api_url = web_api_url; Settings::values.web_api_url = web_api_url;
Settings::values.yuzu_username = UsernameFromDisplayToken(token); Settings::values.yuzu_username = UsernameFromDisplayToken(token);
username = Settings::values.yuzu_username.GetValue(); username = Settings::values.yuzu_username.GetValue();
Settings::values.yuzu_token = TokenFromDisplayToken(token); Settings::values.yuzu_token = TokenFromDisplayToken(token);
} else { } else {
std::cout << "Hosting a public room\n\n"; LOG_INFO(Network, "Hosting a public room");
Settings::values.web_api_url = web_api_url; Settings::values.web_api_url = web_api_url;
Settings::values.yuzu_username = username; Settings::values.yuzu_username = username;
Settings::values.yuzu_token = token; Settings::values.yuzu_token = token;
@ -309,11 +312,9 @@ int main(int argc, char** argv) {
} }
if (!announce && enable_yuzu_mods) { if (!announce && enable_yuzu_mods) {
enable_yuzu_mods = false; enable_yuzu_mods = false;
std::cout << "Can not enable yuzu Moderators for private rooms\n\n"; LOG_INFO(Network, "Can not enable yuzu Moderators for private rooms");
} }
InitializeLogging(log_file);
// Load the ban list // Load the ban list
Network::Room::BanList ban_list; Network::Room::BanList ban_list;
if (!ban_list_file.empty()) { if (!ban_list_file.empty()) {
@ -326,27 +327,26 @@ int main(int argc, char** argv) {
verify_backend = verify_backend =
std::make_unique<WebService::VerifyUserJWT>(Settings::values.web_api_url.GetValue()); std::make_unique<WebService::VerifyUserJWT>(Settings::values.web_api_url.GetValue());
#else #else
std::cout LOG_INFO(Network,
<< "yuzu Web Services is not available with this build: validation is disabled.\n\n"; "yuzu Web Services is not available with this build: validation is disabled.");
verify_backend = std::make_unique<Network::VerifyUser::NullBackend>(); verify_backend = std::make_unique<Network::VerifyUser::NullBackend>();
#endif #endif
} else { } else {
verify_backend = std::make_unique<Network::VerifyUser::NullBackend>(); verify_backend = std::make_unique<Network::VerifyUser::NullBackend>();
} }
Core::System system{}; Network::RoomNetwork network{};
auto& network = system.GetRoomNetwork();
network.Init(); network.Init();
if (std::shared_ptr<Network::Room> room = network.GetRoom().lock()) { if (auto room = network.GetRoom().lock()) {
AnnounceMultiplayerRoom::GameInfo preferred_game_info{.name = preferred_game, AnnounceMultiplayerRoom::GameInfo preferred_game_info{.name = preferred_game,
.id = preferred_game_id}; .id = preferred_game_id};
if (!room->Create(room_name, room_description, "", port, password, max_members, username, if (!room->Create(room_name, room_description, "", port, password, max_members, username,
preferred_game_info, std::move(verify_backend), ban_list, preferred_game_info, std::move(verify_backend), ban_list,
enable_yuzu_mods)) { enable_yuzu_mods)) {
std::cout << "Failed to create room: \n\n"; LOG_INFO(Network, "Failed to create room: ");
return -1; return -1;
} }
std::cout << "Room is open. Close with Q+Enter...\n\n"; LOG_INFO(Network, "Room is open. Close with Q+Enter...");
auto announce_session = std::make_unique<Core::AnnounceMultiplayerSession>(network); auto announce_session = std::make_unique<Core::AnnounceMultiplayerSession>(network);
if (announce) { if (announce) {
announce_session->Start(); announce_session->Start();

View File

@ -10,7 +10,7 @@
class Validation { class Validation {
public: public:
Validation() Validation()
: room_name(room_name_regex), nickname(nickname_regex), ip(ip_regex), port(0, 65535) {} : room_name(room_name_regex), nickname(nickname_regex), ip(ip_regex), port(0, UINT16_MAX) {}
~Validation() = default; ~Validation() = default;

View File

@ -104,11 +104,12 @@ struct Values {
// multiplayer settings // multiplayer settings
Settings::Setting<QString> multiplayer_nickname{QStringLiteral("yuzu"), "nickname"}; Settings::Setting<QString> multiplayer_nickname{QStringLiteral("yuzu"), "nickname"};
Settings::Setting<QString> multiplayer_ip{{}, "ip"}; Settings::Setting<QString> multiplayer_ip{{}, "ip"};
Settings::SwitchableSetting<uint, true> multiplayer_port{24872, 0, 65535, "port"}; Settings::SwitchableSetting<uint, true> multiplayer_port{24872, 0, UINT16_MAX, "port"};
Settings::Setting<QString> multiplayer_room_nickname{{}, "room_nickname"}; Settings::Setting<QString> multiplayer_room_nickname{{}, "room_nickname"};
Settings::Setting<QString> multiplayer_room_name{{}, "room_name"}; Settings::Setting<QString> multiplayer_room_name{{}, "room_name"};
Settings::SwitchableSetting<uint, true> multiplayer_max_player{8, 0, 8, "max_player"}; Settings::SwitchableSetting<uint, true> multiplayer_max_player{8, 0, 8, "max_player"};
Settings::SwitchableSetting<uint, true> multiplayer_room_port{24872, 0, 65535, "room_port"}; Settings::SwitchableSetting<uint, true> multiplayer_room_port{24872, 0, UINT16_MAX,
"room_port"};
Settings::SwitchableSetting<uint, true> multiplayer_host_type{0, 0, 1, "host_type"}; Settings::SwitchableSetting<uint, true> multiplayer_host_type{0, 0, 1, "host_type"};
Settings::Setting<qulonglong> multiplayer_game_id{{}, "game_id"}; Settings::Setting<qulonglong> multiplayer_game_id{{}, "game_id"};
Settings::Setting<QString> multiplayer_room_description{{}, "room_description"}; Settings::Setting<QString> multiplayer_room_description{{}, "room_description"};