Skip to content

Commit

Permalink
Integrated player class in container sync
Browse files Browse the repository at this point in the history
  • Loading branch information
RobbeBryssinck committed Jul 5, 2021
1 parent 220bd65 commit 3936114
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 105 deletions.
2 changes: 1 addition & 1 deletion Code/client/Services/Generic/InventoryService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ void InventoryService::ApplyCachedCharacterInventoryChanges() noexcept
const auto& formIdComponent = view.get<FormIdComponent>(entity);
auto* const pActor = RTTI_CAST(TESForm::GetById(formIdComponent.Id), TESForm, Actor);
if (!pActor)
return;
continue;

if (cpRemoteComponent)
cpRemoteComponent->SpawnRequest.InventoryContent = change.value();
Expand Down
7 changes: 4 additions & 3 deletions Code/server/Components/ObjectComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
#endif

#include <Structs/LockData.h>
#include <Game/Player.h>

struct ObjectComponent
{
ObjectComponent(const ConnectionId_t aConnectionId)
: LastSender(aConnectionId)
ObjectComponent(Player* apLastSender)
: pLastSender(apLastSender)
{}

ConnectionId_t LastSender;
Player* pLastSender;
LockData CurrentLockData{};
};
47 changes: 12 additions & 35 deletions Code/server/Services/EnvironmentService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@


#include <GameServer.h>
#include <World.h>

#include <Services/EnvironmentService.h>
#include <Events/UpdateEvent.h>
Expand Down Expand Up @@ -37,28 +38,21 @@ void EnvironmentService::OnPlayerJoin(const PlayerJoinEvent& acEvent) const noex

void EnvironmentService::OnPlayerLeaveCellEvent(const PlayerLeaveCellEvent& acEvent) noexcept
{
auto playerView = m_world.view<PlayerComponent, CellIdComponent>();

const auto playerInCellIt = std::find_if(std::begin(playerView), std::end(playerView),
[playerView, oldCell = acEvent.OldCell](auto entity)
for (auto pPlayer : m_world.GetPlayerManager())
{
const auto& cellIdComponent = playerView.get<CellIdComponent>(entity);
return cellIdComponent.Cell == oldCell;
});
if (pPlayer->GetCellComponent().Cell == acEvent.OldCell)
return;
}

if (playerInCellIt != std::end(playerView))
auto objectView = m_world.view<ObjectComponent, CellIdComponent>();
for (auto entity : objectView)
{
auto objectView = m_world.view<ObjectComponent, CellIdComponent>();
const auto& cellIdComponent = objectView.get<CellIdComponent>(entity);

for (auto entity : objectView)
{
const auto& cellIdComponent = objectView.get<CellIdComponent>(entity);

if (cellIdComponent.Cell != acEvent.OldCell)
continue;
if (cellIdComponent.Cell != acEvent.OldCell)
continue;

m_world.destroy(entity);
}
m_world.destroy(entity);
}
}

Expand Down Expand Up @@ -97,12 +91,11 @@ void EnvironmentService::OnAssignObjectsRequest(const PacketEvent<AssignObjectsR

m_world.emplace<FormIdComponent>(cEntity, object.Id);

auto& objectComponent = m_world.emplace<ObjectComponent>(cEntity, acMessage.ConnectionId);
auto& objectComponent = m_world.emplace<ObjectComponent>(cEntity, acMessage.pPlayer);
objectComponent.CurrentLockData = object.CurrentLockData;

m_world.emplace<CellIdComponent>(cEntity, object.CellId, object.WorldSpaceId, object.CurrentCoords);
m_world.emplace<InventoryComponent>(cEntity);
m_world.emplace<OwnerComponent>(cEntity, acMessage.ConnectionId);
}
}

Expand Down Expand Up @@ -147,22 +140,6 @@ void EnvironmentService::OnLockChange(const PacketEvent<LockChangeRequest>& acMe
objectComponent.CurrentLockData.LockLevel = acMessage.Packet.LockLevel;
}

auto playerView = m_world.view<PlayerComponent, CellIdComponent>();

auto connectionId = acMessage.ConnectionId;

auto senderIter = std::find_if(std::begin(playerView), std::end(playerView), [playerView, connectionId](auto entity)
{
const auto& playerComponent = playerView.get<PlayerComponent>(entity);
return playerComponent.ConnectionId == connectionId;
});

if (senderIter == std::end(playerView))
{
spdlog::warn("Player with connection id {:X} doesn't exist.", connectionId);
return;
}

