Last active
December 11, 2019 19:46
-
-
Save Hopson97/fd82a1dc6edb7c2b2f3dfde8b79ca344 to your computer and use it in GitHub Desktop.
Playing around with enet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SFML/Graphics.hpp> | |
#include <thread> | |
#include <array> | |
#include <iostream> | |
#include <SFML/Network/Packet.hpp> | |
#define _WINSOCK_DEPRECATED_NO_WARNINGS | |
#define ENET_IMPLEMENTATION | |
#include "enet.h" | |
enum class ClientCommand : uint8_t | |
{ | |
ConnectionAccept, | |
PlayerJoin, | |
PlayerLeave, | |
}; | |
sf::Packet createPacket(ClientCommand command) | |
{ | |
sf::Packet packet; | |
packet << (uint8_t)command; | |
return packet; | |
} | |
ENetPacket* toEnetPacket(const sf::Packet& packet) | |
{ | |
ENetPacket* p = enet_packet_create(packet.getData(), packet.getDataSize(), ENET_PACKET_FLAG_RELIABLE); | |
return p; | |
} | |
void sendPacket(const sf::Packet& packet, ENetPeer* peer, int channel) | |
{ | |
std::cout << "Sending packet to " << peer->connectID << std::endl; | |
ENetPacket* raw = toEnetPacket(packet); | |
enet_peer_send(peer, 0, raw); | |
enet_packet_destroy(raw); | |
} | |
void runClient() | |
{ | |
ENetHost* client = enet_host_create(nullptr, 1, 2, 0, 0); | |
ENetAddress address{ 0 }; | |
enet_address_set_host(&address, "127.0.0.1"); | |
address.port = 12345; | |
ENetPeer* peer = enet_host_connect(client, &address, 2, 0); | |
sf::RenderWindow window(sf::VideoMode(512, 512), "SFML works!"); | |
window.setFramerateLimit(60); | |
sf::RectangleShape shape; | |
shape.setSize({ 64, 64 }); | |
uint8_t m_id = 0; | |
while (window.isOpen()) | |
{ | |
sf::Event event; | |
while (window.pollEvent(event)) | |
{ | |
if (event.type == sf::Event::Closed) | |
window.close(); | |
} | |
ENetEvent e; | |
while (enet_host_service(client, &e, 1) > 0) { | |
switch (e.type) | |
{ | |
case ENET_EVENT_TYPE_RECEIVE: { | |
uint8_t command = 0; | |
uint8_t id = 0; | |
sf::Packet packet; | |
packet.append(e.packet->data, e.packet->dataLength); | |
packet >> command >> id; | |
std::cout << "Command: " << (int)command << " | ID: " << (int)id << std::endl; | |
switch ((ClientCommand)command) { | |
case ClientCommand::PlayerJoin: { | |
std::cout << "Peer has joined: " << (int)id << std::endl; | |
}break; | |
case ClientCommand::PlayerLeave: { | |
std::cout << "Peer has left: " << (int)id << std::endl; | |
}break; | |
case ClientCommand::ConnectionAccept: { | |
m_id = id; | |
std::cout << "I have ID: " << (int)m_id << std::endl; | |
} break; | |
} | |
/* Clean up the packet now that we're done using it. */ | |
enet_packet_destroy(e.packet); | |
}break; | |
case ENET_EVENT_TYPE_CONNECT: | |
std::cout << "Client joined from " << e.peer->address.port << '\n'; | |
break; | |
case ENET_EVENT_TYPE_DISCONNECT: | |
std::cout << "Client disconnected from " << e.peer->address.port << '\n'; | |
break; | |
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT: | |
printf("%s disconnected due to timeout.\n", e.peer->data); | |
/* Reset the peer's client information. */ | |
e.peer->data = NULL; | |
break; | |
} | |
} | |
if (window.hasFocus()) { | |
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) { | |
shape.move(-10, 0); | |
} | |
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) { | |
shape.move(10, 0); | |
} | |
} | |
window.clear(); | |
window.draw(shape); | |
window.display(); | |
} | |
enet_peer_disconnect(peer, 0); | |
ENetEvent network_event; | |
while (enet_host_service(client, &network_event, 3000) > 0) | |
{ | |
switch (network_event.type) | |
{ | |
case ENET_EVENT_TYPE_RECEIVE: | |
enet_packet_destroy(network_event.packet); | |
break; | |
case ENET_EVENT_TYPE_DISCONNECT: | |
break; | |
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT: | |
break; | |
default: | |
break; | |
} | |
} | |
enet_peer_reset(peer); | |
enet_host_destroy(client); | |
} | |
void runServer() | |
{ | |
ENetAddress address{ 0 }; | |
enet_address_set_host(&address, "127.0.0.1"); | |
address.port = 12345; | |
ENetHost* host = enet_host_create(&address, 4, 2, 0, 0); | |
std::array<ENetPeer*, 4> peers{ nullptr }; | |
int connections = 0; | |
auto findSlot = [&peers]() { | |
for (int i = 0; i < 4; i++) { | |
if (!peers[i]) { | |
return i; | |
} | |
} | |
return -1; | |
}; | |
auto broadcast = [&peers](const sf::Packet& packet) | |
{ | |
for (int i = 0; i < 4; i++) { | |
if (peers[i]) { | |
sendPacket(packet, peers[i], 0); | |
} | |
} | |
}; | |
bool running = true; | |
while (running) { | |
ENetEvent e; | |
while (enet_host_service(host, &e, 512) > 0) { | |
switch (e.type) | |
{ | |
case ENET_EVENT_TYPE_RECEIVE: | |
/* Clean up the packet now that we're done using it. */ | |
enet_packet_destroy(e.packet); | |
break; | |
case ENET_EVENT_TYPE_CONNECT: { | |
uint8_t slot = findSlot(); | |
peers[slot] = e.peer; | |
std::cout << "Connection received\nSlot : " << (int)slot << std::endl; | |
sf::Packet packet; | |
packet << slot; | |
ENetPacket* pack = enet_packet_create(packet.getData(), packet.getDataSize(), ENET_PACKET_FLAG_RELIABLE); | |
enet_peer_send(e.peer, 0, pack); | |
enet_host_flush(host); | |
enet_packet_destroy(pack); | |
auto joinPacket = createPacket(ClientCommand::PlayerJoin); | |
joinPacket << slot; | |
for (int i = 0; i < 4; i++) { | |
if (peers[i]) { | |
ENetPacket* pack = enet_packet_create(joinPacket.getData(), joinPacket.getDataSize(), ENET_PACKET_FLAG_RELIABLE); | |
enet_peer_send(peers[i], 0, pack); | |
enet_host_flush(host); | |
enet_packet_destroy(pack); | |
} | |
} | |
}break; | |
case ENET_EVENT_TYPE_DISCONNECT: | |
std::cout << "Client disconnected from " << e.peer->address.port << '\n'; | |
break; | |
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT: | |
std::cout << "Client timeout from " << e.peer->data << '\n'; | |
/* Reset the peer's client information. */ | |
e.peer->data = NULL; | |
break; | |
} | |
} | |
std::cout << "Nope\n"; | |
} | |
enet_host_destroy(host); | |
} | |
void runBoth() | |
{ | |
std::thread t([]() { | |
runServer(); | |
}); | |
runClient(); | |
t.join(); | |
} | |
int main() | |
{ | |
if (enet_initialize() != 0) { | |
std::cout << "ENET has failed to initialize!\n"; | |
return 0; | |
} | |
char option; | |
std::cin >> option; | |
switch (option) | |
{ | |
case 's': | |
runServer(); | |
break; | |
case 'c': | |
runClient(); | |
break; | |
default: | |
break; | |
} | |
enet_deinitialize(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment