2015-05-24 04:55:12 +00:00
|
|
|
// Copyright 2010 Dolphin Emulator Project
|
2015-05-17 23:08:10 +00:00
|
|
|
// Licensed under GPLv2+
|
2013-04-18 02:43:11 +00:00
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
2014-02-10 18:54:46 +00:00
|
|
|
#pragma once
|
2010-05-01 19:10:35 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
#include <SFML/Network/Packet.hpp>
|
2016-01-25 04:26:38 +00:00
|
|
|
#include <array>
|
2010-05-01 19:10:35 +00:00
|
|
|
#include <map>
|
2018-07-04 21:01:50 +00:00
|
|
|
#include <memory>
|
2015-05-26 21:23:43 +00:00
|
|
|
#include <mutex>
|
2018-07-04 21:01:50 +00:00
|
|
|
#include <optional>
|
2016-01-25 02:46:46 +00:00
|
|
|
#include <string>
|
2015-05-26 21:23:43 +00:00
|
|
|
#include <thread>
|
2016-01-25 02:46:46 +00:00
|
|
|
#include <vector>
|
2018-07-04 21:01:50 +00:00
|
|
|
|
2014-02-17 10:18:15 +00:00
|
|
|
#include "Common/CommonTypes.h"
|
2016-07-24 22:40:15 +00:00
|
|
|
#include "Common/Event.h"
|
2017-08-23 23:45:42 +00:00
|
|
|
#include "Common/SPSCQueue.h"
|
2015-02-02 09:56:53 +00:00
|
|
|
#include "Common/TraversalClient.h"
|
2014-02-17 10:18:15 +00:00
|
|
|
#include "Core/NetPlayProto.h"
|
|
|
|
#include "InputCommon/GCPadStatus.h"
|
2015-02-02 10:08:58 +00:00
|
|
|
|
2018-07-04 21:01:50 +00:00
|
|
|
namespace UICommon
|
|
|
|
{
|
|
|
|
class GameFile;
|
|
|
|
}
|
|
|
|
|
2018-07-06 23:39:42 +00:00
|
|
|
namespace NetPlay
|
|
|
|
{
|
2011-02-08 15:36:15 +00:00
|
|
|
class NetPlayUI
|
|
|
|
{
|
|
|
|
public:
|
2016-06-24 08:43:46 +00:00
|
|
|
virtual ~NetPlayUI() {}
|
|
|
|
virtual void BootGame(const std::string& filename) = 0;
|
|
|
|
virtual void StopGame() = 0;
|
2018-07-04 21:01:50 +00:00
|
|
|
virtual bool IsHosting() const = 0;
|
2011-02-18 23:52:14 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
virtual void Update() = 0;
|
|
|
|
virtual void AppendChat(const std::string& msg) = 0;
|
2011-02-08 15:36:15 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
virtual void OnMsgChangeGame(const std::string& filename) = 0;
|
|
|
|
virtual void OnMsgStartGame() = 0;
|
|
|
|
virtual void OnMsgStopGame() = 0;
|
2016-02-02 15:35:27 +00:00
|
|
|
virtual void OnPadBufferChanged(u32 buffer) = 0;
|
|
|
|
virtual void OnDesync(u32 frame, const std::string& player) = 0;
|
|
|
|
virtual void OnConnectionLost() = 0;
|
2018-07-02 02:52:43 +00:00
|
|
|
virtual void OnConnectionError(const std::string& message) = 0;
|
2017-08-08 22:29:47 +00:00
|
|
|
virtual void OnTraversalError(TraversalClient::FailureReason error) = 0;
|
2018-07-20 22:27:43 +00:00
|
|
|
virtual void OnTraversalStateChanged(TraversalClient::State state) = 0;
|
2018-07-04 21:01:50 +00:00
|
|
|
virtual void OnSaveDataSyncFailure() = 0;
|
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
virtual bool IsRecording() = 0;
|
2016-07-10 08:13:34 +00:00
|
|
|
virtual std::string FindGame(const std::string& game) = 0;
|
2018-07-04 21:01:50 +00:00
|
|
|
virtual std::shared_ptr<const UICommon::GameFile> FindGameFile(const std::string& game) = 0;
|
2016-07-13 22:45:38 +00:00
|
|
|
virtual void ShowMD5Dialog(const std::string& file_identifier) = 0;
|
|
|
|
virtual void SetMD5Progress(int pid, int progress) = 0;
|
|
|
|
virtual void SetMD5Result(int pid, const std::string& result) = 0;
|
|
|
|
virtual void AbortMD5() = 0;
|
2016-07-10 08:13:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
enum class PlayerGameStatus
|
|
|
|
{
|
|
|
|
Unknown,
|
|
|
|
Ok,
|
|
|
|
NotFound
|
2011-02-08 15:36:15 +00:00
|
|
|
};
|
|
|
|
|
2013-08-18 13:43:01 +00:00
|
|
|
class Player
|
|
|
|
{
|
2015-02-02 09:27:06 +00:00
|
|
|
public:
|
2016-06-24 08:43:46 +00:00
|
|
|
PlayerId pid;
|
|
|
|
std::string name;
|
|
|
|
std::string revision;
|
|
|
|
u32 ping;
|
2016-07-10 08:13:34 +00:00
|
|
|
PlayerGameStatus game_status;
|
2013-08-18 13:43:01 +00:00
|
|
|
};
|
|
|
|
|
2015-02-02 09:56:53 +00:00
|
|
|
class NetPlayClient : public TraversalClientClient
|
2010-05-01 19:10:35 +00:00
|
|
|
{
|
|
|
|
public:
|
2016-06-24 08:43:46 +00:00
|
|
|
void ThreadFunc();
|
2017-02-10 00:58:27 +00:00
|
|
|
void SendAsync(sf::Packet&& packet);
|
2013-08-05 08:56:30 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
NetPlayClient(const std::string& address, const u16 port, NetPlayUI* dialog,
|
2017-08-07 07:22:33 +00:00
|
|
|
const std::string& name, const NetTraversalConfig& traversal_config);
|
2016-06-24 08:43:46 +00:00
|
|
|
~NetPlayClient();
|
2010-05-01 19:10:35 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
void GetPlayerList(std::string& list, std::vector<int>& pid_list);
|
|
|
|
std::vector<const Player*> GetPlayers();
|
2018-07-09 19:52:31 +00:00
|
|
|
const NetSettings& GetNetSettings() const;
|
2013-08-05 08:56:30 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
// Called from the GUI thread.
|
|
|
|
bool IsConnected() const { return m_is_connected; }
|
|
|
|
bool StartGame(const std::string& path);
|
|
|
|
bool StopGame();
|
|
|
|
void Stop();
|
|
|
|
bool ChangeGame(const std::string& game);
|
|
|
|
void SendChatMessage(const std::string& msg);
|
2018-07-03 23:02:13 +00:00
|
|
|
void RequestStopGame();
|
2013-08-05 08:56:30 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
// Send and receive pads values
|
2016-08-14 13:51:29 +00:00
|
|
|
bool WiimoteUpdate(int _number, u8* data, const u8 size, u8 reporting_mode);
|
2016-10-07 11:49:32 +00:00
|
|
|
bool GetNetPads(int pad_nb, GCPadStatus* pad_status);
|
2010-05-01 19:10:35 +00:00
|
|
|
|
2018-07-14 22:55:17 +00:00
|
|
|
u64 GetInitialRTCValue() const;
|
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
void OnTraversalStateChanged() override;
|
|
|
|
void OnConnectReady(ENetAddress addr) override;
|
|
|
|
void OnConnectFailed(u8 reason) override;
|
2015-02-02 09:56:53 +00:00
|
|
|
|
2016-10-07 11:49:32 +00:00
|
|
|
bool IsFirstInGamePad(int ingame_pad) const;
|
|
|
|
int NumLocalPads() const;
|
2016-05-08 13:29:01 +00:00
|
|
|
|
2017-03-19 13:07:33 +00:00
|
|
|
int InGamePadToLocalPad(int ingame_pad) const;
|
|
|
|
int LocalPadToInGamePad(int localPad) const;
|
2010-05-05 04:31:21 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
static void SendTimeBase();
|
2016-07-10 08:13:34 +00:00
|
|
|
bool DoAllPlayersHaveGame();
|
2015-03-08 10:50:47 +00:00
|
|
|
|
2018-05-12 13:13:30 +00:00
|
|
|
const PadMappingArray& GetPadMapping() const;
|
|
|
|
const PadMappingArray& GetWiimoteMapping() const;
|
|
|
|
|
2010-05-01 19:10:35 +00:00
|
|
|
protected:
|
2016-06-24 08:43:46 +00:00
|
|
|
void ClearBuffers();
|
2010-05-01 19:10:35 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
std::recursive_mutex game;
|
|
|
|
// lock order
|
|
|
|
std::recursive_mutex players;
|
|
|
|
std::recursive_mutex async_queue_write;
|
|
|
|
} m_crit;
|
2010-05-01 19:10:35 +00:00
|
|
|
|
2017-08-23 23:45:42 +00:00
|
|
|
Common::SPSCQueue<sf::Packet, false> m_async_queue;
|
2015-03-09 16:31:13 +00:00
|
|
|
|
2017-08-23 23:45:42 +00:00
|
|
|
std::array<Common::SPSCQueue<GCPadStatus>, 4> m_pad_buffer;
|
|
|
|
std::array<Common::SPSCQueue<NetWiimote>, 4> m_wiimote_buffer;
|
2010-05-05 04:31:21 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
NetPlayUI* m_dialog = nullptr;
|
2015-02-02 09:27:06 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
ENetHost* m_client = nullptr;
|
|
|
|
ENetPeer* m_server = nullptr;
|
|
|
|
std::thread m_thread;
|
2010-05-01 19:10:35 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
std::string m_selected_game;
|
2016-08-05 14:04:39 +00:00
|
|
|
Common::Flag m_is_running{false};
|
|
|
|
Common::Flag m_do_loop{true};
|
2010-05-01 19:10:35 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
unsigned int m_target_buffer_size = 20;
|
2010-05-05 04:31:21 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
Player* m_local_player = nullptr;
|
2010-05-05 04:31:21 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
u32 m_current_game = 0;
|
2010-05-01 19:10:35 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
PadMappingArray m_pad_map;
|
|
|
|
PadMappingArray m_wiimote_map;
|
2013-08-18 13:43:01 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
bool m_is_recording = false;
|
2013-09-03 19:50:41 +00:00
|
|
|
|
2010-05-01 19:10:35 +00:00
|
|
|
private:
|
2016-06-24 08:43:46 +00:00
|
|
|
enum class ConnectionState
|
|
|
|
{
|
|
|
|
WaitingForTraversalClientConnection,
|
|
|
|
WaitingForTraversalClientConnectReady,
|
|
|
|
Connecting,
|
|
|
|
WaitingForHelloResponse,
|
|
|
|
Connected,
|
|
|
|
Failure
|
|
|
|
};
|
|
|
|
|
|
|
|
bool LocalPlayerHasControllerMapped() const;
|
|
|
|
|
|
|
|
void SendStartGamePacket();
|
|
|
|
void SendStopGamePacket();
|
|
|
|
|
2018-07-04 21:01:50 +00:00
|
|
|
void SyncSaveDataResponse(bool success);
|
|
|
|
bool DecompressPacketIntoFile(sf::Packet& packet, const std::string& file_path);
|
|
|
|
std::optional<std::vector<u8>> DecompressPacketIntoBuffer(sf::Packet& packet);
|
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
void UpdateDevices();
|
2018-07-09 20:45:52 +00:00
|
|
|
void AddPadStateToPacket(int in_game_pad, const GCPadStatus& np, sf::Packet& packet);
|
2016-10-07 11:49:32 +00:00
|
|
|
void SendWiimoteState(int in_game_pad, const NetWiimote& nw);
|
2016-06-24 08:43:46 +00:00
|
|
|
unsigned int OnData(sf::Packet& packet);
|
2017-03-19 13:07:33 +00:00
|
|
|
void Send(const sf::Packet& packet);
|
2016-06-24 08:43:46 +00:00
|
|
|
void Disconnect();
|
|
|
|
bool Connect();
|
2016-07-13 22:45:38 +00:00
|
|
|
void ComputeMD5(const std::string& file_identifier);
|
2016-02-02 15:35:27 +00:00
|
|
|
void DisplayPlayersPing();
|
|
|
|
u32 GetPlayersMaxPing() const;
|
2016-06-24 08:43:46 +00:00
|
|
|
|
|
|
|
bool m_is_connected = false;
|
|
|
|
ConnectionState m_connection_state = ConnectionState::Failure;
|
|
|
|
|
|
|
|
PlayerId m_pid = 0;
|
2018-07-09 19:52:31 +00:00
|
|
|
NetSettings m_net_settings{};
|
2016-06-24 08:43:46 +00:00
|
|
|
std::map<PlayerId, Player> m_players;
|
|
|
|
std::string m_host_spec;
|
|
|
|
std::string m_player_name;
|
|
|
|
bool m_connecting = false;
|
|
|
|
TraversalClient* m_traversal_client = nullptr;
|
2016-07-13 22:45:38 +00:00
|
|
|
std::thread m_MD5_thread;
|
|
|
|
bool m_should_compute_MD5 = false;
|
2016-07-24 22:40:15 +00:00
|
|
|
Common::Event m_gc_pad_event;
|
|
|
|
Common::Event m_wii_pad_event;
|
2018-07-04 21:01:50 +00:00
|
|
|
u8 m_sync_save_data_count = 0;
|
|
|
|
u8 m_sync_save_data_success_count = 0;
|
2016-06-24 08:43:46 +00:00
|
|
|
|
2018-07-14 22:55:17 +00:00
|
|
|
u64 m_initial_rtc = 0;
|
2016-06-24 08:43:46 +00:00
|
|
|
u32 m_timebase_frame = 0;
|
2010-05-01 19:10:35 +00:00
|
|
|
};
|
|
|
|
|
2013-08-05 08:56:30 +00:00
|
|
|
void NetPlay_Enable(NetPlayClient* const np);
|
|
|
|
void NetPlay_Disable();
|
2018-07-06 23:39:42 +00:00
|
|
|
} // namespace NetPlay
|