Implemented new version of snapshot for 3D world. Also some cleanup.

This commit is contained in:
stiffly
2015-12-08 17:57:01 +01:00
parent d1880754f5
commit 9f54a08536
5 changed files with 52 additions and 112 deletions
+7 -7
View File
@@ -11,7 +11,9 @@
#include "Network/MessageType.h"
#include "Network/NetworkDefines.h"
#include "Network/PlayerDefinition.h"
#include "Network/WinLeakCheck.h"
#include "Core/World.h"
#include "Core/EventBroker.h"
#include "Core/EKeyDown.h"
@@ -21,14 +23,12 @@ class Client
public:
Client();
~Client();
void Start(EventBroker* eventBroker);
void Start(World* world, EventBroker* eventBroker);
void Close();
private:
// Threaded
void DisplayLoop();
void ReadFromServer();
void InputLoop();
int Receive(char* data, size_t length);
int CreateMessage(MessageType type, std::string message, char* data);
@@ -41,19 +41,19 @@ private:
void ParsePing();
void ParseServerPing();
void ParseSnapshot(char* data, size_t length);
//void SendInput();
void SendDebugInput();
void DrawBoard();
void CreateNewPlayer(int i);
// udp stuff
boost::asio::ip::udp::endpoint m_ReceiverEndpoint;
boost::asio::io_service m_IOService;
boost::asio::ip::udp::socket m_Socket;
World* m_World;
int m_PlayerID = -1;
char m_GameBoard[BOARDSIZE][BOARDSIZE];
glm::vec2 m_PlayerPositions[MAXCONNECTIONS];
std::string m_PlayerNames[MAXCONNECTIONS];
//std::string m_PlayerNames[MAXCONNECTIONS];
PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS];
std::clock_t m_StartPingTime;
double m_DurationOfPingTime;
bool m_ShouldDrawGameBoard = true;
+2 -2
View File
@@ -3,8 +3,8 @@
#include <string>
struct PlayerDefinition {
unsigned int EntityID;
std::string Name;
unsigned int EntityID = -1;
std::string Name = "";
boost::asio::ip::udp::endpoint Endpoint;
};
+34 -99
View File
@@ -19,10 +19,11 @@ Client::~Client()
_CrtDumpMemoryLeaks();
}
void Client::Start(EventBroker* eventBroker)
void Client::Start(World* world, EventBroker* eventBroker)
{
// Subscribe to events
m_EventBroker = eventBroker;
m_World = world;
m_EKeyDown = decltype(m_EKeyDown)(std::bind(&Client::OnKeyDown, this, std::placeholders::_1));
m_EventBroker->Subscribe(m_EKeyDown);
std::cout << "Please enter you name: ";
@@ -34,24 +35,10 @@ void Client::Start(EventBroker* eventBroker)
boost::thread_group threads;
for (size_t i = 0; i < BOARDSIZE; i++) {
for (size_t j = 0; j < BOARDSIZE; j++) {
m_GameBoard[j][i] = ' ';
}
}
for (size_t i = 0; i < MAXCONNECTIONS; i++) {
m_PlayerPositions[i].x = -1;
m_PlayerPositions[i].y = -1;
m_PlayerNames[i] = "X";
}
m_Socket.connect(m_ReceiverEndpoint);
std::cout << "I am client. BIP BOP\n";
threads.create_thread(boost::bind(&Client::DisplayLoop, this));
threads.create_thread(boost::bind(&Client::ReadFromServer, this));
//threads.create_thread(boost::bind(&Client::InputLoop, this));
threads.join_all();
}
@@ -63,47 +50,6 @@ void Client::Close()
m_Socket.close();
}
void Client::InputLoop()
{
int intervallMs = 33; // ~30 times per second
int commandInterval = 200; // for commands like ping and connect, name might be ambigiuos
std::clock_t previousInputTime = std::clock();
std::clock_t previousCommandTime = std::clock();
while (m_ThreadIsRunning) {
std::clock_t currentTime = std::clock();
int testTimeShit = (1000 * (currentTime - previousCommandTime) / (double)CLOCKS_PER_SEC);
if (commandInterval < (1000 * (currentTime - previousCommandTime) / (double)CLOCKS_PER_SEC)) {
SendDebugInput();
previousCommandTime = currentTime;
}
int testTimeShit2 = (1000 * (currentTime - previousInputTime) / (double)CLOCKS_PER_SEC);
if (intervallMs < (1000 * (currentTime - previousInputTime) / (double)CLOCKS_PER_SEC)) {
if (m_PlayerID != -1) {
//SendInput();
}
previousInputTime = currentTime;
}
}
}
void Client::DisplayLoop()
{
while (m_ThreadIsRunning) {
// Update gameboard
for (size_t i = 0; i < BOARDSIZE; i++) {
for (size_t j = 0; j < BOARDSIZE; j++) {
m_GameBoard[j][i] = ' ';
}
}
if (m_ShouldDrawGameBoard)
//DrawBoard();
boost::this_thread::sleep(boost::posix_time::millisec(100));
}
}
void Client::ReadFromServer()
{
int bytesRead = -1;
@@ -183,7 +129,7 @@ void Client::ParseEventMessage(char* data, size_t length)
memcpy(&Id, data, sizeof(int));
MoveMessageHead(data, length, sizeof(int));
// Sett Player name
m_PlayerNames[Id] = command.erase(0, 7);
m_PlayerDefinitions[Id].Name = command.erase(0, 7);
}
else {
std::cout << "Event message: " << std::string(data) << std::endl;
@@ -196,40 +142,37 @@ void Client::ParseSnapshot(char* data, size_t length)
{
std::string tempName;
for (size_t i = 0; i < MAXCONNECTIONS; i++) {
memcpy(&m_PlayerPositions[i].x, data, sizeof(float));
// We're checking for empty name for now. This might not be the best way,
// but it is to avoid sending redundant data.
// Read position data
glm::vec3 playerPos;
memcpy(&playerPos.x, data, sizeof(float));
MoveMessageHead(data, length, sizeof(float));
memcpy(&m_PlayerPositions[i].y, data, sizeof(float));
memcpy(&playerPos.y, data, sizeof(float));
MoveMessageHead(data, length, sizeof(float));
memcpy(&playerPos.z, data, sizeof(float));
MoveMessageHead(data, length, sizeof(float));
tempName = std::string(data);
m_PlayerNames[i] = tempName;
// +1 for null terminator
MoveMessageHead(data, length, tempName.size() + 1);
}
}
void Client::DrawBoard()
{
for (size_t i = 0; i < MAXCONNECTIONS; i++) {
if (m_PlayerPositions[i].x != -1 && m_PlayerPositions[i].y != -1) {
m_GameBoard[static_cast<int>(m_PlayerPositions[i].x)][static_cast<int>(m_PlayerPositions[i].y)] = m_PlayerNames[i][0];
// Apply the position data read to the player entity
// New player connected on the server side
if (m_PlayerDefinitions[i].Name == "" && tempName != "") {
CreateNewPlayer(i);
}
}
system("cls");
for (size_t i = 0; i < BOARDSIZE; i++) {
std::cout << '_';
}
std::cout << std::endl;
for (size_t i = 0; i < BOARDSIZE; i++) {
for (size_t j = 0; j < BOARDSIZE; j++) {
std::cout << m_GameBoard[j][i];
else if (m_PlayerDefinitions[i].Name != "" && tempName == "") {
// Someone disconnected
// TODO: Insert code here
}
std::cout << std::endl;
}
for (size_t i = 0; i < BOARDSIZE; i++) {
std::cout << "^";
else {
// Not a connected player
break;
}
m_World->GetComponent(m_PlayerDefinitions[i].EntityID, "Transform")["Position"] = playerPos;
m_PlayerDefinitions[i].Name = tempName;
}
}
@@ -288,22 +231,6 @@ void Client::MoveMessageHead(char*& data, size_t& length, size_t stepSize)
length -= stepSize;
}
void Client::SendDebugInput()
{
char* dataPackage = new char[INPUTSIZE];
if (GetAsyncKeyState('P')) { // Maybe use previous key here
int length = CreateMessage(MessageType::ClientPing, "Ping", dataPackage);
m_StartPingTime = std::clock();
m_Socket.send_to(boost::asio::buffer(
dataPackage,
length),
m_ReceiverEndpoint, 0);
}
memset(dataPackage, 0, INPUTSIZE);
delete[] dataPackage;
}
bool Client::OnKeyDown(const Events::KeyDown& event)
{
char* dataPackage = new char[INPUTSIZE]; // The package that will be sent to the server, when filled
@@ -345,4 +272,12 @@ bool Client::OnKeyDown(const Events::KeyDown& event)
memset(dataPackage, 0, INPUTSIZE);
delete[] dataPackage;
return true;
}
void Client::CreateNewPlayer(int i)
{
m_PlayerDefinitions[i].EntityID = m_World->CreateEntity();
ComponentWrapper transform = m_World->AttachComponent(m_PlayerDefinitions[i].EntityID, "Transform");
ComponentWrapper model = m_World->AttachComponent(m_PlayerDefinitions[i].EntityID, "Model");
model["Resource"] = "Models/Core/UnitSphere.obj";
}
+8 -3
View File
@@ -203,14 +203,19 @@ void Server::Broadcast(char * data, size_t length)
void Server::SendSnapshot()
{
char* data = new char[128];
char* data = new char[INPUTSIZE];
int offset = CreateHeader(MessageType::Snapshot, data);
for (size_t i = 0; i < MAXCONNECTIONS; i++) {
memcpy(data + offset, &m_PlayerPositions[i].x, sizeof(float));
// Pack player pos into data package
glm::vec3 playerPos = m_World->GetComponent(m_PlayerDefinitions[i].EntityID, "Transform")["Position"];
memcpy(data + offset, &playerPos.x, sizeof(float));
offset += sizeof(float);
memcpy(data + offset, &m_PlayerPositions[i].y, sizeof(float));
memcpy(data + offset, &playerPos.y, sizeof(float));
offset += sizeof(float);
memcpy(data + offset, &playerPos.z, sizeof(float));
offset += sizeof(float);
// +1 for null terminator
// Pack player name into data package
memcpy(data + offset, m_PlayerDefinitions[i].Name.data(), m_PlayerDefinitions[i].Name.size() + 1);
offset += (m_PlayerDefinitions[i].Name.size() + 1) * sizeof(char);
}
+1 -1
View File
@@ -81,7 +81,7 @@ void Game::NetworkFunction()
std::cout << "Start client or server? (c/s)" << std::endl;
std::cin >> inputMessage;
if (inputMessage == "c" || inputMessage == "C") {
m_Client.Start(m_EventBroker);
m_Client.Start(m_World, m_EventBroker);
}
if (inputMessage == "s" || inputMessage == "S") {
m_Server.Start(m_World);