#pragma once #if defined _WINDOWS64 #include #include #elif defined _XBOX #include #include #include #elif defined __PS3__ || defined __ORBIS__ #include #include #include #include #include #include #include #include #elif defined __PSVITA__ #include #endif #ifdef __PS3__ #include #include #endif #include #include "..\..\Common\Network\NetworkPlayerInterface.h" #ifdef _WINDOWS64 #pragma comment(lib, "Ws2_32.lib") #endif #define NETWORK_LAN_DEFAULT_PORT 25565 #define NETWORK_LAN_MAX_CLIENTS 7 #define NETWORK_LAN_RECV_BUFFER_SIZE 65536 #define NETWORK_LAN_MAX_PACKET_SIZE (4 * 1024 * 1024) #define NETWORK_LAN_DISCOVERY_PORT 25566 #define NETWORK_LAN_BROADCAST_MAGIC 0x4D434C4E #ifdef __PS3__ typedef int SOCKET; #define INVALID_SOCKET -1 #define closesocket socketclose #define #elif defined(__ORBIS__) typedef int SOCKET; #define INVALID_SOCKET -1 #define SO_NBIO SCE_NET_SO_NBIO #define sys_net_errno sce_net_errno #define SYS_NET_EINPROGRESS SCE_NET_EINPROGRESS #define socketselect select #define closesocket sceNetSocketClose #define socketclose sceNetSocketClose #elif defined(__PSVITA__) typedef SceNetId SOCKET; typedef SceNetSockaddr sockaddr; typedef SceNetSocklen_t socklen_t; #define getsockopt sceNetGetsockopt #define setsockopt sceNetSetsockopt #define recv sceNetRecv #define send sceNetSend #define bind sceNetBind #define sendto sceNetSendto #define recvfrom sceNetRecvfrom #define listen sceNetListen #define connect sceNetConnect #define accept sceNetAccept #define closesocket sceNetSocketClose #define socketclose sceNetSocketClose #define inet_ntop sceNetInetNtop #define SOL_SOCKET SCE_NET_SOL_SOCKET #define AF_INET SCE_NET_AF_INET #define SOCK_STREAM SCE_NET_SOCK_STREAM #define sys_net_errno sce_net_errno #define SYS_NET_EINPROGRESS SCE_NET_EINPROGRESS #define htonl sceNetHtonl #define htons sceNetHtons #define ntohl sceNetNtohl #define ntohs sceNetNtohs #define SO_BROADCAST SCE_NET_SO_BROADCAST #define SO_ERROR SCE_NET_SO_ERROR #define SO_RCVTIMEO SCE_NET_SO_RCVTIMEO #define SO_REUSEADDR SCE_NET_SO_REUSEADDR #define SO_NBIO SCE_NET_SO_NBIO #define SOCK_DGRAM SCE_NET_SOCK_DGRAM #define INADDR_ANY SCE_NET_INADDR_ANY #define IPPROTO_TCP SCE_NET_IPPROTO_TCP #define IPPROTO_UDP SCE_NET_IPPROTO_UDP #define TCP_NODELAY SCE_NET_TCP_NODELAY #define INADDR_BROADCAST SCE_NET_INADDR_BROADCAST #define INVALID_SOCKET -1 #endif class Socket; #pragma pack(push, 1) struct LANBroadcast { DWORD magic; WORD netVersion; WORD gamePort; char hostName[32]; BYTE playerCount; BYTE maxPlayers; DWORD gameHostSettings; DWORD texturePackParentId; BYTE subTexturePackId; BYTE isJoinable; char playerNames[8][XUSER_NAME_SIZE]; }; #pragma pack(pop) struct LANSession { char hostIP[64]; int hostPort; wchar_t hostName[32]; unsigned short netVersion; unsigned char playerCount; unsigned char maxPlayers; unsigned int gameHostSettings; unsigned int texturePackParentId; unsigned char subTexturePackId; bool isJoinable; DWORD lastSeenTick; char playerNames[8][XUSER_NAME_SIZE]; }; struct RemoteConnection { SOCKET tcpSocket; BYTE smallId; C4JThread* recvThread; volatile bool active; }; class NetworkSocketLayer { public: static bool Initialize(); static void Shutdown(); static bool HostGame(int port); static bool JoinGame(const char *ip, int port); static bool SendToSmallId(BYTE targetSmallId, const void *data, int dataSize); static bool SendOnSocket(SOCKET sock, const void *data, int dataSize); static bool IsHosting() { return s_isHost; } static bool IsConnected() { return s_connected; } static bool IsActive() { return s_active; } static BYTE GetLocalSmallId() { return s_localSmallId; } static BYTE GetHostSmallId() { return s_hostSmallId; } static SOCKET GetSocketForSmallId(BYTE smallId); static void HandleDataReceived(BYTE fromSmallId, BYTE toSmallId, unsigned char *data, unsigned int dataSize); static bool PopDisconnectedSmallId(BYTE *outSmallId); static void PushFreeSmallId(BYTE smallId); static void CloseConnectionBySmallId(BYTE smallId); static bool StartAdvertising(int gamePort, const wchar_t *hostName, unsigned int gameSettings, unsigned int texPackId, unsigned char subTexId, unsigned short netVer); static void StopAdvertising(); static void UpdateAdvertisePlayerCount(BYTE count); static void UpdateAdvertiseJoinable(bool joinable); static void UpdateAdvertisePlayerNames(BYTE count, const char playerNames[][XUSER_NAME_SIZE]); static bool StartDiscovery(); static void StopDiscovery(); static vector GetDiscoveredSessions(); static int GetHostPort() { return s_hostGamePort; } private: static int AcceptThreadProc(void* param); static int RecvThreadProc(void* param); static int ClientRecvThreadProc(void* param); static int AdvertiseThreadProc(void* param); static int DiscoveryThreadProc(void* param); static SOCKET s_listenSocket; static SOCKET s_hostConnectionSocket; static C4JThread* s_acceptThread; static C4JThread* s_clientRecvThread; static bool s_isHost; static bool s_connected; static bool s_active; static bool s_initialized; static BYTE s_localSmallId; static BYTE s_hostSmallId; static BYTE s_nextSmallId; static CRITICAL_SECTION s_sendLock; static CRITICAL_SECTION s_connectionsLock; static std::vector s_connections; static SOCKET s_advertiseSock; static C4JThread* s_advertiseThread; static volatile bool s_advertising; static LANBroadcast s_advertiseData; static CRITICAL_SECTION s_advertiseLock; static int s_hostGamePort; static SOCKET s_discoverySock; static C4JThread* s_discoveryThread; static volatile bool s_discovering; static CRITICAL_SECTION s_discoveryLock; static std::vector s_discoveredSessions; static CRITICAL_SECTION s_disconnectLock; static std::vector s_disconnectedSmallIds; static CRITICAL_SECTION s_freeSmallIdLock; static std::vector s_freeSmallIds; }; extern bool g_MultiplayerHost; extern bool g_MultiplayerJoin; extern int g_MultiplayerPort; extern char g_MultiplayerIP[256];