/* Copyright 2016-2024 melonDS team This file is part of melonDS. melonDS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. melonDS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with melonDS. If not, see http://www.gnu.org/licenses/. */ #ifndef LAN_H #define LAN_H #include #include #include #include #include #ifndef socket_t #ifdef __WIN32__ #include #define socket_t SOCKET #else #define socket_t int #endif #endif #include "types.h" #include "Platform.h" #include "MPInterface.h" namespace melonDS { class LAN : public MPInterface { public: LAN() noexcept; LAN(const LAN&) = delete; LAN& operator=(const LAN&) = delete; LAN(LAN&& other) = delete; LAN& operator=(LAN&& other) = delete; ~LAN() noexcept; enum PlayerStatus { Player_None = 0, // no player in this entry Player_Client, // game client Player_Host, // game host Player_Connecting, // player still connecting Player_Disconnected, // player disconnected }; struct Player { int ID; char Name[32]; PlayerStatus Status; u32 Address; bool IsLocalPlayer; u32 Ping; }; struct DiscoveryData { u32 Magic; u32 Version; u32 Tick; char SessionName[64]; u8 NumPlayers; u8 MaxPlayers; u8 Status; // 0=idle 1=playing }; bool StartDiscovery(); void EndDiscovery(); bool StartHost(const char* player, int numplayers); bool StartClient(const char* player, const char* host); void EndSession(); std::map GetDiscoveryList(); std::vector GetPlayerList(); int GetNumPlayers() { return NumPlayers; } int GetMaxPlayers() { return MaxPlayers; } void Process() override; void Begin(int inst) override; void End(int inst) override; int SendPacket(int inst, u8* data, int len, u64 timestamp) override; int RecvPacket(int inst, u8* data, u64* timestamp) override; int SendCmd(int inst, u8* data, int len, u64 timestamp) override; int SendReply(int inst, u8* data, int len, u64 timestamp, u16 aid) override; int SendAck(int inst, u8* data, int len, u64 timestamp) override; int RecvHostPacket(int inst, u8* data, u64* timestamp) override; u16 RecvReplies(int inst, u8* data, u64 timestamp, u16 aidmask) override; private: bool Inited; bool Active; bool IsHost; ENetHost* Host; ENetPeer* RemotePeers[16]; socket_t DiscoverySocket; u32 DiscoveryLastTick; std::map DiscoveryList; Platform::Mutex* DiscoveryMutex; Player Players[16]; int NumPlayers; int MaxPlayers; Platform::Mutex* PlayersMutex; Player MyPlayer; u32 HostAddress; u16 ConnectedBitmask; int MPRecvTimeout; int LastHostID; ENetPeer* LastHostPeer; std::queue RXQueue; u32 FrameCount; void ProcessDiscovery(); void HostUpdatePlayerList(); void ClientUpdatePlayerList(); void ProcessHostEvent(ENetEvent& event); void ProcessClientEvent(ENetEvent& event); void ProcessEvent(ENetEvent& event); void ProcessLAN(int type); int SendPacketGeneric(u32 type, u8* packet, int len, u64 timestamp); int RecvPacketGeneric(u8* packet, bool block, u64* timestamp); }; } #endif // LAN_H