-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'group_5' into development
- Loading branch information
Showing
10 changed files
with
687 additions
and
1 deletion.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/** | ||
* This file is part of the Fall 2023, CSE 491 course project. | ||
* @brief A networking interface that allows information to be sent across a network | ||
* @note Status: PROTOTYPE | ||
**/ | ||
|
||
#pragma once | ||
|
||
#include <cassert> | ||
#include <string> | ||
#include <vector> | ||
#include <array> | ||
#include <SFML/Network/UdpSocket.hpp> | ||
#include <SFML/Network/Packet.hpp> | ||
#include "../../core/InterfaceBase.hpp" | ||
|
||
namespace netWorth{ | ||
|
||
using namespace sf; | ||
/** | ||
* TODO: Delete or incorporate | ||
*/ | ||
class NetworkingInterface { | ||
private: | ||
|
||
protected: | ||
UdpSocket m_socket; ///The socket we are going to make our connection | ||
std::optional<IpAddress> m_ip; /// the local address of the machine | ||
unsigned short m_port; /// local port number of the machine | ||
//Thought about making m_clients a shared pointer to a vector, but it'll be a vector for now | ||
std::vector<std::string> m_clients; ///list of all the clients that will connect with the server | ||
|
||
public: | ||
NetworkingInterface() = default; | ||
~NetworkingInterface() = default; | ||
|
||
/** | ||
* Receives a socket that has been connected between client and server | ||
* @return the udp socket | ||
*/ | ||
UdpSocket * GetSocket(){ | ||
return &m_socket; | ||
} | ||
|
||
/** | ||
* Bind socket to port number | ||
* @param socket Socket to be bound | ||
* @param port Port number | ||
* @return true if successful | ||
*/ | ||
virtual bool BindSocket(UdpSocket &socket, unsigned short port) { | ||
if (socket.bind(port) != Socket::Status::Done) { | ||
std::cerr << "Failed to bind socket" << std::endl; | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* Sends a packet across the socket | ||
* @param packet the packet we want to send | ||
* @param destAddr the destination address we want to send to | ||
* @param port the port of the connection | ||
* @return true if successfully sent | ||
*/ | ||
virtual bool SendPacket(Packet packet, IpAddress destAddr, const unsigned short port){ | ||
if (m_socket.send(packet, destAddr, port) != Socket::Status::Done) { | ||
std::cerr << "Could not connect to" << destAddr << " at port " << port << std::endl; | ||
return false; | ||
} | ||
return true; | ||
} | ||
/** | ||
* Starts the connection by receiving the first packet | ||
* @param sender IP of sending machine | ||
* @param port port number of sending machine | ||
* @return received packet | ||
*/ | ||
virtual bool ReceivePacket(Packet & pkt, std::optional<IpAddress> &sender, unsigned short &port){ | ||
if (m_socket.receive(pkt, sender, port) != Socket::Status::Done) { | ||
std::cerr << "Failed to receive" << std::endl; | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* Processes the packet and outputs it | ||
* @param packet the packet we want to output | ||
*/ | ||
virtual void ProcessPacket(Packet packet){ | ||
std::string actionInd; | ||
packet >> actionInd; | ||
std::cout << actionInd; | ||
} | ||
}; | ||
}//End of namespace networth |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
/** | ||
* This file is part of the Fall 2023, CSE 491 course project. | ||
* @brief A networking interface that allows information to be sent across a network | ||
* @note Status: PROTOTYPE | ||
**/ | ||
|
||
#pragma once | ||
|
||
#include <cassert> | ||
#include <string> | ||
#include <vector> | ||
#include <SFML/Network/UdpSocket.hpp> | ||
#include <SFML/Network/Packet.hpp> | ||
#include <memory> | ||
|
||
#include "../NetworkInterface.hpp" | ||
#include "../../TrashInterface.hpp" | ||
|
||
namespace netWorth{ | ||
/** | ||
* The interface of our client that will be interacting and connection with our server | ||
*/ | ||
using namespace sf; | ||
|
||
class ClientInterface : public NetworkingInterface { | ||
private: | ||
std::optional<IpAddress> m_dest_ip; /// the destination address (server address) | ||
unsigned short m_dest_port; /// the destination port (server port) | ||
|
||
/** | ||
* Get user input to be sent to server | ||
* @return string corresponding to action | ||
*/ | ||
static std::string GameLoop_GetInput() { | ||
bool valid_input = false; | ||
std::string action; | ||
char input; | ||
|
||
while (!valid_input) { | ||
std::cin >> input; | ||
switch (input) { | ||
case 'w': case 'W': action = "up"; valid_input = true; break; | ||
case 'a': case 'A': action = "left"; valid_input = true; break; | ||
case 's': case 'S': action = "down"; valid_input = true; break; | ||
case 'd': case 'D': action = "right"; valid_input = true; break; | ||
case 'q': case 'Q': action = "quit"; valid_input = true; break; | ||
default: valid_input = false; | ||
} | ||
if (!valid_input) { | ||
std::cout << "Your move?"; | ||
} | ||
} | ||
|
||
return action; | ||
} | ||
|
||
protected: | ||
|
||
public: | ||
/** | ||
* ClientInterface constructor (NetworkingInterface superclass) | ||
* @param ip_string String for destination IP address, make into IpAddress object | ||
* @param port Destination port number | ||
*/ | ||
ClientInterface(const std::string & ip_string, | ||
unsigned short port) { | ||
m_dest_ip = IpAddress::resolve(ip_string); | ||
m_dest_port = port; | ||
} | ||
|
||
/** | ||
* Default destructor | ||
*/ | ||
~ClientInterface() = default; | ||
|
||
/** | ||
* Establish connection with server | ||
* @return True if successful, false if error | ||
*/ | ||
bool EstablishConnection() { | ||
Packet send_pkt, recv_pkt; | ||
|
||
// send request message | ||
send_pkt << "New client requesting connection."; | ||
if (!SendPacket(send_pkt, m_dest_ip.value(), m_dest_port)) return false; | ||
|
||
// receive from server | ||
if (!ReceivePacket(recv_pkt, m_dest_ip, m_dest_port)) return false; | ||
|
||
// print received string (Connection established.) | ||
std::string str; | ||
recv_pkt >> str; | ||
std::cout << str << std::endl; | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* Game loop | ||
*/ | ||
void GameLoop() { | ||
Packet send_pkt, recv_pkt; | ||
std::string recv_str; | ||
|
||
cse491::WorldGrid grid; | ||
cse491::type_options_t type_options; | ||
cse491::item_set_t item_set; | ||
cse491::agent_set_t agent_set; | ||
std::string action; | ||
|
||
send_pkt << "Game started."; | ||
|
||
// ask for map | ||
if (!SendPacket(send_pkt, m_dest_ip.value(), m_dest_port)) return; | ||
|
||
while (action != "quit") { | ||
// receive map | ||
if (!ReceivePacket(recv_pkt, m_dest_ip, m_dest_port)) return; | ||
|
||
// print map | ||
recv_pkt >> recv_str; | ||
std::cout << std::endl << recv_str; | ||
|
||
// get user input | ||
action = GameLoop_GetInput(); | ||
|
||
// TODO: Unpack recv_pkt into world grid, agent list, etc | ||
// We need to serialize these classes... | ||
//recv_pkt >> grid >> type_options >> item_set >> agent_set; | ||
|
||
//action = mTrash->SelectAction(grid, type_options, item_set, agent_set); | ||
|
||
// send packet with action | ||
send_pkt.clear(); | ||
send_pkt << action; | ||
|
||
if (!SendPacket(send_pkt, m_dest_ip.value(), m_dest_port)) return; | ||
} | ||
} | ||
}; //End of ClientInterface | ||
}// End of namespace NetWorth |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
/** | ||
* This file is part of the Fall 2023, CSE 491 course project. | ||
* @brief A networking interface that allows information to be sent across a network | ||
* @note Status: PROTOTYPE | ||
**/ | ||
|
||
#pragma once | ||
|
||
#include <cassert> | ||
#include <string> | ||
#include <vector> | ||
#include <sstream> | ||
#include <SFML/Network/UdpSocket.hpp> | ||
#include <SFML/Network/Packet.hpp> | ||
|
||
#include "../NetworkInterface.hpp" | ||
#include "networkingworld.hpp" | ||
|
||
namespace netWorth{ | ||
using namespace sf; | ||
|
||
class NetworkMazeWorld; | ||
|
||
/** | ||
* The server that will be running and that allows clients to connect to | ||
*/ | ||
class ServerInterface : public NetworkingInterface { | ||
private: | ||
|
||
protected: | ||
|
||
public: | ||
ServerInterface() = default; | ||
~ServerInterface() = default; | ||
|
||
/** | ||
* The initial connection for the server to a client | ||
* @param sender address of the sender | ||
* @param send_pkt the packet that the server will send initially | ||
* @param recv_pkt the packet that the server will receive initially | ||
* @param port port of the connection | ||
* @param str string for the receive packet | ||
* @return true if successful | ||
*/ | ||
bool InitialConnection(std::optional<IpAddress> &sender, unsigned short &port){ | ||
Packet send_pkt, recv_pkt; | ||
std::string str; | ||
|
||
BindSocket(m_socket, 55002); | ||
|
||
// Await client | ||
if (!ReceivePacket(recv_pkt, sender, port)) return false; | ||
|
||
recv_pkt >> str; | ||
std::cout << str << std::endl; | ||
std::cout << sender.value() << " has connected successfully." << std::endl; | ||
|
||
// Acknowledge client | ||
send_pkt << "Connection established."; | ||
if (!SendPacket(send_pkt, sender.value(), port)) return false; | ||
|
||
// await request for map | ||
if (!ReceivePacket(recv_pkt, sender, port)) return false; | ||
|
||
recv_pkt >> str; | ||
std::cout << str << std::endl; | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* The grid that will be sent to the client from the server after the connection | ||
* so the client can start asking to make moves | ||
* @param grid the grid to send to the server | ||
* @param type_options different cell types of the world | ||
* @param item_set the items that may be apart of the grid | ||
* @param agent_set the agents that may be apart of the grid | ||
* @return the grid that will be sent to the client | ||
*/ | ||
static Packet GridToPacket(const cse491::WorldGrid & grid, const cse491::type_options_t & type_options, | ||
const cse491::item_set_t & item_set, const cse491::agent_set_t & agent_set) | ||
{ | ||
std::vector<std::string> packet_grid(grid.GetHeight()); | ||
|
||
// Load the world into the symbol_grid; | ||
for (size_t y=0; y < grid.GetHeight(); ++y) { | ||
packet_grid[y].resize(grid.GetWidth()); | ||
for (size_t x=0; x < grid.GetWidth(); ++x) { | ||
packet_grid[y][x] = type_options[ grid.At(x,y) ].symbol; | ||
} | ||
} | ||
|
||
// Add in the agents / entities | ||
for (const auto & entity_ptr : item_set) { | ||
cse491::GridPosition pos = entity_ptr->GetPosition(); | ||
packet_grid[pos.CellY()][pos.CellX()] = '+'; | ||
} | ||
|
||
for (const auto & agent_ptr : agent_set) { | ||
cse491::GridPosition pos = agent_ptr->GetPosition(); | ||
char c = '*'; | ||
if(agent_ptr->HasProperty("symbol")){ | ||
c = agent_ptr->GetProperty<char>("symbol"); | ||
} | ||
packet_grid[pos.CellY()][pos.CellX()] = c; | ||
} | ||
|
||
// Print out the symbol_grid with a box around it. | ||
std::ostringstream oss; | ||
oss << '+' << std::string(grid.GetWidth(),'-') << "+\n"; | ||
for (const auto & row : packet_grid) { | ||
oss << "|"; | ||
for (char cell : row) { | ||
oss << cell; | ||
} | ||
oss << "|\n"; | ||
} | ||
oss << '+' << std::string(grid.GetWidth(),'-') << "+\n"; | ||
oss << "\nYour move? "; | ||
std::string gridString = oss.str(); | ||
|
||
Packet gridPacket; | ||
gridPacket << gridString; | ||
|
||
return gridPacket; | ||
} | ||
|
||
};//End of class ServerInterface | ||
}//End of namespace netWorth |
Oops, something went wrong.