Character.hpp
#ifndef Character_hpp
#define Character_hpp
#include <iostream>
#include <SFML/Graphics.hpp>
class Character {
public:
std::string name;
int lvl;
int money;
int positionX;
int positionY;
sf::Color color;
sf::RectangleShape view();
};
#endif /* Character_hpp */
Character.cpp
#include "Character.hpp"
sf::RectangleShape Character::view()
{
sf::RectangleShape rectangle;
rectangle.setSize(sf::Vector2f(40, 40));
rectangle.setPosition(sf::Vector2f(positionX, positionY));
return rectangle;
}
server.cpp
#include <SFML/Network.hpp>
#include <iostream>
#include <vector>
#include "Character.hpp"
sf::Packet& operator <<(sf::Packet& packet, const Character& character)
{
return packet << character.name << character.lvl << character.money << character.positionX << character.positionY << character.color.r << character.color.g << character.color.b;
}
sf::Packet& operator >>(sf::Packet& packet, Character& character)
{
return packet >> character.name >> character.lvl >> character.money >> character.positionX >> character.positionY >> character.color.r >> character.color.g >> character.color.b;
}
int main(int argc, char const** argv)
{
unsigned short port = 9080;
sf::TcpListener listener;
sf::SocketSelector selector;
bool done = false;
std::map<std::string, sf::TcpSocket*> clients;
std::map<std::string, Character*> persos;
std::cout << "Server is running : " << sf::IpAddress::getPublicAddress() << ":" << port << " ..." << std::endl;
listener.listen(port);
selector.add(listener);
while (!done)
{
if (selector.wait())
{
if (selector.isReady(listener))
{
sf::TcpSocket *socket = new sf::TcpSocket;
listener.accept(*socket);
sf::Packet packet;
if (socket->receive(packet) == sf::Socket::Done)
{
Character perso;
packet >> perso;
std::cout << "Connected Client: (Name: " << perso.name << ", Level: " << perso.lvl << ", Money: " << perso.money << ", Position: (X: " << perso.positionX << ", Y: " << perso.positionY << ")). From: " << socket->getRemoteAddress() << std::endl;
// show the new connected client on all clients
std::map<std::string, sf::TcpSocket*>::iterator it;
for (it = clients.begin(); it != clients.end(); it++)
it->second->send(packet);
// show all conected clients on the new client
std::map<std::string, Character*>::iterator it2;
for (it2 = persos.begin(); it2 != persos.end(); it2++)
{
sf::Packet packet;
packet << it2->second;
socket->send(packet);
}
// add the new client to the lists
persos[perso.name] = &perso;
clients[perso.name] = socket;
selector.add(*socket);
}
}
else
{
std::map<std::string, sf::TcpSocket*>::iterator it;
for (it = clients.begin(); it != clients.end(); ++it)
{
sf::TcpSocket& client = *it->second;
if (selector.isReady(client))
{
sf::Packet packet, sendPacket;
if (client.receive(packet) == sf::Socket::Done)
{
Character perso;
packet >> perso;
std::cout << "Updated Client: (Name: " << perso.name << ", Level: " << perso.lvl << ", Money: " << perso.money << ", Position: (X: " << perso.positionX << ", Y: " << perso.positionY << ")). From: " << client.getRemoteAddress() << std::endl;
persos[perso.name] = &perso;
sendPacket << perso;
std::map<std::string, sf::TcpSocket*>::iterator it2;
for (it2 = clients.begin(); it2 != clients.end(); it2++)
{
if (it != it2)
it2->second->send(sendPacket);
}
}
else if (client.receive(packet) == sf::Socket::Disconnected)
{
std::string name = it->first;
std::cout << "Client (" << name << ") disconnected." << std::endl;
std::cout << "List size: " << clients.size();
selector.remove(client);
client.disconnect();
delete(&client);
clients.erase(it);
it--;
std::cout << " then: " << clients.size() << std::endl;
persos.erase(name);
}
}
}
}
}
}
std::map<std::string, sf::TcpSocket*>::iterator it;
for (it = clients.begin(); it != clients.end(); it++)
delete it->second;
return EXIT_SUCCESS;
}
client.cpp
#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Network.hpp>
#include "ResourcePath.hpp"
#include "Character.hpp"
#include "MyPacket.hpp"
sf::Packet& operator <<(sf::Packet& packet, const Character& character)
{
return packet << character.name << character.lvl << character.money << character.positionX << character.positionY;
}
sf::Packet& operator >>(sf::Packet& packet, Character& character)
{
return packet >> character.name >> character.lvl >> character.money >> character.positionX >> character.positionY;
}
char genRandom()
{
const char alphanum[] =
"0123456789"
"!@#$%^&*"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
int stringLength = sizeof(alphanum) - 1;
return alphanum[rand() % stringLength];
}
std::string generator(int length)
{
std::string str;
for(unsigned int i = 0; i < length; ++i)
str += genRandom();
return str;
}
int main(int, char const**)
{
srand(time(0));
sf::IpAddress ip = sf::IpAddress().getLocalAddress();
unsigned short port = 9080;
std::string publicIp = ip.toString();
sf::TcpSocket socket;
bool done = false;
std::string id;
id = generator(8);
Character me;
me.name = id;
me.color = sf::Color(rand() % 256, rand() % 256, rand() % 256);
me.lvl = 1;
me.money = 1000;
me.positionX = rand() % 700 + 5;
me.positionY = rand() % 500 + 5;
socket.connect(ip, port);
sf::RenderWindow window(sf::VideoMode(800, 600), "Game", sf::Style::Titlebar | sf::Style::Close);
sf::Image icon;
if (!icon.loadFromFile(resourcePath() + "icon.png"))
return EXIT_FAILURE;
window.setIcon(icon.getSize().x, icon.getSize().y, icon.getPixelsPtr());
std::map<std::string, Character> persos;
sf::Packet packet;
packet << me;
socket.send(packet);
socket.setBlocking(false);
window.setTitle(id);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
socket.disconnect();
window.close();
break;
case sf::Event::KeyPressed:
{
if (event.key.code == sf::Keyboard::Escape)
{
socket.disconnect();
window.close();
}
else if (event.key.code == sf::Keyboard::Up)
me.positionY -= 5;
else if (event.key.code == sf::Keyboard::Down)
me.positionY += 5;
else if (event.key.code == sf::Keyboard::Left)
me.positionX -= 5;
else if (event.key.code == sf::Keyboard::Right)
me.positionX += 5;
sf::Packet packet;
packet << me;
socket.send(packet);
sf::RectangleShape rect = me.view();
rect.setFillColor(me.color);
window.draw(rect);
break;
}
default:
break;
}
}
sf::Packet packet;
socket.receive(packet);
Character tmpChar;
if (packet >> tmpChar)
persos[tmpChar.name] = tmpChar;
std::map<std::string, Character>::iterator it;
for (it = persos.begin(); it != persos.end(); it++)
{
sf::RectangleShape rect = it->second.view();
rect.setFillColor(it->second.color);
window.draw(rect);
}
sf::RectangleShape rect = me.view();
rect.setFillColor(sf::Color::Red);
window.draw(rect);
window.display();
window.clear(sf::Color::White);
}
return EXIT_SUCCESS;
}