NetPlay: Split the server out, and make the local system manage a client as well
This should be transparent, but it may cause regressions. The idea here is that now all players, including the host of the server, talk to the server through TCP/IP networking. This significantly reduces our codepaths through netplay, and will prevent strange local-only bugs from happening. The cleanup isn't 100% finished yet. The NetPlay dialog still drives the server through private APIs. I eventually want to sanction off the server entirely, so all communication is done through TCP/IP. This will allow us to have high-traffic public servers that can relay multiple games and lobbies at a time, and split off channel and game management to people other than the host. This is all still just a pipe dream, though.
This commit is contained in:
parent
9e8655fa1f
commit
3b32d3c90d
|
@ -261,12 +261,6 @@ bool NetPlay::StopGame()
|
|||
return true;
|
||||
}
|
||||
|
||||
void NetPlay::SetMemcardWriteEnabled(bool enabled)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
|
||||
g_NetPlaySettings.m_WriteToMemcard = enabled;
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
u8 NetPlay::GetPadNum(u8 numPAD)
|
||||
{
|
||||
|
@ -279,16 +273,6 @@ u8 NetPlay::GetPadNum(u8 numPAD)
|
|||
return i;
|
||||
}
|
||||
|
||||
void NetPlay::GetNetSettings()
|
||||
{
|
||||
SConfig &instance = SConfig::GetInstance();
|
||||
g_NetPlaySettings.m_DSPHLE = instance.m_LocalCoreStartupParameter.bDSPHLE;
|
||||
g_NetPlaySettings.m_DSPEnableJIT = instance.m_EnableJIT;
|
||||
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
g_NetPlaySettings.m_Controllers[i] = SConfig::GetInstance().m_SIDevice[i];
|
||||
}
|
||||
|
||||
// stuff hacked into dolphin
|
||||
|
||||
// called from ---CPU--- thread
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <SFML/Network.hpp>
|
||||
|
||||
#include "NetPlayProto.h"
|
||||
#include "GCPadStatus.h"
|
||||
|
||||
#include <functional>
|
||||
|
@ -31,63 +32,6 @@ public:
|
|||
u32 nLo;
|
||||
};
|
||||
|
||||
struct NetSettings
|
||||
{
|
||||
bool m_DSPHLE;
|
||||
bool m_DSPEnableJIT;
|
||||
bool m_WriteToMemcard;
|
||||
u8 m_Controllers[4];
|
||||
};
|
||||
extern NetSettings g_NetPlaySettings;
|
||||
|
||||
struct Rpt : public std::vector<u8>
|
||||
{
|
||||
u16 channel;
|
||||
};
|
||||
|
||||
typedef std::vector<Rpt> NetWiimote;
|
||||
|
||||
#define NETPLAY_VERSION "Dolphin NetPlay 2013-07-22"
|
||||
|
||||
// messages
|
||||
enum
|
||||
{
|
||||
NP_MSG_PLAYER_JOIN = 0x10,
|
||||
NP_MSG_PLAYER_LEAVE = 0x11,
|
||||
|
||||
NP_MSG_CHAT_MESSAGE = 0x30,
|
||||
|
||||
NP_MSG_PAD_DATA = 0x60,
|
||||
NP_MSG_PAD_MAPPING = 0x61,
|
||||
NP_MSG_PAD_BUFFER = 0x62,
|
||||
|
||||
NP_MSG_WIIMOTE_DATA = 0x70,
|
||||
NP_MSG_WIIMOTE_MAPPING = 0x71, // just using pad mapping for now
|
||||
|
||||
NP_MSG_START_GAME = 0xA0,
|
||||
NP_MSG_CHANGE_GAME = 0xA1,
|
||||
NP_MSG_STOP_GAME = 0xA2,
|
||||
NP_MSG_DISABLE_GAME = 0xA3,
|
||||
|
||||
NP_MSG_READY = 0xD0,
|
||||
NP_MSG_NOT_READY = 0xD1,
|
||||
|
||||
NP_MSG_PING = 0xE0,
|
||||
NP_MSG_PONG = 0xE1,
|
||||
};
|
||||
|
||||
typedef u8 MessageId;
|
||||
typedef u8 PlayerId;
|
||||
typedef s8 PadMapping;
|
||||
typedef u32 FrameNum;
|
||||
|
||||
enum
|
||||
{
|
||||
CON_ERR_SERVER_FULL = 1,
|
||||
CON_ERR_GAME_RUNNING,
|
||||
CON_ERR_VERSION_MISMATCH
|
||||
};
|
||||
|
||||
class NetPlayUI
|
||||
{
|
||||
public:
|
||||
|
@ -104,6 +48,8 @@ public:
|
|||
virtual void OnMsgStopGame() = 0;
|
||||
};
|
||||
|
||||
extern NetSettings g_NetPlaySettings;
|
||||
|
||||
class NetPlay
|
||||
{
|
||||
public:
|
||||
|
@ -124,16 +70,12 @@ public:
|
|||
virtual bool StartGame(const std::string &path);
|
||||
virtual bool StopGame();
|
||||
|
||||
virtual void SetMemcardWriteEnabled(bool enabled);
|
||||
//void PushPadStates(unsigned int count);
|
||||
|
||||
u8 GetPadNum(u8 numPAD);
|
||||
static NetPlay* GetNetPlayPtr();
|
||||
|
||||
protected:
|
||||
//void GetBufferedPad(const u8 pad_nb, NetPad* const netvalues);
|
||||
void ClearBuffers();
|
||||
void GetNetSettings();
|
||||
virtual void SendPadState(const PadMapping local_nb, const NetPad& np) = 0;
|
||||
|
||||
struct
|
||||
|
@ -179,74 +121,6 @@ protected:
|
|||
void NetPlay_Enable(NetPlay* const np);
|
||||
void NetPlay_Disable();
|
||||
|
||||
class NetPlayServer : public NetPlay
|
||||
{
|
||||
public:
|
||||
void ThreadFunc();
|
||||
|
||||
NetPlayServer(const u16 port, const std::string& name, NetPlayUI* dialog);
|
||||
~NetPlayServer();
|
||||
|
||||
void GetPlayerList(std::string& list, std::vector<int>& pid_list);
|
||||
|
||||
// Send and receive pads values
|
||||
//bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues);
|
||||
bool ChangeGame(const std::string& game);
|
||||
void SendChatMessage(const std::string& msg);
|
||||
|
||||
bool StartGame(const std::string &path);
|
||||
bool StopGame();
|
||||
|
||||
bool GetPadMapping(const int pid, int map[]);
|
||||
bool SetPadMapping(const int pid, const int map[]);
|
||||
|
||||
void AdjustPadBufferSize(unsigned int size);
|
||||
|
||||
#ifdef USE_UPNP
|
||||
void TryPortmapping(u16 port);
|
||||
#endif
|
||||
|
||||
private:
|
||||
class Client : public Player
|
||||
{
|
||||
public:
|
||||
Client() : ping(0), current_game(0) {}
|
||||
|
||||
sf::SocketTCP socket;
|
||||
u64 ping;
|
||||
u32 current_game;
|
||||
};
|
||||
|
||||
void SendPadState(const PadMapping local_nb, const NetPad& np);
|
||||
void SendToClients(sf::Packet& packet, const PlayerId skip_pid = 0);
|
||||
unsigned int OnConnect(sf::SocketTCP& socket);
|
||||
unsigned int OnDisconnect(sf::SocketTCP& socket);
|
||||
unsigned int OnData(sf::Packet& packet, sf::SocketTCP& socket);
|
||||
void UpdatePadMapping();
|
||||
|
||||
std::map<sf::SocketTCP, Client> m_players;
|
||||
|
||||
Common::Timer m_ping_timer;
|
||||
u32 m_ping_key;
|
||||
bool m_update_pings;
|
||||
|
||||
#ifdef USE_UPNP
|
||||
static void mapPortThread(const u16 port);
|
||||
static void unmapPortThread();
|
||||
|
||||
static bool initUPnP();
|
||||
static bool UPnPMapPort(const std::string& addr, const u16 port);
|
||||
static bool UPnPUnmapPort(const u16 port);
|
||||
|
||||
static struct UPNPUrls m_upnp_urls;
|
||||
static struct IGDdatas m_upnp_data;
|
||||
static u16 m_upnp_mapped;
|
||||
static bool m_upnp_inited;
|
||||
static bool m_upnp_error;
|
||||
static std::thread m_upnp_thread;
|
||||
#endif
|
||||
};
|
||||
|
||||
class NetPlayClient : public NetPlay
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#ifndef _NETPLAY_PROTO_H
|
||||
#define _NETPLAY_PROTO_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "CommonTypes.h"
|
||||
|
||||
struct NetSettings
|
||||
{
|
||||
bool m_DSPHLE;
|
||||
bool m_DSPEnableJIT;
|
||||
bool m_WriteToMemcard;
|
||||
u8 m_Controllers[4];
|
||||
};
|
||||
|
||||
struct Rpt : public std::vector<u8>
|
||||
{
|
||||
u16 channel;
|
||||
};
|
||||
|
||||
typedef std::vector<Rpt> NetWiimote;
|
||||
|
||||
#define NETPLAY_VERSION "Dolphin NetPlay 2013-07-19"
|
||||
|
||||
// messages
|
||||
enum
|
||||
{
|
||||
NP_MSG_PLAYER_JOIN = 0x10,
|
||||
NP_MSG_PLAYER_LEAVE = 0x11,
|
||||
|
||||
NP_MSG_CHAT_MESSAGE = 0x30,
|
||||
|
||||
NP_MSG_PAD_DATA = 0x60,
|
||||
NP_MSG_PAD_MAPPING = 0x61,
|
||||
NP_MSG_PAD_BUFFER = 0x62,
|
||||
|
||||
NP_MSG_WIIMOTE_DATA = 0x70,
|
||||
NP_MSG_WIIMOTE_MAPPING = 0x71, // just using pad mapping for now
|
||||
|
||||
NP_MSG_START_GAME = 0xA0,
|
||||
NP_MSG_CHANGE_GAME = 0xA1,
|
||||
NP_MSG_STOP_GAME = 0xA2,
|
||||
NP_MSG_DISABLE_GAME = 0xA3,
|
||||
|
||||
NP_MSG_READY = 0xD0,
|
||||
NP_MSG_NOT_READY = 0xD1,
|
||||
|
||||
NP_MSG_PING = 0xE0,
|
||||
NP_MSG_PONG = 0xE1,
|
||||
};
|
||||
|
||||
typedef u8 MessageId;
|
||||
typedef u8 PlayerId;
|
||||
typedef s8 PadMapping;
|
||||
typedef u32 FrameNum;
|
||||
|
||||
enum
|
||||
{
|
||||
CON_ERR_SERVER_FULL = 1,
|
||||
CON_ERR_GAME_RUNNING,
|
||||
CON_ERR_VERSION_MISMATCH
|
||||
};
|
||||
|
||||
#endif
|
|
@ -2,9 +2,24 @@
|
|||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "NetPlay.h"
|
||||
#include "NetPlayServer.h"
|
||||
|
||||
NetPlayServer::Client::Client()
|
||||
{
|
||||
memset(pad_map, -1, sizeof(pad_map));
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
std::string NetPlayServer::Client::ToString() const
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << name << '[' << (char)(pid+'0') << "] : " << revision << " |";
|
||||
for (unsigned int i=0; i<4; ++i)
|
||||
ss << (pad_map[i]>=0 ? (char)(pad_map[i]+'1') : '-');
|
||||
ss << '|';
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
NetPlayServer::~NetPlayServer()
|
||||
{
|
||||
if (is_connected)
|
||||
|
@ -22,35 +37,15 @@ NetPlayServer::~NetPlayServer()
|
|||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
NetPlayServer::NetPlayServer(const u16 port, const std::string& name, NetPlayUI* dialog) : NetPlay(dialog)
|
||||
NetPlayServer::NetPlayServer(const u16 port) : is_connected(false), m_is_running(false)
|
||||
{
|
||||
m_update_pings = true;
|
||||
|
||||
if (m_socket.Listen(port))
|
||||
{
|
||||
Client player;
|
||||
player.pid = 0;
|
||||
player.revision = netplay_dolphin_ver;
|
||||
player.socket = m_socket;
|
||||
player.name = name;
|
||||
|
||||
// map local pad 1 to game pad 1
|
||||
player.pad_map[0] = 0;
|
||||
|
||||
// add self to player list
|
||||
m_players[m_socket] = player;
|
||||
m_local_player = &m_players[m_socket];
|
||||
//PanicAlertT("Listening");
|
||||
|
||||
m_dialog->Update();
|
||||
|
||||
is_connected = true;
|
||||
|
||||
m_do_loop = true;
|
||||
m_selector.Add(m_socket);
|
||||
m_thread = std::thread(std::mem_fun(&NetPlayServer::ThreadFunc), this);
|
||||
}
|
||||
else
|
||||
is_connected = false;
|
||||
}
|
||||
|
||||
// called from ---NETPLAY--- thread
|
||||
|
@ -258,8 +253,6 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket)
|
|||
// add client to selector/ used for receiving
|
||||
m_selector.Add(socket);
|
||||
|
||||
m_dialog->Update();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -271,7 +264,6 @@ unsigned int NetPlayServer::OnDisconnect(sf::SocketTCP& socket)
|
|||
PanicAlertT("Client disconnect while game is running!! NetPlay is disabled. You must manually stop the game.");
|
||||
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
|
||||
m_is_running = false;
|
||||
NetPlay_Disable();
|
||||
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_DISABLE_GAME;
|
||||
|
@ -293,8 +285,6 @@ unsigned int NetPlayServer::OnDisconnect(sf::SocketTCP& socket)
|
|||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||
SendToClients(spac);
|
||||
|
||||
m_dialog->Update();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -357,8 +347,6 @@ bool NetPlayServer::SetPadMapping(const int pid, const int map[])
|
|||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||
UpdatePadMapping(); // sync pad mappings with everyone
|
||||
|
||||
m_dialog->Update();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -424,12 +412,6 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
|
|||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||
SendToClients(spac, player.pid);
|
||||
}
|
||||
|
||||
// add to gui
|
||||
std::ostringstream ss;
|
||||
ss << player.name << '[' << (char)(player.pid+'0') << "]: " << msg;
|
||||
|
||||
m_dialog->AppendChat(ss.str());
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -440,8 +422,8 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
|
|||
break;
|
||||
|
||||
PadMapping map = 0;
|
||||
NetPad np;
|
||||
packet >> map >> np.nHi >> np.nLo;
|
||||
int hi, lo;
|
||||
packet >> map >> hi >> lo;
|
||||
|
||||
// check if client's pad indeed maps in game
|
||||
if (map >= 0 && map < 4)
|
||||
|
@ -454,14 +436,12 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
|
|||
if (map < 0)
|
||||
return 1;
|
||||
|
||||
// add to pad buffer
|
||||
m_pad_buffer[(unsigned)map].Push(np);
|
||||
|
||||
// relay to clients
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_PAD_DATA;
|
||||
spac << map; // in game mapping
|
||||
spac << np.nHi << np.nLo;
|
||||
spac << hi << lo;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||
SendToClients(spac, player.pid);
|
||||
|
@ -475,11 +455,7 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
|
|||
packet >> ping_key;
|
||||
|
||||
if (m_ping_key == ping_key)
|
||||
{
|
||||
//PanicAlertT("Good pong");
|
||||
player.ping = ping;
|
||||
}
|
||||
m_dialog->Update();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -550,29 +526,16 @@ bool NetPlayServer::ChangeGame(const std::string &game)
|
|||
return true;
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
void NetPlayServer::SendPadState(const PadMapping local_nb, const NetPad& np)
|
||||
// called from ---GUI--- thread
|
||||
void NetPlayServer::SetNetSettings(const NetSettings &settings)
|
||||
{
|
||||
// send to server
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_PAD_DATA;
|
||||
spac << m_local_player->pad_map[local_nb]; // in-game pad num
|
||||
spac << np.nHi << np.nLo;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||
SendToClients(spac);
|
||||
m_settings = settings;
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
bool NetPlayServer::StartGame(const std::string &path)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
|
||||
|
||||
GetNetSettings();
|
||||
if (false == NetPlay::StartGame(path))
|
||||
return false;
|
||||
|
||||
// TODO: i dont like this here
|
||||
m_current_game = Common::Timer::GetTimeMs();
|
||||
|
||||
// no change, just update with clients
|
||||
|
@ -581,17 +544,19 @@ bool NetPlayServer::StartGame(const std::string &path)
|
|||
// tell clients to start game
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_START_GAME;
|
||||
spac << NetPlay::m_current_game;
|
||||
spac << g_NetPlaySettings.m_DSPEnableJIT;
|
||||
spac << g_NetPlaySettings.m_DSPHLE;
|
||||
spac << g_NetPlaySettings.m_WriteToMemcard;
|
||||
spac << m_current_game;
|
||||
spac << m_settings.m_DSPEnableJIT;
|
||||
spac << m_settings.m_DSPHLE;
|
||||
spac << m_settings.m_WriteToMemcard;
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
spac << g_NetPlaySettings.m_Controllers[i];
|
||||
spac << m_settings.m_Controllers[i];
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
|
||||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||
SendToClients(spac);
|
||||
|
||||
m_is_running = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -599,9 +564,6 @@ bool NetPlayServer::StartGame(const std::string &path)
|
|||
// called from ---GUI--- thread
|
||||
bool NetPlayServer::StopGame()
|
||||
{
|
||||
if (false == NetPlay::StopGame())
|
||||
return false;
|
||||
|
||||
// tell clients to stop game
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_STOP_GAME;
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#ifndef _NETPLAY_SERVER_H
|
||||
#define _NETPLAY_SERVER_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "CommonTypes.h"
|
||||
#include "Thread.h"
|
||||
#include "Timer.h"
|
||||
|
||||
#include <SFML/Network.hpp>
|
||||
|
||||
#include "NetPlayProto.h"
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
|
||||
class NetPlayServer
|
||||
{
|
||||
public:
|
||||
void ThreadFunc();
|
||||
|
||||
NetPlayServer(const u16 port);
|
||||
~NetPlayServer();
|
||||
|
||||
void GetPlayerList(std::string& list, std::vector<int>& pid_list);
|
||||
|
||||
bool ChangeGame(const std::string& game);
|
||||
void SendChatMessage(const std::string& msg);
|
||||
|
||||
void SetNetSettings(const NetSettings &settings);
|
||||
|
||||
bool StartGame(const std::string &path);
|
||||
bool StopGame();
|
||||
|
||||
bool GetPadMapping(const int pid, int map[]);
|
||||
bool SetPadMapping(const int pid, const int map[]);
|
||||
|
||||
void AdjustPadBufferSize(unsigned int size);
|
||||
|
||||
bool is_connected;
|
||||
|
||||
#ifdef USE_UPNP
|
||||
void TryPortmapping(u16 port);
|
||||
#endif
|
||||
|
||||
private:
|
||||
class Client
|
||||
{
|
||||
public:
|
||||
Client();
|
||||
std::string ToString() const;
|
||||
|
||||
PlayerId pid;
|
||||
std::string name;
|
||||
PadMapping pad_map[4];
|
||||
std::string revision;
|
||||
|
||||
sf::SocketTCP socket;
|
||||
u64 ping;
|
||||
u32 current_game;
|
||||
};
|
||||
|
||||
void SendToClients(sf::Packet& packet, const PlayerId skip_pid = 0);
|
||||
unsigned int OnConnect(sf::SocketTCP& socket);
|
||||
unsigned int OnDisconnect(sf::SocketTCP& socket);
|
||||
unsigned int OnData(sf::Packet& packet, sf::SocketTCP& socket);
|
||||
void UpdatePadMapping();
|
||||
|
||||
NetSettings m_settings;
|
||||
|
||||
bool m_is_running;
|
||||
bool m_do_loop;
|
||||
Common::Timer m_ping_timer;
|
||||
u32 m_ping_key;
|
||||
bool m_update_pings;
|
||||
u32 m_current_game;
|
||||
unsigned int m_target_buffer_size;
|
||||
|
||||
std::map<sf::SocketTCP, Client> m_players;
|
||||
|
||||
struct
|
||||
{
|
||||
std::recursive_mutex game;
|
||||
// lock order
|
||||
std::recursive_mutex players, send;
|
||||
} m_crit;
|
||||
|
||||
std::string m_selected_game;
|
||||
|
||||
sf::SocketTCP m_socket;
|
||||
std::thread m_thread;
|
||||
sf::Selector<sf::SocketTCP> m_selector;
|
||||
|
||||
#ifdef USE_UPNP
|
||||
static void mapPortThread(const u16 port);
|
||||
static void unmapPortThread();
|
||||
|
||||
static bool initUPnP();
|
||||
static bool UPnPMapPort(const std::string& addr, const u16 port);
|
||||
static bool UPnPUnmapPort(const u16 port);
|
||||
|
||||
static struct UPNPUrls m_upnp_urls;
|
||||
static struct IGDdatas m_upnp_data;
|
||||
static u16 m_upnp_mapped;
|
||||
static bool m_upnp_inited;
|
||||
static bool m_upnp_error;
|
||||
static std::thread m_upnp_thread;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
|
@ -7,9 +7,11 @@
|
|||
|
||||
#include "WxUtils.h"
|
||||
#include "NetPlay.h"
|
||||
#include "NetPlayServer.h"
|
||||
#include "NetWindow.h"
|
||||
#include "Frame.h"
|
||||
#include "Core.h"
|
||||
#include "ConfigManager.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
@ -20,7 +22,8 @@ BEGIN_EVENT_TABLE(NetPlayDiag, wxFrame)
|
|||
EVT_COMMAND(wxID_ANY, wxEVT_THREAD, NetPlayDiag::OnThread)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
static NetPlay* netplay_ptr = NULL;
|
||||
static NetPlayServer* netplay_server = NULL;
|
||||
static NetPlayClient* netplay_client = NULL;
|
||||
extern CFrame* main_frame;
|
||||
NetPlayDiag *NetPlayDiag::npd = NULL;
|
||||
|
||||
|
@ -200,6 +203,28 @@ NetPlaySetupDiag::~NetPlaySetupDiag()
|
|||
main_frame->g_NetPlaySetupDiag = NULL;
|
||||
}
|
||||
|
||||
void NetPlaySetupDiag::MakeNetPlayDiag(int port, const std::string &game, bool is_hosting)
|
||||
{
|
||||
NetPlayDiag *&npd = NetPlayDiag::GetInstance();
|
||||
std::string ip;
|
||||
npd = new NetPlayDiag(m_parent, m_game_list, game, is_hosting);
|
||||
if (is_hosting)
|
||||
ip = "127.0.0.1";
|
||||
else
|
||||
ip = WxStrToStr(m_connect_ip_text->GetValue());
|
||||
|
||||
netplay_client = new NetPlayClient(ip, (u16)port, npd, WxStrToStr(m_nickname_text->GetValue()));
|
||||
if (netplay_client->is_connected)
|
||||
{
|
||||
npd->Show();
|
||||
Destroy();
|
||||
}
|
||||
else
|
||||
{
|
||||
npd->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void NetPlaySetupDiag::OnHost(wxCommandEvent&)
|
||||
{
|
||||
NetPlayDiag *&npd = NetPlayDiag::GetInstance();
|
||||
|
@ -217,25 +242,19 @@ void NetPlaySetupDiag::OnHost(wxCommandEvent&)
|
|||
|
||||
std::string game(WxStrToStr(m_game_lbox->GetStringSelection()));
|
||||
|
||||
npd = new NetPlayDiag(m_parent, m_game_list, game, true);
|
||||
unsigned long port = 0;
|
||||
m_host_port_text->GetValue().ToULong(&port);
|
||||
netplay_ptr = new NetPlayServer(u16(port), WxStrToStr(m_nickname_text->GetValue()), npd);
|
||||
netplay_ptr->ChangeGame(game);
|
||||
if (netplay_ptr->is_connected)
|
||||
netplay_server = new NetPlayServer(u16(port));
|
||||
netplay_server->ChangeGame(game);
|
||||
if (netplay_server->is_connected)
|
||||
{
|
||||
#ifdef USE_UPNP
|
||||
if(m_upnp_chk->GetValue())
|
||||
((NetPlayServer*)netplay_ptr)->TryPortmapping(port);
|
||||
netplay_server->TryPortmapping(port);
|
||||
#endif
|
||||
npd->Show();
|
||||
Destroy();
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlertT("Failed to Listen!!");
|
||||
npd->Destroy();
|
||||
}
|
||||
|
||||
MakeNetPlayDiag(port, game, true);
|
||||
}
|
||||
|
||||
void NetPlaySetupDiag::OnJoin(wxCommandEvent&)
|
||||
|
@ -247,20 +266,9 @@ void NetPlaySetupDiag::OnJoin(wxCommandEvent&)
|
|||
return;
|
||||
}
|
||||
|
||||
npd = new NetPlayDiag(m_parent, m_game_list, "");
|
||||
unsigned long port = 0;
|
||||
m_connect_port_text->GetValue().ToULong(&port);
|
||||
netplay_ptr = new NetPlayClient(WxStrToStr(m_connect_ip_text->GetValue())
|
||||
, (u16)port, npd, WxStrToStr(m_nickname_text->GetValue()));
|
||||
if (netplay_ptr->is_connected)
|
||||
{
|
||||
npd->Show();
|
||||
Destroy();
|
||||
}
|
||||
else
|
||||
{
|
||||
npd->Destroy();
|
||||
}
|
||||
MakeNetPlayDiag(port, "", false);
|
||||
}
|
||||
|
||||
void NetPlaySetupDiag::OnQuit(wxCommandEvent&)
|
||||
|
@ -344,7 +352,6 @@ NetPlayDiag::NetPlayDiag(wxWindow* const parent, const CGameListCtrl* const game
|
|||
}
|
||||
|
||||
m_memcard_write = new wxCheckBox(panel, wxID_ANY, _("Write memcards (GC)"));
|
||||
m_memcard_write->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &NetPlayDiag::OnMemcardWriteCheck, this);
|
||||
bottom_szr->Add(m_memcard_write, 0, wxCENTER);
|
||||
|
||||
bottom_szr->AddStretchSpacer(1);
|
||||
|
@ -366,10 +373,15 @@ NetPlayDiag::NetPlayDiag(wxWindow* const parent, const CGameListCtrl* const game
|
|||
|
||||
NetPlayDiag::~NetPlayDiag()
|
||||
{
|
||||
if (netplay_ptr)
|
||||
if (netplay_client)
|
||||
{
|
||||
delete netplay_ptr;
|
||||
netplay_ptr = NULL;
|
||||
delete netplay_client;
|
||||
netplay_client = NULL;
|
||||
}
|
||||
if (netplay_server)
|
||||
{
|
||||
delete netplay_server;
|
||||
netplay_server = NULL;
|
||||
}
|
||||
npd = NULL;
|
||||
}
|
||||
|
@ -380,37 +392,50 @@ void NetPlayDiag::OnChat(wxCommandEvent&)
|
|||
|
||||
if (s.Length())
|
||||
{
|
||||
netplay_ptr->SendChatMessage(WxStrToStr(s));
|
||||
netplay_client->SendChatMessage(WxStrToStr(s));
|
||||
m_chat_text->AppendText(s.Prepend(wxT(" >> ")).Append(wxT('\n')));
|
||||
m_chat_msg_text->Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void NetPlayDiag::OnStart(wxCommandEvent&)
|
||||
void NetPlayDiag::GetNetSettings(NetSettings &settings)
|
||||
{
|
||||
SConfig &instance = SConfig::GetInstance();
|
||||
settings.m_DSPHLE = instance.m_LocalCoreStartupParameter.bDSPHLE;
|
||||
settings.m_DSPEnableJIT = instance.m_EnableJIT;
|
||||
settings.m_WriteToMemcard = m_memcard_write->GetValue();
|
||||
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
settings.m_Controllers[i] = SConfig::GetInstance().m_SIDevice[i];
|
||||
}
|
||||
|
||||
const std::string& NetPlayDiag::FindGame()
|
||||
{
|
||||
// find path for selected game, sloppy..
|
||||
for (u32 i = 0 ; auto game = m_game_list->GetISO(i); ++i)
|
||||
{
|
||||
if (m_selected_game == BuildGameName(*game))
|
||||
{
|
||||
netplay_ptr->StartGame(game->GetFileName());
|
||||
return;
|
||||
}
|
||||
}
|
||||
return game->GetFileName();
|
||||
|
||||
PanicAlertT("Game not found!");
|
||||
return "";
|
||||
}
|
||||
|
||||
void NetPlayDiag::OnStart(wxCommandEvent&)
|
||||
{
|
||||
NetSettings settings;
|
||||
GetNetSettings(settings);
|
||||
netplay_server->SetNetSettings(settings);
|
||||
netplay_server->StartGame(FindGame());
|
||||
}
|
||||
|
||||
void NetPlayDiag::OnStop(wxCommandEvent&)
|
||||
{
|
||||
netplay_ptr->StopGame();
|
||||
netplay_server->StopGame();
|
||||
}
|
||||
|
||||
void NetPlayDiag::BootGame(const std::string& filename)
|
||||
{
|
||||
main_frame->BootGame(filename);
|
||||
|
||||
Core::g_CoreStartupParameter.bEnableMemcardSaving = m_memcard_write->GetValue();
|
||||
}
|
||||
|
||||
void NetPlayDiag::StopGame()
|
||||
|
@ -452,19 +477,14 @@ void NetPlayDiag::OnMsgStopGame()
|
|||
GetEventHandler()->AddPendingEvent(evt);
|
||||
}
|
||||
|
||||
void NetPlayDiag::OnMemcardWriteCheck(wxCommandEvent &event)
|
||||
{
|
||||
netplay_ptr->SetMemcardWriteEnabled(m_memcard_write->GetValue());
|
||||
}
|
||||
|
||||
void NetPlayDiag::OnAdjustBuffer(wxCommandEvent& event)
|
||||
{
|
||||
const int val = ((wxSpinCtrl*)event.GetEventObject())->GetValue();
|
||||
((NetPlayServer*)netplay_ptr)->AdjustPadBufferSize(val);
|
||||
netplay_server->AdjustPadBufferSize(val);
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << "< Pad Buffer: " << val << " >";
|
||||
netplay_ptr->SendChatMessage(ss.str());
|
||||
netplay_client->SendChatMessage(ss.str());
|
||||
m_chat_text->AppendText(StrToWxStr(ss.str()).Append(wxT('\n')));
|
||||
}
|
||||
|
||||
|
@ -479,7 +499,7 @@ void NetPlayDiag::OnThread(wxCommandEvent& event)
|
|||
// player list
|
||||
m_playerids.clear();
|
||||
std::string tmps;
|
||||
netplay_ptr->GetPlayerList(tmps, m_playerids);
|
||||
netplay_client->GetPlayerList(tmps, m_playerids);
|
||||
|
||||
const int selection = m_player_lbox->GetSelection();
|
||||
|
||||
|
@ -502,15 +522,13 @@ void NetPlayDiag::OnThread(wxCommandEvent& event)
|
|||
case NP_GUI_EVT_START_GAME :
|
||||
// client start game :/
|
||||
{
|
||||
wxCommandEvent evt;
|
||||
OnStart(evt);
|
||||
netplay_client->StartGame(FindGame());
|
||||
}
|
||||
break;
|
||||
case NP_GUI_EVT_STOP_GAME :
|
||||
// client stop game
|
||||
{
|
||||
wxCommandEvent evt;
|
||||
OnStop(evt);
|
||||
netplay_client->StopGame();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -534,7 +552,7 @@ void NetPlayDiag::OnChangeGame(wxCommandEvent&)
|
|||
if (game_name.length())
|
||||
{
|
||||
m_selected_game = WxStrToStr(game_name);
|
||||
netplay_ptr->ChangeGame(m_selected_game);
|
||||
netplay_server->ChangeGame(m_selected_game);
|
||||
m_game_btn->SetLabel(game_name.Prepend(_(" Game : ")));
|
||||
}
|
||||
}
|
||||
|
@ -549,13 +567,13 @@ void NetPlayDiag::OnConfigPads(wxCommandEvent&)
|
|||
return;
|
||||
pid = m_playerids.at(pid);
|
||||
|
||||
if (false == ((NetPlayServer*)netplay_ptr)->GetPadMapping(pid, mapping))
|
||||
if (false == netplay_server->GetPadMapping(pid, mapping))
|
||||
return;
|
||||
|
||||
PadMapDiag pmd(this, mapping);
|
||||
pmd.ShowModal();
|
||||
|
||||
if (false == ((NetPlayServer*)netplay_ptr)->SetPadMapping(pid, mapping))
|
||||
if (false == netplay_server->SetPadMapping(pid, mapping))
|
||||
PanicAlertT("Could not set pads. The player left or the game is currently running!\n"
|
||||
"(setting pads while the game is running is not yet supported)");
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@ private:
|
|||
void OnHost(wxCommandEvent& event);
|
||||
void OnQuit(wxCommandEvent& event);
|
||||
|
||||
void MakeNetPlayDiag(int port, const std::string &game, bool is_hosting);
|
||||
|
||||
wxTextCtrl *m_nickname_text,
|
||||
*m_host_port_text,
|
||||
*m_connect_port_text,
|
||||
|
@ -85,11 +87,12 @@ private:
|
|||
|
||||
void OnChat(wxCommandEvent& event);
|
||||
void OnQuit(wxCommandEvent& event);
|
||||
void OnMemcardWriteCheck(wxCommandEvent& event);
|
||||
void OnThread(wxCommandEvent& event);
|
||||
void OnChangeGame(wxCommandEvent& event);
|
||||
void OnAdjustBuffer(wxCommandEvent& event);
|
||||
void OnConfigPads(wxCommandEvent& event);
|
||||
void GetNetSettings(NetSettings &settings);
|
||||
const std::string& FindGame();
|
||||
|
||||
wxListBox* m_player_lbox;
|
||||
wxTextCtrl* m_chat_text;
|
||||
|
|
Loading…
Reference in New Issue