generated from Persson-dev/Godot-Xmake
129 lines
4.0 KiB
C++
129 lines
4.0 KiB
C++
#include <blitz/godot/NetworkInterface.h>
|
|
|
|
#include <blitz/protocol/PacketFactory.h>
|
|
#include <blitz/protocol/PacketSerializer.h>
|
|
#include <godot_cpp/classes/e_net_multiplayer_peer.hpp>
|
|
#include <godot_cpp/classes/multiplayer_api.hpp>
|
|
#include <godot_cpp/classes/packed_scene.hpp>
|
|
#include <godot_cpp/classes/resource_loader.hpp>
|
|
#include <godot_cpp/variant/utility_functions.hpp>
|
|
|
|
namespace blitz {
|
|
|
|
static const char ServerScenePath[] = "res://Scenes/Network/server.tscn";
|
|
|
|
using namespace godot;
|
|
|
|
void NetworkInterface::_bind_methods() {
|
|
ClassDB::bind_method(D_METHOD("RecievePacketDataReliable", "a_PacketData"), &NetworkInterface::RecievePacketDataReliable);
|
|
|
|
// server
|
|
ADD_SIGNAL(MethodInfo("player_connected", PropertyInfo(Variant::INT, "peer_id")));
|
|
ADD_SIGNAL(MethodInfo("player_disconnected", PropertyInfo(Variant::INT, "peer_id")));
|
|
|
|
// client
|
|
ADD_SIGNAL(MethodInfo("server_disconnected"));
|
|
ADD_SIGNAL(MethodInfo("local_player_connected"));
|
|
|
|
protocol::PacketFactory::Init();
|
|
}
|
|
|
|
NetworkInterface::NetworkInterface() {}
|
|
|
|
NetworkInterface::~NetworkInterface() {}
|
|
|
|
void NetworkInterface::_ready() {
|
|
// TODO: unreliable
|
|
Dictionary config;
|
|
config["rpc_mode"] = MultiplayerAPI::RPC_MODE_ANY_PEER;
|
|
config["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_RELIABLE;
|
|
config["call_local"] = true;
|
|
config["channel"] = 0;
|
|
rpc_config("RecievePacketDataReliable", config);
|
|
|
|
get_multiplayer()->connect("peer_connected", callable_mp(this, &NetworkInterface::OnPlayerConnected));
|
|
get_multiplayer()->connect("peer_disconnected", callable_mp(this, &NetworkInterface::OnPlayerDisconnected));
|
|
get_multiplayer()->connect("connected_to_server", callable_mp(this, &NetworkInterface::OnConnectOk));
|
|
get_multiplayer()->connect("connection_failed", callable_mp(this, &NetworkInterface::OnConnectFail));
|
|
get_multiplayer()->connect("server_disconnected", callable_mp(this, &NetworkInterface::OnServerDisconnected));
|
|
}
|
|
|
|
void NetworkInterface::BroadcastPacket(const protocol::Packet& a_Packet) {
|
|
PackedByteArray byteArray = protocol::PacketSerializer::Serialize(a_Packet);
|
|
rpc("RecievePacketDataReliable", byteArray);
|
|
}
|
|
|
|
void NetworkInterface::SendPacket(PeerID a_Peer, const protocol::Packet& a_Packet) {
|
|
PackedByteArray byteArray = protocol::PacketSerializer::Serialize(a_Packet);
|
|
rpc_id(a_Peer, "RecievePacketDataReliable", byteArray);
|
|
}
|
|
|
|
void NetworkInterface::RecievePacketDataReliable(godot::PackedByteArray a_PacketData) {
|
|
auto packet = protocol::PacketSerializer::Deserialize(a_PacketData);
|
|
if (packet) {
|
|
packet->m_Sender = get_multiplayer()->get_remote_sender_id();
|
|
Dispatch(*packet);
|
|
}
|
|
}
|
|
|
|
Error NetworkInterface::JoinGame(const String& a_Address, uint16_t a_Port) {
|
|
auto* peer = memnew(ENetMultiplayerPeer);
|
|
Error error = peer->create_client(a_Address, a_Port);
|
|
if (error) {
|
|
OnConnectFail();
|
|
return error;
|
|
}
|
|
|
|
get_multiplayer()->set_multiplayer_peer(peer);
|
|
return Error::OK;
|
|
}
|
|
|
|
Error NetworkInterface::CreateGame(uint16_t a_Port, bool a_Dedicated) {
|
|
auto* peer = memnew(ENetMultiplayerPeer);
|
|
Error error = peer->create_server(a_Port);
|
|
if (error)
|
|
return error;
|
|
|
|
get_multiplayer()->set_multiplayer_peer(peer);
|
|
|
|
Ref<PackedScene> serverScene = ResourceLoader::get_singleton()->load(ServerScenePath);
|
|
add_child(serverScene->instantiate());
|
|
|
|
if (!a_Dedicated) {
|
|
emit_signal("local_player_connected");
|
|
emit_signal("player_connected", get_multiplayer()->get_unique_id());
|
|
}
|
|
|
|
return Error::OK;
|
|
}
|
|
|
|
void NetworkInterface::OnPlayerConnected(PeerID a_PeerId) {
|
|
emit_signal("player_connected", a_PeerId);
|
|
}
|
|
|
|
void NetworkInterface::OnPlayerDisconnected(PeerID a_PeerId) {
|
|
emit_signal("player_disconnected", a_PeerId);
|
|
}
|
|
|
|
void NetworkInterface::OnConnectOk() {
|
|
emit_signal("local_player_connected");
|
|
}
|
|
|
|
void NetworkInterface::OnConnectFail() {
|
|
ShutdownNetwork();
|
|
emit_signal("server_disconnected");
|
|
}
|
|
|
|
void NetworkInterface::OnServerDisconnected() {
|
|
ShutdownNetwork();
|
|
emit_signal("server_disconnected");
|
|
}
|
|
|
|
void NetworkInterface::ShutdownNetwork() {
|
|
get_multiplayer()->set_multiplayer_peer(nullptr);
|
|
if (auto* server = find_child("Server")) {
|
|
server->queue_free();
|
|
}
|
|
}
|
|
|
|
} // namespace blitz
|