Server now broadcasts certain input commands to all other clients (for stuff like shooting)
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user