Batch multiple player positions in a single packet
This commit is contained in:
@@ -24,6 +24,7 @@ namespace Cast
|
||||
std::uint16_t m_serverId;
|
||||
Cast::Network::SessionsManager m_sessionsManager{};
|
||||
static inline Cast::Classes::RoomsManager m_roomsManager{};
|
||||
std::shared_ptr<asio::steady_timer> m_positionTimer;
|
||||
|
||||
tcp::acceptor m_mainServerAcceptor;
|
||||
std::optional<tcp::socket> m_mainSocket;
|
||||
@@ -34,6 +35,7 @@ namespace Cast
|
||||
CastServer(ioContext& io_context, const std::string& serverIp, std::uint16_t port, std::uint16_t mainPort, std::uint16_t serverId);
|
||||
void asyncAccept();
|
||||
void asyncAcceptMainServer();
|
||||
void tickPositionFlush();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -27,9 +27,13 @@ namespace Cast
|
||||
std::uint32_t m_roomNumber = -1;
|
||||
std::uint32_t m_serverId{};
|
||||
|
||||
std::vector<Common::Network::UnecryptedPacket> m_pendingPositions;
|
||||
|
||||
public:
|
||||
bool m_hasMatchStarted{};
|
||||
bool m_isInvisible{};
|
||||
std::uint32_t m_roomTick{};
|
||||
|
||||
|
||||
// Arena Mode
|
||||
bool m_isArenaMode{};
|
||||
@@ -124,6 +128,10 @@ namespace Cast
|
||||
void shuffleCoordinates();
|
||||
|
||||
void respawnEveryoneArena();
|
||||
|
||||
void enqueuePosition(Common::Network::UnecryptedPacket&& pkt);
|
||||
|
||||
void flushPendingPositions();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,14 @@ namespace Cast
|
||||
{
|
||||
private:
|
||||
std::array<std::shared_ptr<Cast::Classes::Room>, Common::Constants::maxSessionsPerServer + 1> m_playerSessionIdToRoom{};
|
||||
std::vector<std::shared_ptr<Cast::Classes::Room>> m_rooms{};
|
||||
|
||||
public:
|
||||
const auto& getAllRooms() const
|
||||
{
|
||||
return m_rooms;
|
||||
}
|
||||
|
||||
void addRoom(std::shared_ptr<Room> room, std::uint64_t playerId);
|
||||
|
||||
void switchRoomJoinOrExit(std::shared_ptr<Cast::Network::Session> session, std::uint64_t hostSessionId = -1);
|
||||
@@ -32,6 +38,8 @@ namespace Cast
|
||||
|
||||
void playerForwardToHost(std::uint64_t hostSessionId, std::uint64_t senderSessionId, Common::Network::UnecryptedPacket& packet);
|
||||
|
||||
void setRoomTick(std::uint64_t hostSessionId, std::uint64_t tick);
|
||||
|
||||
void hostForwardToPlayer(std::uint64_t hostSessionId, std::uint64_t receiverSessionId, Common::Network::UnecryptedPacket& packet, bool useHostSessionIdInTcpHeader = true);
|
||||
|
||||
void setMapFor(std::uint64_t playerId, std::uint32_t map);
|
||||
|
||||
@@ -17,9 +17,14 @@ namespace Cast
|
||||
{
|
||||
namespace Handlers
|
||||
{
|
||||
std::uint32_t getPositionTickMs(std::uint64_t timeSinceLastRestart, std::uint64_t roomTick)
|
||||
{
|
||||
return Common::Utils::getCurrentTimestampMs() - timeSinceLastRestart;
|
||||
}
|
||||
|
||||
inline void handlePlayerPosition(const Common::Network::UnecryptedPacket& request, std::shared_ptr<Cast::Network::Session> session,
|
||||
Cast::Classes::RoomsManager& roomsManager, std::uint32_t serverId, Cast::Network::SessionsManager& sm,
|
||||
Ac::AntiCheatManager& acManager)
|
||||
Ac::AntiCheatManager& acManager, std::uint64_t timeSinceLastRestart)
|
||||
{
|
||||
using namespace Cast::Structures;
|
||||
|
||||
@@ -29,6 +34,8 @@ namespace Cast
|
||||
|
||||
Cast::Structures::ClientPlayerInfoBasic playerPositionFromClient = Cast::Details::parseData<Cast::Structures::ClientPlayerInfoBasic>(request);
|
||||
if (playerPositionFromClient.isBad()) return;
|
||||
room->m_roomTick = playerPositionFromClient.matchTick;
|
||||
|
||||
|
||||
if (room->m_isInvisible || session->m_isInvisible)
|
||||
{
|
||||
@@ -57,20 +64,17 @@ namespace Cast
|
||||
const auto fullSize = request.getFullSize();
|
||||
|
||||
|
||||
if (fullSize == 36)
|
||||
// Note: melee worked without warping, and the only thing melee doesn't have is bullets! That may be the issue with all-weapons FFA warps
|
||||
if (fullSize == 36)
|
||||
{
|
||||
Cast::Structures::ClientPlayerInfoBullet playerPositionBullet{};
|
||||
std::memcpy(&playerPositionBullet, request.getData(), sizeof(playerPositionBullet));
|
||||
if (playerPositionBullet.isBad())
|
||||
{
|
||||
::Utils::Logger::log("Bad Player Respawn Position", ::Utils::LogType::Warning, "Cast::handlePlayerPosition");
|
||||
return;
|
||||
}
|
||||
if (playerPositionBullet.isBad()) return;
|
||||
|
||||
PlayerInfoResponseWithBullets playerInfoResponseWithBullets;
|
||||
// playerInfoResponseWithBullets.tick = playerPositionFromClient.matchTick;
|
||||
playerInfoResponseWithBullets.specificInfo.enableBullet = true;
|
||||
|
||||
playerInfoResponseWithBullets.tick = playerPositionFromClient.matchTick;
|
||||
playerInfoResponseWithBullets.specificInfo.enableJump = false;
|
||||
playerInfoResponseWithBullets.position = playerPositionFromClient.position;
|
||||
playerInfoResponseWithBullets.direction = playerPositionFromClient.direction;
|
||||
playerInfoResponseWithBullets.specificInfo.animation1 = playerPositionFromClient.animation1;
|
||||
@@ -83,9 +87,8 @@ namespace Cast
|
||||
playerInfoResponseWithBullets.currentWeapon = playerPositionBullet.bulletStruct.bullet4;
|
||||
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&playerInfoResponseWithBullets), sizeof(playerInfoResponseWithBullets));
|
||||
|
||||
}
|
||||
else if (fullSize == 40)
|
||||
else if (fullSize == 40) // bullet+jump+movement+rotation (simplified)
|
||||
{
|
||||
Cast::Structures::ClientPlayerInfoComplete playerPositionComplete{};
|
||||
std::memcpy(&playerPositionComplete, request.getData(), request.getDataSize());
|
||||
@@ -97,8 +100,9 @@ namespace Cast
|
||||
|
||||
PlayerInfoResponseWithBullets playerInfoResponseWithBullets;
|
||||
playerInfoResponseWithBullets.specificInfo.enableBullet = true;
|
||||
playerInfoResponseWithBullets.specificInfo.enableJump = true;
|
||||
|
||||
playerInfoResponseWithBullets.tick = playerPositionFromClient.matchTick;
|
||||
// playerInfoResponseWithBullets.tick = playerPositionFromClient.matchTick;
|
||||
playerInfoResponseWithBullets.position = playerPositionFromClient.position;
|
||||
playerInfoResponseWithBullets.direction = playerPositionFromClient.direction;
|
||||
playerInfoResponseWithBullets.specificInfo.animation1 = playerPositionFromClient.animation1;
|
||||
@@ -109,9 +113,7 @@ namespace Cast
|
||||
playerInfoResponseWithBullets.specificInfo.sessionId = static_cast<std::uint32_t>(session->getId());
|
||||
playerInfoResponseWithBullets.bullets = playerPositionBullet.bulletStruct;
|
||||
playerInfoResponseWithBullets.currentWeapon = playerPositionBullet.bulletStruct.bullet4;
|
||||
|
||||
PlayerInfoResponseComplete playerInfoResponseComplete{ playerInfoResponseWithBullets };
|
||||
playerInfoResponseComplete.playerInfoBasicResponse.specificInfo.enableJump = true;
|
||||
|
||||
playerInfoResponseComplete.jump = playerPositionComplete.jumpStruct;
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&playerInfoResponseComplete), sizeof(playerInfoResponseComplete));
|
||||
@@ -119,7 +121,7 @@ namespace Cast
|
||||
else
|
||||
{
|
||||
PlayerInfoBasicResponse playerInfoBasicResponse;
|
||||
playerInfoBasicResponse.tick = playerPositionFromClient.matchTick;
|
||||
// playerInfoBasicResponse.tick = playerPositionFromClient.matchTick;
|
||||
playerInfoBasicResponse.position = playerPositionFromClient.position;
|
||||
playerInfoBasicResponse.direction = playerPositionFromClient.direction;
|
||||
playerInfoBasicResponse.currentWeapon = playerPositionFromClient.weapon;
|
||||
@@ -129,7 +131,8 @@ namespace Cast
|
||||
playerInfoBasicResponse.rotation2 = request.getOption();
|
||||
playerInfoBasicResponse.rotation3 = playerPositionFromClient.rotation;
|
||||
playerInfoBasicResponse.specificInfo.sessionId = static_cast<std::uint32_t>(session->getId());
|
||||
|
||||
playerInfoBasicResponse.specificInfo.enableJump = false;
|
||||
playerInfoBasicResponse.specificInfo.enableBullet = false;
|
||||
|
||||
if (fullSize == 28)
|
||||
{
|
||||
@@ -139,7 +142,6 @@ namespace Cast
|
||||
{
|
||||
playerInfoBasicResponse.specificInfo.enableJump = true;
|
||||
PlayerInfoResponseWithJump playerInfoResponseWithJump{ playerInfoBasicResponse };
|
||||
|
||||
|
||||
Cast::Structures::ClientPlayerInfoJump playerPositionJump{};
|
||||
std::memcpy(&playerPositionJump, request.getData(), request.getDataSize());
|
||||
@@ -156,7 +158,8 @@ namespace Cast
|
||||
}
|
||||
|
||||
// reminder: this is correct, dont use exceptSelf as that causes log errors in SysLog (host receives [322] command not found)
|
||||
room->broadcastToRoom(response);
|
||||
// room->broadcastToRoom(response);
|
||||
room->enqueuePosition(std::move(response));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,10 @@ namespace Cast
|
||||
bool m_isInMatch{ 0 };
|
||||
std::string m_nickname;
|
||||
bool m_isInvisible{};
|
||||
Cast::Structures::ClientPlayerInfoBasic m_lastClientPosition{};
|
||||
std::uint32_t m_lastRotation1{};
|
||||
std::uint32_t m_lastRotation2{};
|
||||
std::uint32_t m_lastRotation3{};
|
||||
|
||||
public:
|
||||
explicit Session(asio::ip::tcp::socket&& socket, std::function<void(std::size_t)> fnct)
|
||||
|
||||
@@ -133,6 +133,13 @@ PACK_PUSH(1)
|
||||
{
|
||||
return position.isBadPos() || direction.isBadDir();
|
||||
}
|
||||
|
||||
bool hasMoved(const PositionStruct& newPos) const
|
||||
{
|
||||
return position.positionX != newPos.positionX ||
|
||||
position.positionY != newPos.positionY ||
|
||||
position.positionZ != newPos.positionZ;
|
||||
}
|
||||
};
|
||||
PACK_POP()
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ PACK_POP()
|
||||
PACK_PUSH(1)
|
||||
struct PlayerInfoBasicResponse
|
||||
{
|
||||
std::uint32_t tick{};
|
||||
// std::uint32_t tick{};
|
||||
SpecificInfo specificInfo{};
|
||||
Cast::Structures::PositionStruct position;
|
||||
Cast::Structures::DirectionStruct direction;
|
||||
@@ -50,7 +50,7 @@ PACK_POP()
|
||||
PACK_PUSH(1)
|
||||
struct PlayerInfoResponseWithBullets
|
||||
{
|
||||
std::uint32_t tick{};
|
||||
// std::uint32_t tick{};
|
||||
SpecificInfo specificInfo{};
|
||||
Cast::Structures::PositionStruct position;
|
||||
Cast::Structures::DirectionStruct direction;
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace Cast
|
||||
return parseDataImpl<T, Common::Network::UnecryptedPacket, Warn>(request, offset, location);
|
||||
}
|
||||
|
||||
bool mustBroadcastDeath(std::uint32_t mode)
|
||||
inline bool mustBroadcastDeath(std::uint32_t mode)
|
||||
{
|
||||
return (mode == Common::Enums::Elimination || mode == Common::Enums::CaptureTheBattery
|
||||
|| mode == Common::Enums::BombBattle || mode == Common::Enums::Clan_BombBattle
|
||||
|
||||
Reference in New Issue
Block a user