for(auto pPlayer : m_world.GetPlayerManager())
{
if (pPlayer != acMessage.pPlayer && pPlayer->GetCellComponent().Cell == acMessage.Packet.CellId)
Expand Down
55 changes: 26 additions & 29 deletions Code/server/Services/InventoryService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ void InventoryService::OnObjectInventoryChanges(const PacketEvent<RequestObjectI
{
const auto entity = m_world.create();
m_world.emplace<FormIdComponent>(entity, it.first.BaseId, it.first.ModId);
m_world.emplace<ObjectComponent>(entity, acMessage.ConnectionId);
m_world.emplace<ObjectComponent>(entity, acMessage.pPlayer);
m_world.emplace<CellIdComponent>(entity, it.second.CellId, it.second.WorldSpaceId, it.second.CurrentCoords);

// TODO: emplace or replace
auto& inventoryComponent = m_world.emplace<InventoryComponent>(entity);
inventoryComponent.Content = it.second.CurrentInventory;
inventoryComponent.DirtyInventory = true;
Expand All @@ -54,8 +55,9 @@ void InventoryService::OnObjectInventoryChanges(const PacketEvent<RequestObjectI
else
{
auto& objectComponent = m_world.get<ObjectComponent>(*formIdIt);
objectComponent.LastSender = acMessage.ConnectionId;
objectComponent.pLastSender = acMessage.pPlayer;

// TODO: emplace or replace
auto& inventoryComponent = m_world.get<InventoryComponent>(*formIdIt);
inventoryComponent.Content = it.second.CurrentInventory;
inventoryComponent.DirtyInventory = true;
Expand All @@ -69,20 +71,21 @@ void InventoryService::OnObjectInventoryChanges(const PacketEvent<RequestObjectI

void InventoryService::OnCharacterInventoryChanges(const PacketEvent<RequestCharacterInventoryChanges>& acMessage) noexcept
{
// TODO: change this to new OwnerView
auto view = m_world.view<CharacterComponent, InventoryComponent, OwnerComponent>();

auto& message = acMessage.Packet;

for (auto& [id, inventory] : message.Changes)
{
auto itor = view.find(static_cast<entt::entity>(id));
auto iter = view.find(static_cast<entt::entity>(id));

if (itor == std::end(view) || view.get<OwnerComponent>(*itor).ConnectionId != acMessage.ConnectionId)
if (iter == std::end(view))
continue;

spdlog::critical("Character inventory size: {}", inventory.Buffer.size());

auto& inventoryComponent = view.get<InventoryComponent>(*itor);
auto& inventoryComponent = view.get<InventoryComponent>(*iter);
inventoryComponent.Content = inventory;
inventoryComponent.DirtyInventory = true;
}
Expand All @@ -99,10 +102,9 @@ void InventoryService::ProcessObjectInventoryChanges() noexcept

lastSendTimePoint = now;

const auto playerView = m_world.view<PlayerComponent, CellIdComponent>();
const auto objectView = m_world.view<FormIdComponent, ObjectComponent, InventoryComponent, CellIdComponent>();

Map<ConnectionId_t, NotifyObjectInventoryChanges> messages;
Map<Player*, NotifyObjectInventoryChanges> messages;

for (auto entity : objectView)
{
Expand All @@ -115,14 +117,12 @@ void InventoryService::ProcessObjectInventoryChanges() noexcept
if (inventoryComponent.DirtyInventory == false)
continue;

for (auto player : playerView)
for (auto pPlayer : m_world.GetPlayerManager())
{
const auto& playerComponent = playerView.get<PlayerComponent>(player);

if (playerComponent.ConnectionId == objectComponent.LastSender)
if (pPlayer == objectComponent.pLastSender)
continue;

const auto& playerCellIdComponent = playerView.get<CellIdComponent>(player);
const auto& playerCellIdComponent = pPlayer->GetCellComponent();
if (cellIdComponent.WorldSpaceId == GameId{})
{
if (playerCellIdComponent != cellIdComponent)
Expand All @@ -133,14 +133,14 @@ void InventoryService::ProcessObjectInventoryChanges() noexcept
else
{
if (cellIdComponent.WorldSpaceId != playerCellIdComponent.WorldSpaceId ||
!GridCellCoords::IsCellInGridCell(&cellIdComponent.CenterCoords,
&playerCellIdComponent.CenterCoords))
!GridCellCoords::IsCellInGridCell(cellIdComponent.CenterCoords,
playerCellIdComponent.CenterCoords))
{
continue;
}
}

auto& message = messages[playerComponent.ConnectionId];
auto& message = messages[pPlayer];
auto& change = message.Changes[formIdComponent.Id];

change = inventoryComponent.Content;
Expand All @@ -149,10 +149,10 @@ void InventoryService::ProcessObjectInventoryChanges() noexcept
inventoryComponent.DirtyInventory = false;
}

for (auto [connectionId, message] : messages)
for (auto [pPlayer, message] : messages)
{
if (!message.Changes.empty())
GameServer::Get()->Send(connectionId, message);
pPlayer->Send(message);

spdlog::info("Sent inventory contents");
}
Expand All @@ -169,10 +169,9 @@ void InventoryService::ProcessCharacterInventoryChanges() noexcept

lastSendTimePoint = now;

const auto playerView = m_world.view<PlayerComponent, CellIdComponent>();
const auto characterView = m_world.view<CharacterComponent, CellIdComponent, InventoryComponent, OwnerComponent>();

Map<ConnectionId_t, NotifyCharacterInventoryChanges> messages;
Map<Player*, NotifyCharacterInventoryChanges> messages;

for (auto entity : characterView)
{
Expand All @@ -184,14 +183,12 @@ void InventoryService::ProcessCharacterInventoryChanges() noexcept
if (inventoryComponent.DirtyInventory == false)
continue;

for (auto player : playerView)
for (auto pPlayer : m_world.GetPlayerManager())
{
const auto& playerComponent = playerView.get<PlayerComponent>(player);

if (playerComponent.ConnectionId == ownerComponent.ConnectionId)
if (pPlayer == ownerComponent.GetOwner())
continue;

const auto& playerCellIdComponent = playerView.get<CellIdComponent>(player);
const auto& playerCellIdComponent = pPlayer->GetCellComponent();
if (cellIdComponent.WorldSpaceId == GameId{})
{
if (playerCellIdComponent != cellIdComponent)
Expand All @@ -200,14 +197,14 @@ void InventoryService::ProcessCharacterInventoryChanges() noexcept
else
{
if (cellIdComponent.WorldSpaceId != playerCellIdComponent.WorldSpaceId ||
!GridCellCoords::IsCellInGridCell(&cellIdComponent.CenterCoords,
&playerCellIdComponent.CenterCoords))
!GridCellCoords::IsCellInGridCell(cellIdComponent.CenterCoords,
playerCellIdComponent.CenterCoords))
{
continue;
}
}

auto& message = messages[playerComponent.ConnectionId];
auto& message = messages[pPlayer];
auto& change = message.Changes[World::ToInteger(entity)];

change = inventoryComponent.Content;
Expand All @@ -216,10 +213,10 @@ void InventoryService::ProcessCharacterInventoryChanges() noexcept
inventoryComponent.DirtyInventory = false;
}

for (auto [connectionId, message] : messages)
for (auto [pPlayer, message] : messages)
{
if (!message.Changes.empty())
GameServer::Get()->Send(connectionId, message);
pPlayer->Send(message);

spdlog::error("Character inventory sent");
}
Expand Down
43 changes: 6 additions & 37 deletions Code/server/Services/PlayerService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,13 @@ PlayerService::PlayerService(World& aWorld, entt::dispatcher& aDispatcher) noexc

void PlayerService::HandleGridCellShift(const PacketEvent<ShiftGridCellRequest>& acMessage) const noexcept
{
auto playerView = m_world.view<PlayerComponent>();

const auto itor = std::find_if(std::begin(playerView), std::end(playerView),
[playerView, connectionId = acMessage.ConnectionId](auto entity)
{
const auto& [playerComponent] = playerView.get(entity);
return playerComponent.ConnectionId == connectionId;
});

if(itor == std::end(playerView))
{
spdlog::error("Connection {:x} is not associated with a player.", acMessage.ConnectionId);
return;
}
auto* pPlayer = acMessage.pPlayer;

if (const auto pCellIdComponent = m_world.try_get<CellIdComponent>(*itor))
{
m_world.GetDispatcher().trigger(PlayerLeaveCellEvent(pCellIdComponent->Cell));
}
if (const auto cell = pPlayer->GetCellComponent())
m_world.GetDispatcher().trigger(PlayerLeaveCellEvent(cell.Cell));

auto& message = acMessage.Packet;

auto* pPlayer = acMessage.pPlayer;

auto cell = CellIdComponent{message.PlayerCell, message.WorldSpaceId, message.CenterCoords};
pPlayer->SetCellComponent(cell);

Expand Down Expand Up @@ -98,28 +81,14 @@ void PlayerService::HandleExteriorCellEnter(const PacketEvent<EnterExteriorCellR

void PlayerService::HandleInteriorCellEnter(const PacketEvent<EnterInteriorCellRequest>& acMessage) const noexcept
{
auto playerView = m_world.view<PlayerComponent>();

const auto itor = std::find_if(std::begin(playerView), std::end(playerView),
[playerView, connectionId = acMessage.ConnectionId](auto entity)
{
const auto& [playerComponent] = playerView.get(entity);
return playerComponent.ConnectionId == connectionId;
});

if(itor == std::end(playerView))
{
spdlog::error("Connection {:x} is not associated with a player.", acMessage.ConnectionId);
return;
}
auto* pPlayer = acMessage.pPlayer;

if (const auto pCellIdComponent = m_world.try_get<CellIdComponent>(*itor))
if (const auto cell = pPlayer->GetCellComponent())
{
m_world.GetDispatcher().trigger(PlayerLeaveCellEvent(pCellIdComponent->Cell));
m_world.GetDispatcher().trigger(PlayerLeaveCellEvent(cell.Cell));
}

auto& message = acMessage.Packet;
auto* pPlayer = acMessage.pPlayer;

if (pPlayer->GetCharacter())
{
Expand Down

0 comments on commit 3936114

Please sign in to comment.