Skip to content

Instantly share code, notes, and snippets.

@Hopson97
Last active December 11, 2019 19:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Hopson97/fd82a1dc6edb7c2b2f3dfde8b79ca344 to your computer and use it in GitHub Desktop.
Save Hopson97/fd82a1dc6edb7c2b2f3dfde8b79ca344 to your computer and use it in GitHub Desktop.
Playing around with enet
#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