Server now broadcasts certain input commands to all other clients (for stuff like shooting)

This commit is contained in:
2016-02-09 19:37:42 +01:00
parent d5647ce89c
commit d83190290f
6 changed files with 48 additions and 22 deletions
+2
View File
@@ -48,6 +48,7 @@ private:
float snapshotInterval; float snapshotInterval;
int checkTimeOutInterval = 100; int checkTimeOutInterval = 100;
int m_NextPlayerID = 0; int m_NextPlayerID = 0;
std::vector<Events::InputCommand> m_InputCommandsToBroadcast;
//Timers //Timers
std::clock_t m_StartPingTime; std::clock_t m_StartPingTime;
@@ -64,6 +65,7 @@ private:
void broadcast(Packet& packet); void broadcast(Packet& packet);
void sendSnapshot(); void sendSnapshot();
void addChildrenToPacket(Packet& packet, EntityID entityID); void addChildrenToPacket(Packet& packet, EntityID entityID);
void addInputCommandsToPacket(Packet& packet);
void sendPing(); void sendPing();
void checkForTimeOuts(); void checkForTimeOuts();
void disconnect(PlayerID playerID); void disconnect(PlayerID playerID);
+1 -7
View File
@@ -9,7 +9,6 @@
#include "Core/System.h" #include "Core/System.h"
#include "Core/EPlayerDamage.h" #include "Core/EPlayerDamage.h"
#include "Core/EShoot.h" #include "Core/EShoot.h"
#include "Core/EPlayerSpawned.h"
#include "Input/EInputCommand.h" #include "Input/EInputCommand.h"
#include "Core/EntityFile.h" #include "Core/EntityFile.h"
#include "Core/EntityFileParser.h" #include "Core/EntityFileParser.h"
@@ -28,16 +27,11 @@ public:
private: private:
IRenderer* m_Renderer; IRenderer* m_Renderer;
// State
EntityWrapper m_LocalPlayer = EntityWrapper::Invalid;
// Events // Events
EventRelay<WeaponSystem, Events::PlayerSpawned> m_EPlayerSpawned;
bool WeaponSystem::OnPlayerSpawned(const Events::PlayerSpawned& e);
EventRelay<WeaponSystem, Events::Shoot> m_EShoot; EventRelay<WeaponSystem, Events::Shoot> m_EShoot;
bool WeaponSystem::OnShoot(Events::Shoot& e); bool WeaponSystem::OnShoot(Events::Shoot& e);
EventRelay<WeaponSystem, Events::InputCommand> m_EInputCommand; EventRelay<WeaponSystem, Events::InputCommand> m_EInputCommand;
bool WeaponSystem::OnInputCommand(const Events::InputCommand& e); bool WeaponSystem::OnInputCommand(Events::InputCommand& e);
}; };
#endif #endif
+16
View File
@@ -230,6 +230,18 @@ void Client::ignoreFields(Packet& packet, const ComponentInfo& componentInfo)
void Client::parseSnapshot(Packet& packet) void Client::parseSnapshot(Packet& packet)
{ {
// Read input commands
std::size_t numInputCommands = packet.ReadPrimitive<std::size_t>();
for (std::size_t i = 0; i < numInputCommands; ++i) {
Events::InputCommand e;
e.PlayerID = packet.ReadPrimitive<EntityID>();
e.Player = EntityWrapper(m_World, m_ServerIDToClientID.at(packet.ReadPrimitive<EntityID>()));
e.Command = packet.ReadString();
e.Value = packet.ReadPrimitive<float>();
m_EventBroker->Publish(e);
}
// Read world state
while (packet.DataReadSize() < packet.Size()) { while (packet.DataReadSize() < packet.Size()) {
EntityID serverEntityID = packet.ReadPrimitive<EntityID>(); EntityID serverEntityID = packet.ReadPrimitive<EntityID>();
EntityID serverParentID = packet.ReadPrimitive<EntityID>(); EntityID serverParentID = packet.ReadPrimitive<EntityID>();
@@ -339,6 +351,10 @@ void Client::disconnect()
bool Client::OnInputCommand(const Events::InputCommand & e) bool Client::OnInputCommand(const Events::InputCommand & e)
{ {
if (e.PlayerID != -1) {
return false;
}
if (e.Command == "ConnectToServer") { // Connect for now if (e.Command == "ConnectToServer") { // Connect for now
if (e.Value > 0) { if (e.Value > 0) {
connect(); connect();
+18
View File
@@ -165,10 +165,24 @@ void Server::broadcast(Packet& packet)
void Server::sendSnapshot() void Server::sendSnapshot()
{ {
Packet packet(MessageType::Snapshot); Packet packet(MessageType::Snapshot);
addInputCommandsToPacket(packet);
addChildrenToPacket(packet, EntityID_Invalid); addChildrenToPacket(packet, EntityID_Invalid);
broadcast(packet); broadcast(packet);
} }
void Server::addInputCommandsToPacket(Packet& packet)
{
// Number of input commands
packet.WritePrimitive(m_InputCommandsToBroadcast.size());
for (auto& command : m_InputCommandsToBroadcast) {
packet.WritePrimitive(command.PlayerID);
packet.WritePrimitive(m_ConnectedPlayers.at(command.PlayerID).EntityID);
packet.WriteString(command.Command);
packet.WritePrimitive(command.Value);
}
m_InputCommandsToBroadcast.clear();
}
void Server::addChildrenToPacket(Packet & packet, EntityID entityID) void Server::addChildrenToPacket(Packet & packet, EntityID entityID)
{ {
auto itPair = m_World->GetChildren(entityID); auto itPair = m_World->GetChildren(entityID);
@@ -273,6 +287,10 @@ void Server::parseOnInputCommand(Packet& packet)
e.Player = EntityWrapper(m_World, m_ConnectedPlayers.at(player).EntityID); e.Player = EntityWrapper(m_World, m_ConnectedPlayers.at(player).EntityID);
e.Value = packet.ReadPrimitive<float>(); e.Value = packet.ReadPrimitive<float>();
m_EventBroker->Publish(e); m_EventBroker->Publish(e);
if (e.Command == "PrimaryFire") {
m_InputCommandsToBroadcast.push_back(e);
}
//LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); //LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
} }
} }
+5
View File
@@ -218,5 +218,10 @@ int Game::parseArgs(int argc, char* argv[])
m_IsClient = true; m_IsClient = true;
} }
// HACK: Right now, client and server are mutually exclusive
if (m_IsServer) {
m_IsClient = false;
}
return 0; return 0;
} }
+6 -15
View File
@@ -5,7 +5,6 @@ WeaponSystem::WeaponSystem(SystemParams params, IRenderer* renderer)
, ImpureSystem() , ImpureSystem()
, m_Renderer(renderer) , m_Renderer(renderer)
{ {
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &WeaponSystem::OnPlayerSpawned);
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &WeaponSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &WeaponSystem::OnInputCommand);
EVENT_SUBSCRIBE_MEMBER(m_EShoot, &WeaponSystem::OnShoot); EVENT_SUBSCRIBE_MEMBER(m_EShoot, &WeaponSystem::OnShoot);
} }
@@ -15,30 +14,22 @@ void WeaponSystem::Update(double dt)
} }
bool WeaponSystem::OnPlayerSpawned(const Events::PlayerSpawned& e) bool WeaponSystem::OnInputCommand(Events::InputCommand& e)
{
if (e.PlayerID == -1) {
m_LocalPlayer = e.Player;
}
return true;
}
bool WeaponSystem::OnInputCommand(const Events::InputCommand& e)
{ {
// Only shoot client-side! // Only shoot client-side!
if (e.PlayerID != -1) { if (!IsClient) {
return false; return false;
} }
// Only shoot if the player is alive // Only shoot if the player is alive
if (!m_LocalPlayer.Valid()) { if (!e.Player.Valid()) {
return false; return false;
} }
if (e.Command == "PrimaryFire" && e.Value > 0) { if (e.Command == "PrimaryFire" && e.Value > 0) {
Events::Shoot eShoot; Events::Shoot eShoot;
if (e.PlayerID == -1) { if (e.PlayerID == -1) {
eShoot.Player = m_LocalPlayer; eShoot.Player = LocalPlayer;
} else { } else {
eShoot.Player = e.Player; eShoot.Player = e.Player;
} }
@@ -97,8 +88,8 @@ bool WeaponSystem::OnShoot(Events::Shoot& eShoot)
//(glm::vec3&)ray["Transform"]["Orientation"] = Transform::AbsoluteOrientationEuler(weapon); //(glm::vec3&)ray["Transform"]["Orientation"] = Transform::AbsoluteOrientationEuler(weapon);
} }
// Only run further picking code client-side! // Only run further picking code for the local player!
if (eShoot.Player != m_LocalPlayer) { if (eShoot.Player != LocalPlayer) {
return false; return false;
} }