mirror of
https://github.com/microvolts/MicrovoltsEmulator
synced 2026-08-24 06:26:03 -04:00
refactoring
This commit is contained in:
parent
dd09cc932e
commit
35a94d1240
76 changed files with 1040 additions and 1623 deletions
|
|
@ -37,7 +37,6 @@ namespace Auth
|
|||
|
||||
if (ec)
|
||||
{
|
||||
std::cerr << "Error during read: " << ec.message() << std::endl;
|
||||
asio::error_code ec;
|
||||
socket.shutdown(asio::ip::tcp::socket::shutdown_both, ec);
|
||||
socket.close();
|
||||
|
|
@ -51,7 +50,6 @@ namespace Auth
|
|||
auto [ptr, ecc] = std::from_chars(response.data(), response.data() + response.size(), playerCount);
|
||||
if (ecc != std::errc{})
|
||||
{
|
||||
std::cerr << "Conversion error\n";
|
||||
asio::error_code ec;
|
||||
socket.shutdown(asio::ip::tcp::socket::shutdown_both, ec);
|
||||
socket.close();
|
||||
|
|
@ -62,7 +60,6 @@ namespace Auth
|
|||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr << "Exception: " << e.what() << std::endl;
|
||||
asio::error_code ec;
|
||||
socket.shutdown(asio::ip::tcp::socket::shutdown_both, ec);
|
||||
socket.close();
|
||||
|
|
|
|||
|
|
@ -25,33 +25,6 @@ namespace Cast
|
|||
public:
|
||||
Room() = default;
|
||||
|
||||
~Room()
|
||||
{
|
||||
// Just for debug.
|
||||
std::cout << "Room with number: " << m_roomNumber << " is being closed!\n";
|
||||
}
|
||||
|
||||
// Debug
|
||||
void printRoomState(const std::string& furtherInfo) const
|
||||
{
|
||||
/*
|
||||
std::cout << "____________________________\n";
|
||||
std::cout << furtherInfo << ":\n\n";
|
||||
std::cout << "Room Information:\n";
|
||||
std::cout << " Room Number: " << m_roomNumber << '\n';
|
||||
std::cout << "Players:\n";
|
||||
for (const auto& currentPlayer : m_players)
|
||||
{
|
||||
std::cout << " - SessionID: " << currentPlayer.first
|
||||
//<< "\n RoomID: " << currentPlayer.second->getRoomId()
|
||||
<< "\n RoomNum: " << currentPlayer.second->getRoomNumber()
|
||||
<< "\n Is In Match: " << (currentPlayer.second->isInMatch() ? "Yes" : "No") << '\n';
|
||||
}
|
||||
std::cout << "____________________________\n";
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
Room(std::uint64_t hostSessionId, Cast::Network::Session* hostSession);
|
||||
|
||||
std::uint32_t getRoomNumber() const;
|
||||
|
|
@ -90,10 +63,6 @@ namespace Cast
|
|||
|
||||
std::uint32_t getMode() const;
|
||||
|
||||
std::uint32_t getTick() const;
|
||||
|
||||
void setTick(std::uint32_t tick);
|
||||
|
||||
void leaveAllPLayers();
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ namespace Cast
|
|||
public:
|
||||
void addRoom(std::shared_ptr<Cast::Classes::Room> room, std::uint64_t playerId);
|
||||
|
||||
// Debug
|
||||
void printRoomInfo(std::uint64_t sessionId, const std::string& furtherInfo)
|
||||
{
|
||||
}
|
||||
|
|
@ -34,8 +33,6 @@ namespace Cast
|
|||
|
||||
void setMapFor(std::uint64_t playerId, std::uint32_t map);
|
||||
|
||||
void setModeFor(std::uint64_t hostId, std::uint32_t mode);
|
||||
|
||||
void endMatch(std::uint64_t hostId);
|
||||
|
||||
std::uint32_t getMapOf(std::uint64_t hostId);
|
||||
|
|
|
|||
|
|
@ -10,11 +10,8 @@ namespace Cast
|
|||
{
|
||||
inline void handleAccountNames(const Common::Network::Packet& request, Cast::Network::Session& session, Cast::Classes::RoomsManager& roomsManager)
|
||||
{
|
||||
std::cout << "OKKKKKKKKKKKKKKKKKKKKKK\n";
|
||||
// This should only be broadcast to players that are NOT inside the match, but inside the room!
|
||||
roomsManager.broadcastToRoomExceptSelf(session.getId(), const_cast<Common::Network::Packet&>(request)); // note: do not broadcast to self!
|
||||
|
||||
// roomsManager.printRoomInfo(session.getRoomId(), "after HandleAccountNames");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,10 +13,6 @@ namespace Cast
|
|||
{
|
||||
inline void handleCrash(const Common::Network::Packet& request, Cast::Network::Session& session, Cast::Classes::RoomsManager& roomsManager)
|
||||
{
|
||||
auto& logger = ::Utils::Logger::getInstance(true);
|
||||
logger.log<::Utils::LogDestination::File>("User crashed (SessionID: " + std::to_string(session.getId()) + ", RoomNum: "
|
||||
+ std::to_string(session.getRoomNumber()), ::Utils::LogType::Info, "handleCrash");
|
||||
|
||||
const auto selfSessionId = session.getId();
|
||||
const auto roomHostId = request.getSession();
|
||||
Main::Structures::UniqueId uniqueId{ selfSessionId, 4, 0 };
|
||||
|
|
@ -26,8 +22,6 @@ namespace Cast
|
|||
|
||||
// This sets is in match to false, roomNum to -1, removes player from room, removes player from roomsManager's unordered_map
|
||||
roomsManager.removePlayerFromRoom(session.getId());
|
||||
|
||||
//roomsManager.printRoomInfo(session.getRoomId(), "After CrashHandler");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,17 +10,12 @@ namespace Cast
|
|||
namespace Handlers
|
||||
{
|
||||
// Client sends packet to the host whenever someone joins their room
|
||||
|
||||
// Ok. checked
|
||||
inline void handlePlayerJoinRoom(const Common::Network::Packet& request, Cast::Network::Session& session, Cast::Classes::RoomsManager& roomsManager)
|
||||
{
|
||||
const std::uint64_t hostSessionId = request.getSession();
|
||||
const std::uint64_t selfSessionId = session.getId();
|
||||
|
||||
std::cout << "Player: " << selfSessionId << " attempting to join room of player: " << hostSessionId << '\n';
|
||||
roomsManager.switchRoomJoinOrExit(session, hostSessionId);
|
||||
|
||||
// roomsManager.printRoomInfo(session.getRoomId(), "after PlayerJoinRoom");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ namespace Cast
|
|||
inline void handleMatchEnd(const Common::Network::Packet& request, Cast::Network::Session& session, Cast::Classes::RoomsManager& roomsManager)
|
||||
{
|
||||
roomsManager.endMatch(session.getId());
|
||||
|
||||
// roomsManager.printRoomInfo(session.getRoomId(), "After HandleMatchEnd");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,19 +12,11 @@ namespace Cast
|
|||
inline void handleMatchLeave(const Common::Network::Packet& request, Cast::Network::Session& session, Cast::Classes::RoomsManager& roomsManager)
|
||||
{
|
||||
const auto selfSessionId = session.getId();
|
||||
|
||||
auto& logger = ::Utils::Logger::getInstance();
|
||||
logger.log("Player is leaving the match (SessionID: " + std::to_string(session.getId())
|
||||
+ ", roomNum: " + std::to_string(session.getRoomNumber()), ::Utils::LogType::Info, "handleMatchLeave");
|
||||
|
||||
Main::Structures::UniqueId uniqueId{ selfSessionId, 4, 0 };
|
||||
auto response = request;
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&uniqueId), sizeof(uniqueId));
|
||||
|
||||
session.setIsInMatch(false);
|
||||
|
||||
|
||||
//roomsManager.printRoomInfo(session.getRoomId(), "after PlayerLeaveMatch");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,20 +121,6 @@ namespace Cast
|
|||
}
|
||||
|
||||
roomsManager.broadcastToRoomExceptSelf(session.getId(), response);
|
||||
|
||||
response.setOrder(284);
|
||||
response.setMission(0);
|
||||
response.setOption(0);
|
||||
response.setExtra(52);
|
||||
struct Nickname
|
||||
{
|
||||
char nick[16] = "test1";
|
||||
} nick;
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&nick),sizeof(nick));
|
||||
if (session.getId() == 500)
|
||||
{
|
||||
roomsManager.broadcastToRoomExceptSelf(session.getId(), response);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,14 +16,9 @@ namespace Cast
|
|||
// 2. they don't respawn at all.
|
||||
inline void handlePlayerSyncWithRoom(const Common::Network::Packet& request, Cast::Network::Session& session, Cast::Classes::RoomsManager& roomsManager)
|
||||
{
|
||||
auto& logger = ::Utils::Logger::getInstance();
|
||||
logger.log("Getting player sync room info", ::Utils::LogType::Info, "handlePlayerSyncWithRoom");
|
||||
|
||||
const auto receiverSessionId = request.getSession();
|
||||
const auto hostSessionId = session.getId();
|
||||
roomsManager.hostForwardToPlayer(hostSessionId, receiverSessionId, const_cast<Common::Network::Packet&>(request));
|
||||
|
||||
// roomsManager.printRoomInfo(session.getRoomId(), "After handlePlayerSyncWithRoom");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,23 +41,15 @@ namespace Cast
|
|||
|
||||
const auto targetSessionId = playerRespawnPosition.targetUniqueId.session;
|
||||
roomsManager.broadcastToRoom(session.getId(), response);
|
||||
|
||||
// roomsManager.printRoomInfo(session.getRoomId(), "After handle Player Respawn");
|
||||
}
|
||||
|
||||
// Non host client requests host to respawn them
|
||||
inline void handlePlayerRespawnRequest(const Common::Network::Packet& request, Cast::Network::Session& session, Cast::Classes::RoomsManager& roomsManager)
|
||||
{
|
||||
auto& logger = ::Utils::Logger::getInstance(true);
|
||||
logger.log("Respawning player", ::Utils::LogType::Info, "handlePlayerRespawnRequest");
|
||||
|
||||
const auto roomHostSessionId = request.getSession();
|
||||
const auto selfSessionId = session.getId();
|
||||
|
||||
roomsManager.playerForwardToHost(roomHostSessionId, selfSessionId, const_cast<Common::Network::Packet&>(request));
|
||||
|
||||
//roomsManager.printRoomInfo(session.getRoomId(), "After handle Player Respawn Req");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@ namespace Cast
|
|||
// Create a room, add the player to id (sessionID=>Session pair).
|
||||
// Then, add the room to roomsManager. Pass the room and the sessionID of the player. Don't keep track that it's the host: the client does this for us in P2P.
|
||||
roomsManager.addRoom(std::make_shared<Cast::Classes::Room>(session.getId(), &session), session.getId());
|
||||
|
||||
// roomsManager.printRoomInfo(session.getRoomId(), "After RoomCreation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,7 @@ namespace Cast
|
|||
const auto receiverSessionId = request.getSession();
|
||||
const auto hostSessionId = session.getId();
|
||||
|
||||
std::cout << "Host: " << hostSessionId << " sending tick to: " << receiverSessionId << '\n';
|
||||
roomsManager.hostForwardToPlayer(hostSessionId, receiverSessionId, const_cast<Common::Network::Packet&>(request));
|
||||
|
||||
// roomsManager.printRoomInfo(session.getRoomId(), "After handle room tick providing");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,6 @@ namespace Cast
|
|||
*/
|
||||
inline void handleRoomTickSyncRequest(const Common::Network::Packet& request, Cast::Network::Session& session, Cast::Classes::RoomsManager& roomsManager)
|
||||
{
|
||||
std::cout << "Player: " << session.getId() << " asking Tick Request to: " << request.getSession() << '\n';
|
||||
|
||||
const auto roomHostSessionId = request.getSession();
|
||||
const auto selfSessionId = session.getId();
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ namespace Cast
|
|||
inline void leaveRoom(const Common::Network::Packet& request, Cast::Network::Session& session, Cast::Classes::RoomsManager& roomsManager)
|
||||
{
|
||||
roomsManager.switchRoomJoinOrExit(session);
|
||||
// roomsManager.printRoomInfo(session.getRoomId(), "After switch state handler");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,15 +14,10 @@ namespace Cast
|
|||
// This is a request from the client to get the Room Info (e.g. how many wins in which team, etc)
|
||||
inline void roomInfoHandler(const Common::Network::Packet& request, Cast::Network::Session& session, Cast::Classes::RoomsManager& roomsManager)
|
||||
{
|
||||
auto& logger = ::Utils::Logger::getInstance();
|
||||
logger.log("Room Info Handler...", ::Utils::LogType::Info, "roomInfoHandler");
|
||||
|
||||
const auto roomHostSessionId = request.getSession();
|
||||
const auto selfSessionId = session.getId();
|
||||
// roomsManager.playerForwardToHost(session.getRoomId(), selfSessionId, const_cast<Common::Network::Packet&>(request));
|
||||
// This command does NOT exist in the client! [order = 255]
|
||||
|
||||
// roomsManager.printRoomInfo(session.getRoomId(), "After room info handler");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,16 +17,11 @@ namespace Cast
|
|||
{
|
||||
inline void handleMatchStart(const Common::Network::Packet& request, Cast::Network::Session& session, Cast::Classes::RoomsManager& roomsManager)
|
||||
{
|
||||
auto& logger = ::Utils::Logger::getInstance();
|
||||
logger.log("Handling match start", ::Utils::LogType::Info, "handleMatchStart");
|
||||
|
||||
session.setIsInMatch(true);
|
||||
|
||||
auto mapIdInfoFromMain = ::Utils::IPCManager::ipc_castGetFromMain<::Utils::MapInfo>(std::to_string(session.getRoomNumber()), "map_info");
|
||||
roomsManager.setMapFor(mapIdInfoFromMain.hostId, mapIdInfoFromMain.mapId);
|
||||
std::cout << "Map Host From Main: " << mapIdInfoFromMain.hostId << ", map ID: " << mapIdInfoFromMain.mapId << '\n';
|
||||
|
||||
|
||||
|
||||
const auto receiverSessionId = request.getSession();
|
||||
const auto hostSessionId = session.getId();
|
||||
|
||||
|
|
@ -36,25 +31,16 @@ namespace Cast
|
|||
// And if we resend this packet to the host client, it resets the score to 0... so we just avoid doing that.
|
||||
if (hostSessionId != receiverSessionId)
|
||||
{
|
||||
logger.log("session.getRoomId() != receiverSessionId", ::Utils::LogType::Info, "handleMatchStart");
|
||||
roomsManager.hostForwardToPlayer(hostSessionId, receiverSessionId, const_cast<Common::Network::Packet&>(request));
|
||||
}
|
||||
|
||||
//roomsManager.printRoomInfo(session.getRoomId(), "After Handle Match Start");
|
||||
}
|
||||
|
||||
// order 94
|
||||
inline void unknownHandler3(const Common::Network::Packet& request, Cast::Network::Session& session, Cast::Classes::RoomsManager& roomsManager)
|
||||
{
|
||||
auto& logger = ::Utils::Logger::getInstance();
|
||||
logger.log("Unknown Handler 3", ::Utils::LogType::Info, "unknownHandler3");
|
||||
|
||||
const auto receiverSessionId = request.getSession();
|
||||
const auto hostSessionId = session.getId();
|
||||
|
||||
roomsManager.broadcastToRoomExceptSelf(hostSessionId, const_cast<Common::Network::Packet&>(request));
|
||||
|
||||
//roomsManager.printRoomInfo(session.getRoomId(), "After unknownHandler3");
|
||||
}
|
||||
|
||||
inline void unknownHandler306(const Common::Network::Packet& request, Cast::Network::Session& session, Cast::Classes::RoomsManager& roomsManager)
|
||||
|
|
@ -63,10 +49,6 @@ namespace Cast
|
|||
const auto receiverSessionId = request.getSession();
|
||||
const auto hostSessionId = session.getId();
|
||||
roomsManager.hostForwardToPlayer(hostSessionId, receiverSessionId, const_cast<Common::Network::Packet&>(request));
|
||||
|
||||
std::cout << "(unknownHandler306) HostSessionID: " << hostSessionId << " => playerSessionID: " << receiverSessionId << '\n';
|
||||
|
||||
// roomsManager.printRoomInfo(session.getRoomId(), "After unknownHandler306");
|
||||
}
|
||||
|
||||
// CTB battery respawn when host changes, Bomb battle bomb plant,
|
||||
|
|
@ -82,11 +64,6 @@ namespace Cast
|
|||
const auto hostSessionId = request.getSession();
|
||||
const auto selfId = session.getId();
|
||||
roomsManager.playerForwardToHost(hostSessionId, selfId, const_cast<Common::Network::Packet&>(request));
|
||||
//roomsManager.broadcastToRoom(session.getId(), const_cast<Common::Network::Packet&>(request));
|
||||
|
||||
std::cout << "(unknownHandler90) HostSessionID: " << hostSessionId << " => playerSessionID: " << selfId << '\n';
|
||||
|
||||
// roomsManager.printRoomInfo(session.getRoomId(), "After unknownHandler306");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,10 +18,6 @@ namespace Cast
|
|||
hostSession->setRoomId(hostSessionId);
|
||||
m_roomNumber = ++idCounter;
|
||||
hostSession->setRoomNumber(m_roomNumber);
|
||||
|
||||
auto& logger = ::Utils::Logger::getInstance();
|
||||
logger.log("Creating Room. Added Host (ID: " + std::to_string(hostSessionId)
|
||||
+ ", RoomNumber: " + std::to_string(hostSession->getRoomNumber()) + ")", ::Utils::LogType::Info, "Room::Room");
|
||||
}
|
||||
|
||||
std::uint32_t Room::getRoomNumber() const
|
||||
|
|
@ -71,11 +67,10 @@ namespace Cast
|
|||
{
|
||||
if (!m_players.contains(playerSessionId))
|
||||
{
|
||||
std::cout << "Room::removePlayer: player not found\n";
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "removing player from room: " << m_players[playerSessionId]->getRoomNumber() << "\n";
|
||||
m_players[playerSessionId]->setIsInMatch(false);
|
||||
m_players[playerSessionId]->setRoomNumber(-1);
|
||||
m_players.erase(playerSessionId);
|
||||
|
|
@ -100,10 +95,6 @@ namespace Cast
|
|||
|
||||
void Room::addPlayer(Cast::Network::Session* playerSession)
|
||||
{
|
||||
auto& logger = ::Utils::Logger::getInstance(true);
|
||||
logger.log("Added playerID: " + std::to_string(playerSession->getId())
|
||||
+ " to room number: " + std::to_string(m_roomNumber), ::Utils::LogType::Info, "Room::addPlayer");
|
||||
|
||||
// Check whether m_players or m_observerPlayers is full?
|
||||
m_players[playerSession->getId()] = playerSession;
|
||||
m_playersVec.push_back(playerSession);
|
||||
|
|
@ -143,24 +134,16 @@ namespace Cast
|
|||
|
||||
void Room::playerForwardToHost(std::uint64_t hostSessionId, std::uint64_t senderSessionId, Common::Network::Packet& packet)
|
||||
{
|
||||
auto& logger = ::Utils::Logger::getInstance();
|
||||
|
||||
packet.setTcpHeader(senderSessionId, Common::Enums::NO_ENCRYPTION);
|
||||
|
||||
if (m_players.contains(hostSessionId))
|
||||
{
|
||||
m_players[hostSessionId]->asyncWrite(packet);
|
||||
|
||||
logger.log("Forwarding Packet from SenderSessionID: " + std::to_string(senderSessionId) +
|
||||
" to Room Host SessionID: " + std::to_string(hostSessionId), ::Utils::LogType::Info, "Room::playerForwardToHost");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Room::hostForwardToPlayer(std::uint64_t hostSessionId, std::uint64_t playerId, Common::Network::Packet& packet, bool useHostIdInTcpHeader)
|
||||
{
|
||||
auto& logger = ::Utils::Logger::getInstance();
|
||||
|
||||
if (useHostIdInTcpHeader)
|
||||
{
|
||||
packet.setTcpHeader(hostSessionId, Common::Enums::NO_ENCRYPTION);
|
||||
|
|
@ -172,9 +155,6 @@ namespace Cast
|
|||
if (m_players.contains(playerId))
|
||||
{
|
||||
m_players[playerId]->asyncWrite(packet);
|
||||
|
||||
logger.log("Forwarding Packet from Host: " + std::to_string(hostSessionId) +
|
||||
" to Player SessionID: " + std::to_string(playerId), ::Utils::LogType::Info, "Room::hostForwardToPlayer");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -208,30 +188,6 @@ namespace Cast
|
|||
++totalInMatch;
|
||||
}
|
||||
}
|
||||
|
||||
if (totalInMatch == 1)
|
||||
{
|
||||
if (m_mode == Common::Enums::SquareMode || m_mode == Common::Enums::AiBattle || m_mode == Common::Enums::BossBattle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (auto& player : m_playersVec)
|
||||
{
|
||||
player->setIsInMatch(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Room::setTick(std::uint32_t tick)
|
||||
{
|
||||
m_tick = tick;
|
||||
std::cout << "tick set to : " << tick << '\n';
|
||||
}
|
||||
|
||||
std::uint32_t Room::getTick() const
|
||||
{
|
||||
return m_tick;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ namespace Cast
|
|||
{
|
||||
void RoomsManager::addRoom(std::shared_ptr<Cast::Classes::Room> room, std::uint64_t playerId)
|
||||
{
|
||||
std::cout << "[addRoom] New room created. RoomNumber: " << room->getRoomNumber() << ", playerID: " << playerId << '\n';
|
||||
m_playerSessionIdToRoom[playerId] = room;
|
||||
}
|
||||
|
||||
|
|
@ -19,7 +18,6 @@ namespace Cast
|
|||
// Otherwise, they join it.
|
||||
if (m_playerSessionIdToRoom.contains(session.getId()))
|
||||
{
|
||||
std::cout << "SwitchRoomJoinOrExit: Found player inside a room. Removing it.\n";
|
||||
// The player identified by "session" is inside the room where the host's sessionId equals "roomId", thus the room exists
|
||||
removePlayerFromRoom(session.getId());
|
||||
}
|
||||
|
|
@ -74,15 +72,6 @@ namespace Cast
|
|||
room->setMap(map);
|
||||
}
|
||||
|
||||
/*
|
||||
void RoomsManager::setModeFor(std::uint64_t hostId, std::uint32_t mode)
|
||||
{
|
||||
if (!m_roomsByHostSessionId.contains(hostId)) return;
|
||||
auto& room = m_roomsByHostSessionId[hostId];
|
||||
room.setMode(mode);
|
||||
std::cout << "MODE HAS BEEN SET TO: " << mode << "\n";
|
||||
}*/
|
||||
|
||||
bool RoomsManager::exists(std::uint64_t playerId)
|
||||
{
|
||||
return m_playerSessionIdToRoom.contains(playerId);
|
||||
|
|
@ -109,17 +98,14 @@ namespace Cast
|
|||
{
|
||||
if (m_playerSessionIdToRoom.contains(sessionId))
|
||||
{
|
||||
std::cout << "Room found, match end: leaving all players...\n";
|
||||
m_playerSessionIdToRoom[sessionId]->endMatch();
|
||||
}
|
||||
}
|
||||
|
||||
void RoomsManager::leaveAllPlayers(std::uint64_t sessionId)
|
||||
{
|
||||
std::cout << "Inside leaveAllPlayers\n";
|
||||
if (m_playerSessionIdToRoom.contains(sessionId))
|
||||
{
|
||||
std::cout << "Room found, leaving all players...\n";
|
||||
m_playerSessionIdToRoom[sessionId]->leaveAllPLayers();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,6 @@ namespace Cast
|
|||
|
||||
void Session::setIsInMatch(bool val)
|
||||
{
|
||||
std::cout << "Set Is In Match set to: " << val << " for sessionID: " << m_id << '\n';
|
||||
m_isInMatch = val;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -18,23 +18,15 @@ namespace Cast
|
|||
|
||||
void SessionsManager::addSession(Cast::Network::Session* session, std::size_t sessionId)
|
||||
{
|
||||
auto& logger = ::Utils::Logger::getInstance(true, false, "cast_log.txt");
|
||||
logger.log<::Utils::LogDestination::File>("Trying to add session with ID: " + std::to_string(sessionId), ::Utils::LogType::Info, "SessionsManager::addSession");
|
||||
|
||||
if (!m_sessionsBySessionId.contains(sessionId))
|
||||
{
|
||||
m_sessionsBySessionId.emplace(sessionId, session);
|
||||
session->setSessionId(sessionId);
|
||||
|
||||
logger.log<::Utils::LogDestination::File>("Added session with ID: " + std::to_string(sessionId), ::Utils::LogType::Info, "SessionsManager::addSession");
|
||||
}
|
||||
}
|
||||
|
||||
void SessionsManager::removeSession(std::size_t sessionId)
|
||||
{
|
||||
auto& logger = ::Utils::Logger::getInstance(true);
|
||||
logger.log("Trying to remove SessionID: " + std::to_string(sessionId), ::Utils::LogType::Info, "SessionsManager::removeSession");
|
||||
|
||||
// The player is inside a room.
|
||||
if (m_sessionsBySessionId.contains(sessionId) && m_sessionsBySessionId[sessionId]->getRoomNumber() != -1)
|
||||
{
|
||||
|
|
@ -42,7 +34,6 @@ namespace Cast
|
|||
if (m_sessionsBySessionId.contains(sessionId))
|
||||
{
|
||||
m_sessionsBySessionId.erase(sessionId);
|
||||
logger.log<::Utils::LogDestination::File>("Session removed from sessions list: " + std::to_string(sessionId), ::Utils::LogType::Info, "SessionsManager::removeSession");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -56,10 +56,6 @@ namespace Common
|
|||
auto entries = cdbWeapon.getEntries();
|
||||
for (const auto& [id, structType] : entries)
|
||||
{
|
||||
if (m_itemByType.contains(structType.ii_id))
|
||||
{
|
||||
std::cout << "Item Already Contained in FirstLoop\n";
|
||||
}
|
||||
m_itemByType[structType.ii_id] = structType.ii_type;
|
||||
}
|
||||
|
||||
|
|
@ -68,10 +64,6 @@ namespace Common
|
|||
auto entries2 = cdbItem.getEntries();
|
||||
for (const auto& [id, structType] : entries2)
|
||||
{
|
||||
if (m_itemByType.contains(structType.ii_id))
|
||||
{
|
||||
std::cout << "Item Already Contained in SecondLoop\n";
|
||||
}
|
||||
m_itemByType[structType.ii_id] = structType.ii_type;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -267,7 +267,7 @@
|
|||
<ClInclude Include="include\Structures\AccountInfo\MainAccountInfo.h" />
|
||||
<ClInclude Include="include\Structures\AccountInfo\MainAccountUniqueId.h" />
|
||||
<ClInclude Include="include\Structures\AccountInfo\MuteInfo.h" />
|
||||
<ClInclude Include="include\Structures\ClientData\PingData.h" />
|
||||
<ClInclude Include="include\Structures\ClientData\Structures.h" />
|
||||
<ClInclude Include="include\Structures\PlayerLists\BlockedPlayer.h" />
|
||||
<ClInclude Include="include\Structures\Capsule\CapsuleList.h" />
|
||||
<ClInclude Include="include\Structures\Capsule\CapsuleSpin.h" />
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@
|
|||
<ClInclude Include="include\Boxes\MpBox.h" />
|
||||
<ClInclude Include="include\Network\AuthSession.h" />
|
||||
<ClInclude Include="include\Handlers\CapsuleReqHandler.h" />
|
||||
<ClInclude Include="include\Structures\ClientData\PingData.h" />
|
||||
<ClInclude Include="include\Structures\ClientData\Structures.h" />
|
||||
<ClInclude Include="include\Handlers\Item\ItemAndCapsuleHandler.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -63,7 +63,6 @@ namespace Main
|
|||
{
|
||||
const auto mapInfoMap = cdbMapInfo::getInstance().getEntry(itemId);
|
||||
if (mapInfoMap == std::nullopt) return std::nullopt;
|
||||
std::cout << "Name: " << mapInfoMap.value().mi_name << ", height: " << mapInfoMap.value().mi_death_height << '\n';
|
||||
return mapInfoMap.value().mi_death_height;
|
||||
}
|
||||
|
||||
|
|
@ -87,6 +86,16 @@ namespace Main
|
|||
return itemDurability;
|
||||
}
|
||||
|
||||
std::optional<std::uint16_t> getItemRefundPrice() const
|
||||
{
|
||||
const auto refundValue = getRefundValue(cdbItems::getInstance());
|
||||
if (refundValue == std::nullopt)
|
||||
{
|
||||
return getRefundValue(cdbWeapons::getInstance());
|
||||
}
|
||||
return refundValue;
|
||||
}
|
||||
|
||||
std::optional<Common::ConstantDatabase::CdbRewardInfo> getRewardInfoForMode(std::uint32_t mode) const
|
||||
{
|
||||
auto entry = cdbRewardInfo::getInstance().getEntry("ri_mod", mode);
|
||||
|
|
@ -167,25 +176,6 @@ namespace Main
|
|||
return entry->ui_parentid;
|
||||
}
|
||||
|
||||
/*
|
||||
std::vector<Main::Structures::CapsuleList> getCapsuleItems(std::uint32_t maxItems)
|
||||
{
|
||||
m_maxCapsuleItems = maxItems;
|
||||
//auto entries = cdbCapsuleInfos::getInstance().getEntries();
|
||||
auto entries = cdbCapsulePackageInfos::getInstance().getEntries();
|
||||
std::vector<Main::Structures::CapsuleList> ret;
|
||||
for (std::size_t total = 0; const auto& [id, capsuleInfoStruct] : entries)
|
||||
{
|
||||
std::cout << "CapsuleID: " << capsuleInfoStruct.gi_id << '\n';
|
||||
if (total >= maxItems) break;
|
||||
//ret.push_back(Main::Structures::CapsuleList{ static_cast<std::uint32_t>(capsuleInfoStruct.gi_id), static_cast<std::uint32_t>(capsuleInfoStruct.gi_price) });
|
||||
ret.push_back(Main::Structures::CapsuleList{ static_cast<std::uint32_t>(capsuleInfoStruct.gi_id) });
|
||||
++total;
|
||||
}
|
||||
return ret;
|
||||
}*/
|
||||
|
||||
|
||||
std::optional<Common::ConstantDatabase::CdbCapsuleInfo> getCapsuleInfoById(std::uint32_t gi_id) const
|
||||
{
|
||||
const auto& entries = cdbCapsuleInfos::getInstance().getEntries();
|
||||
|
|
@ -206,8 +196,6 @@ namespace Main
|
|||
for (std::size_t total = 0; const auto & [id, capsuleInfoStruct] : cdbCapsuleInfos::getInstance().getEntries())
|
||||
{
|
||||
if (total == m_maxCapsuleItems) break;
|
||||
// assume max index = MP = 2
|
||||
//averageCosts[capsuleInfoStruct.gi_type] += capsuleInfoStruct.gi_price;
|
||||
++totalCapsuleTypesByCurrency[capsuleInfoStruct.gi_type];
|
||||
}
|
||||
averageCosts[0] /= totalCapsuleTypesByCurrency[0];
|
||||
|
|
@ -314,6 +302,14 @@ namespace Main
|
|||
if (entry == std::nullopt) return std::nullopt;
|
||||
return entry->ii_durable_value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::optional<std::uint16_t> getRefundValue(const Common::ConstantDatabase::Cdb<T>& cdb) const
|
||||
{
|
||||
const std::optional<T> entry = cdb.getEntry("ii_id", itemId);
|
||||
if (entry == std::nullopt) return std::nullopt;
|
||||
return entry->ii_sell_point;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ namespace Main
|
|||
std::string m_mutedBy;
|
||||
std::string m_muteReason;
|
||||
std::string m_mutedUntil;
|
||||
bool m_isInLobby{ true };
|
||||
|
||||
// Mailbox specific
|
||||
std::vector<Mailbox> m_mailboxReceived{};
|
||||
|
|
@ -71,7 +70,6 @@ namespace Main
|
|||
const char* const getPlayerName() const;
|
||||
void setAccountRockTotens(std::uint32_t rt);
|
||||
void setAccountMicroPoints(std::uint32_t mp);
|
||||
void setAccountCoins(std::uint16_t coins);
|
||||
void setAccountLatestCharacterSelected(std::uint16_t latestCharacterSelected);
|
||||
void setLevel(std::uint16_t level);
|
||||
void setPlayerName(const char* playerName);
|
||||
|
|
@ -83,7 +81,6 @@ namespace Main
|
|||
std::uint32_t getLuckyPoints() const;
|
||||
void setPing(std::uint16_t ping);
|
||||
std::uint16_t getPing() const;
|
||||
void setIsInLobby(bool val);
|
||||
bool isInLobby() const;
|
||||
void mute(const std::string& reason, const std::string& mutedBy, const std::string& mutedUntil);
|
||||
void unmute();
|
||||
|
|
@ -155,8 +152,7 @@ namespace Main
|
|||
|
||||
std::string getPlayerInfoAsString() const
|
||||
{
|
||||
return "(PlayerName: " + std::string(m_accountInfo.nickname) + ", RoomNumber: " + std::to_string(m_roomNumber) + ", IsInMatch : " + std::to_string(m_isInMatch)
|
||||
+ ", IsInLobby: " + std::to_string(m_isInLobby) + ")";
|
||||
return "(PlayerName: " + std::string(m_accountInfo.nickname) + ", RoomNumber: " + std::to_string(m_roomNumber) + ", IsInMatch : " + std::to_string(m_isInMatch) + "\n";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,12 @@ namespace Main
|
|||
class Room
|
||||
{
|
||||
private:
|
||||
struct MapValue
|
||||
{
|
||||
Main::Network::Session* session;
|
||||
Main::Structures::RoomPlayerInfo* playerInfo;
|
||||
};
|
||||
|
||||
inline static std::uint16_t idCounter{};
|
||||
|
||||
std::uint64_t m_tick{};
|
||||
|
|
@ -35,6 +41,8 @@ namespace Main
|
|||
Main::Structures::RoomSettings m_settings{};
|
||||
std::vector<std::pair<Main::Structures::RoomPlayerInfo, Main::Network::Session*>> m_players{};
|
||||
std::vector<std::pair<Main::Structures::RoomPlayerInfo, Main::Network::Session*>> m_observerPlayers{};
|
||||
std::unordered_map<std::uint32_t, std::size_t> m_playerSessionIdToVecIdx{};
|
||||
std::unordered_map<std::uint32_t, std::size_t> m_obsPlayerSessionIdToVecIdx{};
|
||||
std::vector<std::uint32_t> m_kickedPlayerAccountIds{};
|
||||
|
||||
// Points
|
||||
|
|
@ -44,6 +52,9 @@ namespace Main
|
|||
// Other
|
||||
bool m_isMuted = false;
|
||||
|
||||
private:
|
||||
Main::Structures::RoomPlayerInfo createRoomPlayerInfo(Main::Network::Session* session, std::uint32_t team) const;
|
||||
|
||||
public:
|
||||
Room() = default;
|
||||
explicit Room(const std::string& title, const Main::Structures::RoomSettings& settings, const Main::Structures::RoomPlayerInfo& player, Main::Network::Session* session);
|
||||
|
|
@ -54,124 +65,72 @@ namespace Main
|
|||
+ ", TotalPlayers: " + std::to_string(m_players.size()) + ", TotalObserverPlayers: " + std::to_string(m_observerPlayers.size()) + ")";
|
||||
}
|
||||
|
||||
Main::Network::Session* getHost() { return m_players[0].second; }
|
||||
Main::Network::Session* getPlayer(const Main::Structures::UniqueId& uniqueId);
|
||||
void addObserverPlayer(Main::Network::Session* session);
|
||||
// Setters
|
||||
void addPlayer(Main::Network::Session* session, std::uint32_t team);
|
||||
void addObserverPlayer(Main::Network::Session* session);
|
||||
void removeAllPlayers();
|
||||
void updatePlayerInfo(Main::Network::Session* session);
|
||||
void addKickedPlayer(std::uint32_t accountId);
|
||||
bool removeHostFromMatch();
|
||||
bool removePlayer(Main::Network::Session* session, std::uint32_t extra);
|
||||
void breakroom();
|
||||
bool changeHost(std::size_t newHostIdx);
|
||||
void updatePlayersTeamToTeamBased();
|
||||
void updatePlayersTeamToNonTeamBased();
|
||||
void setStateFor(const Main::Structures::UniqueId& uniqueId, const Common::Enums::PlayerState& playerState);
|
||||
void setPlayersPerTeam(std::uint16_t playersPerTeam);
|
||||
bool kickPlayer(const std::string& name);
|
||||
void startMatch(const Main::Structures::UniqueId& uniqueId);
|
||||
void endMatch();
|
||||
void updateMap(std::uint16_t newMap);
|
||||
void updateRoomSettings(const Main::Structures::RoomSettingsUpdateBase& newRoomSettings, std::uint16_t newMode);
|
||||
void updateTitle(const std::string& newTitle);
|
||||
void updatePassword(const std::string& newPassword);
|
||||
void setPassword(const std::string& password);
|
||||
void addPoint(std::uint32_t team);
|
||||
void sendTo(const Main::Structures::UniqueId& uniqueId, const Common::Network::Packet& packet);
|
||||
void storeEndMatchStatsFor(const Main::Structures::UniqueId& uniqueId, const Main::Structures::ScoreboardResponse& stats,
|
||||
std::uint32_t blueScore, std::uint32_t redScore, bool hasLeveledUp);
|
||||
void setSpecificSetting(std::uint8_t setting);
|
||||
void setTime(std::uint16_t time);
|
||||
std::optional<std::uint32_t> changePlayerTeam(const Main::Structures::UniqueId& uniqueId, std::uint32_t newTeam);
|
||||
|
||||
void muteRoom();
|
||||
|
||||
void unmuteRoom();
|
||||
|
||||
void unmuteRoom();
|
||||
bool isMuted() const;
|
||||
|
||||
void removeAllPlayers();
|
||||
|
||||
Main::Network::Session* getPlayer(const Main::Structures::UniqueId& uniqueId);
|
||||
std::uint32_t getBestMsIndexExceptSelf(bool checkIsInMatch, std::uint64_t selfId);
|
||||
|
||||
void setTick(std::uint64_t tick);
|
||||
|
||||
std::uint64_t getTick() const { return m_tick; }
|
||||
|
||||
std::uint32_t getPlayerIdx(std::uint64_t playerIndex) const;
|
||||
|
||||
void setPassword(const std::string& password);
|
||||
|
||||
const std::string& getPassword() const;
|
||||
|
||||
std::uint16_t getRoomNumber() const;
|
||||
|
||||
void updatePlayerInfo(Main::Network::Session* session);
|
||||
|
||||
void addKickedPlayer(std::uint32_t accountId);
|
||||
|
||||
bool removeHostFromMatch();
|
||||
|
||||
bool removePlayer(Main::Network::Session* session, std::uint32_t extra);
|
||||
|
||||
bool changeHostByNickname(const std::string&);
|
||||
|
||||
std::vector<Main::Structures::RoomPlayerInfo> getAllPlayers() const;
|
||||
|
||||
|
||||
Main::Structures::SingleRoom getRoomInfo() const;
|
||||
|
||||
const Main::Structures::RoomSettings& getRoomSettings() const;
|
||||
|
||||
Main::Structures::RoomJoin getRoomJoinInfo() const;
|
||||
|
||||
std::vector<Main::Structures::RoomPlayerItems> getPlayersItems() const;
|
||||
|
||||
std::vector<Main::Structures::PlayerClan> getPlayersClans() const;
|
||||
|
||||
void breakroom();
|
||||
bool isHost(const Main::Structures::UniqueId& uniqueId) const;
|
||||
Common::Enums::Team calculateNewPlayerTeam() const;
|
||||
bool isModeTeamBased() const;
|
||||
std::uint8_t getSpecificSetting() const;
|
||||
const std::string& getRoomTitle() const;
|
||||
bool isRoomFullObserverExcluded() const;
|
||||
bool hasMatchStarted() const;
|
||||
bool isObserverFull() const;
|
||||
std::size_t getPlayersCount() const;
|
||||
std::uint32_t getHostLevel() const;
|
||||
bool wasPreviouslyKicked(std::uint32_t accountId) const;
|
||||
Main::Structures::RoomSettingsUpdateTitlePassword getRoomSettingsUpdate() const;
|
||||
Main::Network::Session::AccountInfo getAccountInfoFor(const Main::Structures::UniqueId& uniqueId) const;
|
||||
|
||||
void broadcastToRoom(Common::Network::Packet& packet);
|
||||
|
||||
void broadcastToReady(Common::Network::Packet& packet)
|
||||
{
|
||||
for (auto& [roomInfo, session] : m_players)
|
||||
{
|
||||
if (roomInfo.state == Common::Enums::STATE_READY)
|
||||
{
|
||||
packet.setTcpHeader(session->getSessionId(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
session->asyncWrite(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void broadcastToRoomExceptSelf(Common::Network::Packet& packet, const Main::Structures::UniqueId& uniqueId);
|
||||
|
||||
// In-room chat messages
|
||||
void broadcastToTeamExceptSelf(Common::Network::Packet& packet, const Main::Structures::UniqueId& uniqueId, bool inMatch);
|
||||
void broadcastToMatchExceptSelf(Common::Network::Packet& packet, const Main::Structures::UniqueId& uniqueId, std::uint32_t extra);
|
||||
void broadcastOutsideMatchExceptSelf(Common::Network::Packet& packet, const Main::Structures::UniqueId& selfUniqueId, std::uint32_t extra);
|
||||
|
||||
bool changeHost(std::size_t newHostIdx);
|
||||
|
||||
void setCurrentHostAsOriginalHost();
|
||||
|
||||
bool isHost(const Main::Structures::UniqueId& uniqueId) const;
|
||||
|
||||
void setSpecificSetting(std::uint8_t setting);
|
||||
|
||||
void setTime(std::uint16_t time);
|
||||
|
||||
std::optional<std::uint32_t> changePlayerTeam(const Main::Structures::UniqueId& uniqueId, std::uint32_t newTeam);
|
||||
|
||||
void updatePlayersTeamToTeamBased();
|
||||
|
||||
void updatePlayersTeamToNonTeamBased();
|
||||
|
||||
Common::Enums::Team calculateNewPlayerTeam() const;
|
||||
|
||||
bool isModeTeamBased() const;
|
||||
|
||||
void setPlayersPerTeam(std::uint16_t playersPerTeam);
|
||||
|
||||
std::uint8_t getSpecificSetting() const;
|
||||
|
||||
const std::string& getRoomTitle() const;
|
||||
|
||||
bool kickPlayer(const std::string& name);
|
||||
|
||||
bool isRoomFullObserverExcluded() const;
|
||||
|
||||
void setStateFor(const Main::Structures::UniqueId& uniqueId, const Common::Enums::PlayerState& playerState);
|
||||
|
||||
void startMatch(const Main::Structures::UniqueId& uniqueId);
|
||||
|
||||
void endMatch();
|
||||
|
||||
bool hasMatchStarted() const;
|
||||
|
||||
bool isObserverFull() const;
|
||||
|
||||
std::size_t getPlayersCount() const;
|
||||
|
||||
std::uint32_t getHostLevel() const;
|
||||
|
||||
bool wasPreviouslyKicked(std::uint32_t accountId) const;
|
||||
|
||||
template<Main::Enums::RoomSimpleSetting T> requires (T == Main::Enums::SETTING_ITEM)
|
||||
void switchSimpleSetting()
|
||||
|
|
@ -196,25 +155,6 @@ namespace Main
|
|||
{
|
||||
m_settings.isObserverModeOn = ~m_settings.isObserverModeOn;
|
||||
}
|
||||
|
||||
void updateMap(std::uint16_t newMap);
|
||||
|
||||
void updateRoomSettings(const Main::Structures::RoomSettingsUpdateBase& newRoomSettings, std::uint16_t newMode);
|
||||
|
||||
Main::Structures::RoomSettingsUpdateTitlePassword getRoomSettingsUpdate() const;
|
||||
|
||||
void updateTitle(const std::string& newTitle);
|
||||
|
||||
void updatePassword(const std::string& newPassword);
|
||||
|
||||
void addPoint(std::uint32_t team);
|
||||
|
||||
void sendTo(const Main::Structures::UniqueId& uniqueId, const Common::Network::Packet& packet);
|
||||
|
||||
void storeEndMatchStatsFor(const Main::Structures::UniqueId& uniqueId, const Main::Structures::ScoreboardResponse& stats,
|
||||
std::uint32_t blueScore, std::uint32_t redScore, bool hasLeveledUp);
|
||||
|
||||
Main::Network::Session::AccountInfo getAccountInfoFor(const Main::Structures::UniqueId& uniqueId) const;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Main
|
|||
|
||||
std::vector<Main::Structures::SingleRoom> getRoomsList() const;
|
||||
|
||||
std::optional<std::reference_wrapper<Main::Classes::Room>> getRoomByNumber(std::uint16_t roomNumber);
|
||||
Main::Classes::Room* getRoomByNumber(std::uint16_t roomNumber);
|
||||
|
||||
void broadcastToRoom(std::uint16_t roomNumber, Common::Network::Packet& packet);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ namespace Main
|
|||
inline void handleCapsuleReq(const Common::Network::Packet& request, Main::Network::Session& session, Main::Classes::RoomsManager& roomsManager)
|
||||
{
|
||||
// capsules are all completely client sided
|
||||
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setOrder(83);
|
||||
|
|
|
|||
|
|
@ -9,10 +9,8 @@ namespace Main
|
|||
{
|
||||
namespace Handlers
|
||||
{
|
||||
inline void handleItemDelete(const Common::Network::Packet& request, Main::Network::Session& session)
|
||||
inline void handleItemDelete(const Common::Network::Packet& request, Main::Network::Session& session, const Main::Structures::ItemSerialInfo& itemSerialInfoToDelete)
|
||||
{
|
||||
Main::Structures::ItemSerialInfo itemSerialInfoToDelete{};
|
||||
std::memcpy(&itemSerialInfoToDelete, request.getData(), sizeof(itemSerialInfoToDelete));
|
||||
session.deleteItem(itemSerialInfoToDelete);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace Main
|
|||
namespace Handlers
|
||||
{
|
||||
inline void handleGeneralItem(const Common::Network::Packet& request, Main::Network::Session& session, Main::Persistence::PersistentDatabase& db,
|
||||
const std::unordered_map<std::uint32_t, std::unique_ptr<Main::Box::IBox>>& m_boxes)
|
||||
const std::unordered_map<std::uint32_t, std::unique_ptr<Main::Box::IBox>>& m_boxes, const Main::Structures::ItemSerialInfo& openedItemSerialInfo)
|
||||
{
|
||||
if (request.getMission() == 2) // capsule spin
|
||||
{
|
||||
|
|
@ -24,20 +24,15 @@ namespace Main
|
|||
}
|
||||
else
|
||||
{
|
||||
Main::Structures::ItemSerialInfo openedItemSerialInfo;
|
||||
std::memcpy(&openedItemSerialInfo, request.getData(), request.getDataSize());
|
||||
const auto& userItems = session.getItems();
|
||||
|
||||
auto response = request;
|
||||
response.setOption(1);
|
||||
|
||||
if (userItems.contains(openedItemSerialInfo.itemNumber))
|
||||
{
|
||||
const auto& item = userItems.at(openedItemSerialInfo.itemNumber);
|
||||
if (m_boxes.contains(item.id))
|
||||
{
|
||||
auto response = request;
|
||||
|
||||
if (item.id >= Main::Enums::MP_100 && item.id <= Main::Enums::MP_500000)
|
||||
{ // mp box
|
||||
response.setMission(1);
|
||||
|
|
@ -53,6 +48,7 @@ namespace Main
|
|||
boxItem.itemId = m_boxes.at(item.id)->get();
|
||||
boxItem.serialInfo = wonItemSerialInfo;
|
||||
|
||||
response.setOption(1);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&boxItem), sizeof(boxItem));
|
||||
session.asyncWrite(response);
|
||||
session.deleteItem(openedItemSerialInfo); // Delete the box / item that was just opened
|
||||
|
|
@ -69,6 +65,7 @@ namespace Main
|
|||
|
||||
Main::Structures::ItemSerialInfo wonItemSerialInfo;
|
||||
wonItemSerialInfo.itemNumber = session.getLatestItemNumber() + 1;
|
||||
response.setOption(1);
|
||||
Main::Structures::BoxItem boxItem;
|
||||
|
||||
switch (item.id)
|
||||
|
|
|
|||
|
|
@ -3,22 +3,34 @@
|
|||
|
||||
#include "../../Network/MainSession.h"
|
||||
#include "../../../include/Structures/AccountInfo/MainAccountInfo.h"
|
||||
#include "../../../include/Structures/ClientData/Structures.h"
|
||||
#include "Network/Packet.h"
|
||||
#include "../../../include/MainEnums.h"
|
||||
|
||||
#include <iostream>
|
||||
namespace Main
|
||||
{
|
||||
namespace Handlers
|
||||
{
|
||||
inline void handleItemRefund(const Common::Network::Packet& request, Main::Network::Session& session)
|
||||
inline void handleItemRefund(const Common::Network::Packet& request, Main::Network::Session& session, const Main::ClientData::ItemRefund& itemRefund)
|
||||
{
|
||||
std::uint32_t mpToAdd{};
|
||||
Main::Structures::ItemSerialInfo serialInfo{};
|
||||
std::memcpy(&mpToAdd, request.getData() + 8, sizeof(std::uint32_t));
|
||||
std:memcpy(&serialInfo, request.getData(), sizeof(Main::Structures::ItemSerialInfo));
|
||||
std::uint32_t toRefund = 0;
|
||||
for (const auto& [itemNum, actualItem] : session.getItems())
|
||||
{
|
||||
if (itemNum == itemRefund.serialInfo.itemNumber)
|
||||
{
|
||||
Main::ConstantDatabase::CdbUtil cdbUtil(actualItem.id);
|
||||
auto refund = cdbUtil.getItemRefundPrice();
|
||||
if (refund == std::nullopt) return;
|
||||
toRefund = *refund;
|
||||
}
|
||||
}
|
||||
|
||||
const bool removed = session.deleteItemBasic(serialInfo);
|
||||
session.setAccountMicroPoints(session.getAccountInfo().microPoints + mpToAdd);
|
||||
const bool removed = session.deleteItemBasic(itemRefund.serialInfo);
|
||||
if (removed)
|
||||
{
|
||||
session.setAccountMicroPoints(session.getAccountInfo().microPoints + toRefund);
|
||||
}
|
||||
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "../../Utilities.h"
|
||||
#include "../../Boxes/BoxBase.h"
|
||||
#include "../CapsuleSpinHandler.h"
|
||||
#include "../../Structures/ClientData/Structures.h"
|
||||
|
||||
namespace Main
|
||||
{
|
||||
|
|
@ -31,7 +32,7 @@ namespace Main
|
|||
RESET_REQUEST = 55
|
||||
};
|
||||
|
||||
inline void handleItemUpgrade(const Common::Network::Packet& request, Main::Network::Session& session)
|
||||
inline void handleItemUpgrade(const Common::Network::Packet& request, Main::Network::Session& session, const Main::ClientData::ItemUpgrade& itemUpgradeData)
|
||||
{
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
|
|
@ -41,23 +42,16 @@ namespace Main
|
|||
|
||||
if (request.getExtra() == ItemClientExtra::ADD_ENERGY_REQUEST)
|
||||
{
|
||||
std::uint32_t usedEnergy;
|
||||
Main::Structures::ItemSerialInfo itemSerialInfo{};
|
||||
std::memcpy(&usedEnergy, request.getData() + 8, sizeof(std::uint32_t));
|
||||
std::memcpy(&itemSerialInfo, request.getData(), sizeof(itemSerialInfo));
|
||||
|
||||
if (usedEnergy > accountInfo.battery) return; // security check, client already prevents this
|
||||
if (itemUpgradeData.usedEnergy > accountInfo.battery) return; // security check, client already prevents this
|
||||
response.setExtra(ItemUpgradeExtra::ENERGY_ADD);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(const_cast<std::uint8_t*>(request.getData())), sizeof(usedEnergy) + sizeof(Main::Structures::ItemSerialInfo));
|
||||
if (!session.addEnergyToItem(itemSerialInfo, usedEnergy)) return;
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(const_cast<std::uint8_t*>(request.getData())), sizeof(itemUpgradeData.usedEnergy) + sizeof(Main::Structures::ItemSerialInfo));
|
||||
if (!session.addEnergyToItem(itemUpgradeData.serialInfo, itemUpgradeData.usedEnergy)) return;
|
||||
session.asyncWrite(response);
|
||||
}
|
||||
else if (request.getExtra() == ItemClientExtra::UPGRADE_REQUEST)
|
||||
{
|
||||
Main::Structures::ItemSerialInfo itemSerialInfo{};
|
||||
std::memcpy(&itemSerialInfo, request.getData(), sizeof(itemSerialInfo));
|
||||
std::array<std::uint8_t, 72> unused{};
|
||||
auto found = session.findItemBySerialInfo(itemSerialInfo);
|
||||
auto found = session.findItemBySerialInfo(itemUpgradeData.serialInfo);
|
||||
if (found == std::nullopt) return;
|
||||
|
||||
Main::ConstantDatabase::CdbUtil cdbCurrentId(found->id);
|
||||
|
|
@ -85,8 +79,8 @@ namespace Main
|
|||
response.setExtra(ItemUpgradeExtra::UPGRADE_FAIL);
|
||||
response.setData(unused.data(), unused.size());
|
||||
session.asyncWrite(response);
|
||||
session.deleteItem(itemSerialInfo);
|
||||
session.spawnItem(found->id, itemSerialInfo); // spawn new item with correct energy (=reset energy)
|
||||
session.deleteItem(itemUpgradeData.serialInfo);
|
||||
session.spawnItem(found->id, itemUpgradeData.serialInfo); // spawn new item with correct energy (=reset energy)
|
||||
return;
|
||||
}
|
||||
response.setExtra(ItemUpgradeExtra::UPGRADE_SUCCESS);
|
||||
|
|
@ -94,8 +88,8 @@ namespace Main
|
|||
session.asyncWrite(response);
|
||||
|
||||
// Delete the old item, respawn new (upgraded) one
|
||||
session.deleteItem(itemSerialInfo);
|
||||
session.spawnItem(found->id + toAdd, itemSerialInfo);
|
||||
session.deleteItem(itemUpgradeData.serialInfo);
|
||||
session.spawnItem(found->id + toAdd, itemUpgradeData.serialInfo);
|
||||
session.setAccountMicroPoints(accountInfo.microPoints - *mpNeededForUpgrade);
|
||||
session.sendCurrency();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -207,17 +207,13 @@ namespace Main
|
|||
|
||||
if (request.getExtra() != Enums::ChatExtra::CLAN)
|
||||
{
|
||||
auto room = roomsManager.getRoomByNumber(session.getRoomNumber());
|
||||
if (!room) return;
|
||||
auto& actualRoom = room->get();
|
||||
|
||||
if (actualRoom.isMuted() && session.getAccountInfo().playerGrade < Common::Enums::GRADE_MOD)
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(session.getRoomNumber()))
|
||||
{
|
||||
Details::sendMessage("the room is currently muted", session);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (session.isInMatch())
|
||||
if (room->isMuted() && session.getAccountInfo().playerGrade < Common::Enums::GRADE_MOD)
|
||||
{
|
||||
Details::sendMessage("the room is currently muted", session);
|
||||
}
|
||||
else if (session.isInMatch())
|
||||
{
|
||||
roomsManager.broadcastToMatchExceptSelf(session.getRoomNumber(), session.getAccountInfo().uniqueId, response, request.getExtra());
|
||||
}
|
||||
|
|
@ -225,7 +221,6 @@ namespace Main
|
|||
{
|
||||
roomsManager.broadcastOutsideMatchExceptSelf(session.getRoomNumber(), session.getAccountInfo().uniqueId, response, request.getExtra());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -10,32 +10,30 @@ namespace Main
|
|||
{
|
||||
namespace Handlers
|
||||
{
|
||||
template<std::size_t N>
|
||||
inline void handlePlayerBlock(const Common::Network::Packet& request, Main::Network::Session& session, Main::Network::SessionsManager& sessionsManager,
|
||||
Main::Persistence::PersistentDatabase& database)
|
||||
Main::Persistence::PersistentDatabase& database, const std::array<char, N>& targetAccountName)
|
||||
{
|
||||
if (request.getOption() == 2) // for some reason the client always sends this option for blocked players list
|
||||
{
|
||||
char targetAccountName[16]{};
|
||||
std::memcpy(targetAccountName, request.getData(), sizeof(targetAccountName));
|
||||
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setCommand(request.getOrder(), 0, 1, 0);
|
||||
|
||||
if (auto* targetSession = sessionsManager.findSessionByName(targetAccountName))
|
||||
if (auto* targetSession = sessionsManager.findSessionByName(targetAccountName.data()))
|
||||
{
|
||||
const std::uint32_t targetAccountId = targetSession->getAccountInfo().accountID;
|
||||
session.blockAccount(targetAccountId, targetAccountName);
|
||||
session.blockAccount(targetAccountId, targetAccountName.data());
|
||||
session.deleteFriend(targetAccountId);
|
||||
targetSession->deleteFriend(session.getAccountInfo().accountID, false);
|
||||
session.asyncWrite(response);
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::uint32_t targetAccountId = database.blockPlayerByNickname(session.getAccountInfo().accountID, targetAccountName);
|
||||
const std::uint32_t targetAccountId = database.blockPlayerByNickname(session.getAccountInfo().accountID, targetAccountName.data());
|
||||
if (targetAccountId != -1)
|
||||
{
|
||||
session.blockAccount(targetAccountId, targetAccountName);
|
||||
session.blockAccount(targetAccountId, targetAccountName.data());
|
||||
session.deleteFriend(targetAccountId);
|
||||
session.asyncWrite(response);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,11 +9,8 @@ namespace Main
|
|||
{
|
||||
namespace Handlers
|
||||
{
|
||||
inline void handlePlayerUnblock(const Common::Network::Packet& request, Main::Network::Session& session)
|
||||
inline void handlePlayerUnblock(const Common::Network::Packet& request, Main::Network::Session& session, std::uint32_t targetAccountId)
|
||||
{
|
||||
std::uint32_t targetAccountId;
|
||||
std::memcpy(&targetAccountId, request.getData(), sizeof(std::uint32_t));
|
||||
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setCommand(request.getOrder(), 0, session.unblockAccount(targetAccountId), 0);
|
||||
|
|
|
|||
|
|
@ -9,11 +9,9 @@ namespace Main
|
|||
{
|
||||
namespace Handlers
|
||||
{
|
||||
inline void handleFriendDeletion(const Common::Network::Packet& request, Main::Network::Session& session, Main::Network::SessionsManager& sessionsManager)
|
||||
inline void handleFriendDeletion(const Common::Network::Packet& request, Main::Network::Session& session, Main::Network::SessionsManager& sessionsManager,
|
||||
std::uint32_t targetAccountIdToDelete)
|
||||
{
|
||||
std::uint32_t targetAccountIdToDelete;
|
||||
std::memcpy(&targetAccountIdToDelete, request.getData(), sizeof(std::uint32_t));
|
||||
|
||||
session.deleteFriend(targetAccountIdToDelete);
|
||||
if (auto* foundSession = sessionsManager.getSessionByAccountId(targetAccountIdToDelete))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,10 +14,8 @@ namespace Main
|
|||
namespace Handlers
|
||||
{
|
||||
inline void handleLobbyAccountInfo(const Common::Network::Packet& request, Main::Network::Session& session, Main::Network::SessionsManager& sessionsManager,
|
||||
std::uint32_t serverId)
|
||||
std::uint32_t serverId, const Main::Structures::UniqueId& uniqueId)
|
||||
{
|
||||
Main::Structures::UniqueId uniqueId;
|
||||
std::memcpy(&uniqueId, request.getData(), sizeof(Main::Structures::UniqueId));
|
||||
auto* targetSession = sessionsManager.getSessionBySessionId(uniqueId.session);
|
||||
if (!targetSession) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,11 +10,8 @@ namespace Main
|
|||
namespace Handlers
|
||||
{
|
||||
// TODO: Implement "mass" mailbox delete (= deleting multiple mailboxes at once), unsure if required by the client
|
||||
inline void handleMailboxDelete(const Common::Network::Packet& request, Main::Network::Session& session)
|
||||
{
|
||||
std::uint32_t timestamp;
|
||||
std::memcpy(×tamp, request.getData() + 4, sizeof(timestamp));
|
||||
|
||||
inline void handleMailboxDelete(const Common::Network::Packet& request, Main::Network::Session& session, std::uint32_t timestamp)
|
||||
{
|
||||
if (request.getMission() == Main::Enums::MailboxMission::MISSION_MAILBOX_RECEIVED)
|
||||
{
|
||||
session.deleteReceivedMailbox(timestamp);
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@ namespace Main
|
|||
namespace Handlers
|
||||
{
|
||||
inline void handleMailboxCommunication(const Common::Network::Packet& request, Main::Network::Session& session, Main::Network::SessionsManager& sessionsManager,
|
||||
Main::Persistence::PersistentDatabase& database)
|
||||
Main::Persistence::PersistentDatabase& database, const Main::ClientData::MailboxMessage& mailboxData)
|
||||
{
|
||||
const auto& accountInfo = session.getAccountInfo();
|
||||
const auto* const data = request.getData();
|
||||
constexpr const std::uint32_t maxMailboxes = 100;
|
||||
constexpr const std::uint32_t nicknameSize = 16;
|
||||
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
|
|
@ -35,16 +35,14 @@ namespace Main
|
|||
return;
|
||||
}
|
||||
|
||||
constexpr std::size_t nicknameSize = 16;
|
||||
char nickname[nicknameSize]{};
|
||||
std::memcpy(nickname, data, 16);
|
||||
auto* targetSession = sessionsManager.findSessionByName(nickname);
|
||||
|
||||
auto* targetSession = sessionsManager.findSessionByName(mailboxData.nickname);
|
||||
if (!targetSession)
|
||||
{
|
||||
Main::Structures::Mailbox mailbox;
|
||||
mailbox.timestamp = static_cast<__time32_t>(std::time(0));
|
||||
std::memcpy(mailbox.nickname, nickname, nicknameSize);
|
||||
std::memcpy(mailbox.message, data + nicknameSize, request.getDataSize() - nicknameSize);
|
||||
std::memcpy(mailbox.nickname, mailboxData.nickname, nicknameSize);
|
||||
std::memcpy(mailbox.message, mailboxData.message, request.getDataSize() - nicknameSize);
|
||||
auto res = database.storeOfflineMailbox(mailbox, accountInfo.nickname);
|
||||
|
||||
if (!res)
|
||||
|
|
@ -56,7 +54,7 @@ namespace Main
|
|||
else
|
||||
{
|
||||
mailbox.accountId = accountInfo.accountID;
|
||||
std::memcpy(mailbox.nickname, nickname, nicknameSize);
|
||||
std::memcpy(mailbox.nickname, mailboxData.nickname, nicknameSize);
|
||||
session.addMailboxSent(mailbox);
|
||||
}
|
||||
}
|
||||
|
|
@ -86,7 +84,7 @@ namespace Main
|
|||
Main::Structures::Mailbox mailbox{ targetAccountInfo.accountID, static_cast<__time32_t>(std::time(0)) };
|
||||
constexpr std::size_t nicknameSize = 16;
|
||||
std::memcpy(mailbox.nickname, accountInfo.nickname, nicknameSize);
|
||||
std::memcpy(mailbox.message, data + nicknameSize, request.getDataSize() - nicknameSize);
|
||||
std::memcpy(mailbox.message, mailboxData.message, request.getDataSize() - nicknameSize);
|
||||
targetSession->addMailboxReceived(mailbox);
|
||||
|
||||
mailbox.accountId = accountInfo.accountID;
|
||||
|
|
|
|||
|
|
@ -9,11 +9,9 @@ namespace Main
|
|||
{
|
||||
namespace Handlers
|
||||
{
|
||||
inline void handleReadMailbox(const Common::Network::Packet& request, Main::Network::Session& session, Main::Persistence::PersistentDatabase& database)
|
||||
inline void handleReadMailbox(const Common::Network::Packet& request, Main::Network::Session& session, Main::Persistence::PersistentDatabase& database,
|
||||
std::uint32_t timestamp)
|
||||
{
|
||||
std::uint32_t timestamp;
|
||||
std::memcpy(×tamp, request.getData() + 4, sizeof(timestamp));
|
||||
|
||||
if (request.getExtra() == Main::Enums::MailboxExtra::MAILBOX_HAS_BEEN_READ)
|
||||
{
|
||||
database.updateReadMailbox(session.getAccountInfo().accountID, timestamp);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include "../../../include/Structures/AccountInfo/MainAccountInfo.h"
|
||||
#include "Network/Packet.h"
|
||||
#include "../../../include/Classes/RoomsManager.h"
|
||||
#include "../../Structures/ClientData/PingData.h"
|
||||
#include "../../Structures/ClientData/Structures.h"
|
||||
|
||||
namespace Main
|
||||
{
|
||||
|
|
@ -16,11 +16,9 @@ namespace Main
|
|||
{
|
||||
if (request.getMission() == 1)
|
||||
{
|
||||
session.setPing(pingData.ping);
|
||||
const std::uint16_t roomNumber = session.getRoomNumber();
|
||||
|
||||
if (roomNumber)
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(session.getRoomNumber()))
|
||||
{
|
||||
session.setPing(pingData.ping);
|
||||
struct Resp
|
||||
{
|
||||
Main::ClientData::Ping clientData;
|
||||
|
|
@ -32,11 +30,7 @@ namespace Main
|
|||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setCommand(request.getOrder() + 1, request.getMission() + 1, 0, request.getOption());
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&resp), sizeof(resp));
|
||||
|
||||
auto roomFound = roomsManager.getRoomByNumber(roomNumber);
|
||||
if (roomFound == std::nullopt) return;
|
||||
auto& room = roomFound->get();
|
||||
room.broadcastToRoomExceptSelf(response, resp.uniqueId);
|
||||
room->broadcastToRoomExceptSelf(response, resp.uniqueId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,19 +17,18 @@ namespace Main
|
|||
{
|
||||
session.setPlayerState(static_cast<Common::Enums::PlayerState>(request.getOption()));
|
||||
|
||||
auto foundRoom = roomsManager.getRoomByNumber(session.getRoomNumber());
|
||||
if (foundRoom == std::nullopt) return;
|
||||
auto& room = foundRoom->get();
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(session.getRoomNumber()))
|
||||
{
|
||||
auto uniqueId = session.getAccountInfo().uniqueId;
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setCommand(Details::Orders::PLAYER_STATE_NOTIFICATION, 0, 0, session.getPlayerState());
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&uniqueId), sizeof(uniqueId));
|
||||
room->broadcastToRoom(response);
|
||||
room->setStateFor(uniqueId, session.getPlayerState());
|
||||
|
||||
auto uniqueId = session.getAccountInfo().uniqueId;
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setCommand(Details::Orders::PLAYER_STATE_NOTIFICATION, 0, 0, session.getPlayerState());
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&uniqueId), sizeof(uniqueId));
|
||||
room.broadcastToRoom(response);
|
||||
room.setStateFor(uniqueId, session.getPlayerState());
|
||||
|
||||
Details::broadcastPlayerItems(roomsManager, session, request);
|
||||
Details::broadcastPlayerItems(roomsManager, session, request);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,108 +39,89 @@ namespace Main
|
|||
roomsManager.broadcastToRoomExceptSelf(session.getRoomNumber(), session.getAccountInfo().uniqueId, const_cast<Common::Network::Packet&>(request));
|
||||
|
||||
// Next, specific ending info for each session
|
||||
const auto& roomOpt = roomsManager.getRoomByNumber(session.getRoomNumber());
|
||||
if (roomOpt == std::nullopt) return;
|
||||
auto& room = roomOpt->get();
|
||||
|
||||
const Main::ConstantDatabase::CdbUtil cdbUtil;
|
||||
const auto rewardInfo = cdbUtil.getRewardInfoForMode(room.getRoomSettings().mode);
|
||||
if (!rewardInfo.has_value())
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(session.getRoomNumber()))
|
||||
{
|
||||
std::cerr << "Error: RewardInfo was nullopt!\n";
|
||||
return;
|
||||
}
|
||||
|
||||
Common::Network::Packet response;
|
||||
for (std::size_t i = 0; i < request.getOption(); ++i)
|
||||
{
|
||||
// IMPORTANT: EXP and MP will be given even if the match was played for 1 second!
|
||||
// TODO: Add matchStartTime to Room class, and here check whether at least 60 seconds passed. Otherwise don't give anything to the players! (FARM prevention)
|
||||
Main::Structures::ClientEndingMatchNotification finalScoreGivenByClient;
|
||||
std::memcpy(&finalScoreGivenByClient, request.getData()
|
||||
+ sizeof(finalScoreGivenByClient) * i + sizeof(ClientEndingMatchNotificationHeader), sizeof(finalScoreGivenByClient));
|
||||
finalScoreGivenByClient.uniqueId.server = 4;
|
||||
Main::Structures::ScoreboardResponse responseStruct(finalScoreGivenByClient);
|
||||
|
||||
auto* targetSession = room.getPlayer(finalScoreGivenByClient.uniqueId);
|
||||
if (!targetSession) continue;
|
||||
response.setTcpHeader(targetSession->getId(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
std::cout << "EndMatch: Taking care of SessionID: " << targetSession->getId() << '\n';
|
||||
|
||||
// Calculate new EXP
|
||||
auto targetAccountInfo = room.getAccountInfoFor(finalScoreGivenByClient.uniqueId);
|
||||
responseStruct.newTotalEXP = targetAccountInfo.experience
|
||||
+ rewardInfo->ri_exp_base + rewardInfo->ri_exp_kill * responseStruct.totalKills * 2 + rewardInfo->ri_exp_death * responseStruct.deaths
|
||||
+ rewardInfo->ri_exp_assist * responseStruct.assists;
|
||||
|
||||
// Calculate new MP
|
||||
responseStruct.newTotalMP = targetAccountInfo.microPoints
|
||||
+ rewardInfo->ri_poi_base + rewardInfo->ri_poi_kill * responseStruct.totalKills * 2 + rewardInfo->ri_poi_death * responseStruct.deaths
|
||||
+ rewardInfo->ri_poi_assist * responseStruct.assists;
|
||||
|
||||
// Check if player leveled up
|
||||
auto gradeInfo = cdbUtil.getGradeInfoForLevel(targetAccountInfo.playerLevel + 1);
|
||||
if (gradeInfo != std::nullopt)
|
||||
const Main::ConstantDatabase::CdbUtil cdbUtil;
|
||||
const auto rewardInfo = cdbUtil.getRewardInfoForMode(room->getRoomSettings().mode);
|
||||
if (!rewardInfo.has_value())
|
||||
{
|
||||
if (responseStruct.newTotalEXP >= gradeInfo->gi_exp)
|
||||
return;
|
||||
}
|
||||
|
||||
Common::Network::Packet response;
|
||||
for (std::size_t i = 0; i < request.getOption(); ++i)
|
||||
{
|
||||
// TODO: Add matchStartTime to Room class, and here check whether at least 60 seconds passed. Otherwise don't give anything to the players! (FARM prevention)
|
||||
Main::Structures::ClientEndingMatchNotification finalScoreGivenByClient;
|
||||
std::memcpy(&finalScoreGivenByClient, request.getData()
|
||||
+ sizeof(finalScoreGivenByClient) * i + sizeof(ClientEndingMatchNotificationHeader), sizeof(finalScoreGivenByClient));
|
||||
finalScoreGivenByClient.uniqueId.server = 4;
|
||||
Main::Structures::ScoreboardResponse responseStruct(finalScoreGivenByClient);
|
||||
|
||||
auto* targetSession = room->getPlayer(finalScoreGivenByClient.uniqueId);
|
||||
if (!targetSession) continue;
|
||||
response.setTcpHeader(targetSession->getId(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
std::cout << "EndMatch: Taking care of SessionID: " << targetSession->getId() << '\n';
|
||||
|
||||
// Calculate new EXP
|
||||
auto targetAccountInfo = room->getAccountInfoFor(finalScoreGivenByClient.uniqueId);
|
||||
responseStruct.newTotalEXP = targetAccountInfo.experience
|
||||
+ rewardInfo->ri_exp_base + rewardInfo->ri_exp_kill * responseStruct.totalKills * 2 + rewardInfo->ri_exp_death * responseStruct.deaths
|
||||
+ rewardInfo->ri_exp_assist * responseStruct.assists;
|
||||
|
||||
// Calculate new MP
|
||||
responseStruct.newTotalMP = targetAccountInfo.microPoints
|
||||
+ rewardInfo->ri_poi_base + rewardInfo->ri_poi_kill * responseStruct.totalKills * 2 + rewardInfo->ri_poi_death * responseStruct.deaths
|
||||
+ rewardInfo->ri_poi_assist * responseStruct.assists;
|
||||
|
||||
// Check if player leveled up
|
||||
auto gradeInfo = cdbUtil.getGradeInfoForLevel(targetAccountInfo.playerLevel + 1);
|
||||
if (gradeInfo != std::nullopt)
|
||||
{
|
||||
responseStruct.newTotalMP += gradeInfo->gi_reward_point;
|
||||
room.storeEndMatchStatsFor(finalScoreGivenByClient.uniqueId, responseStruct,
|
||||
clientEndMatchNotificationHeader.blueScore, clientEndMatchNotificationHeader.redScore, true);
|
||||
|
||||
const auto newPlayerLevel = targetAccountInfo.playerLevel + 1;
|
||||
// Level up packet
|
||||
response.setOrder(311);
|
||||
response.setExtra(1);
|
||||
response.setOption(newPlayerLevel);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&finalScoreGivenByClient.uniqueId), sizeof(finalScoreGivenByClient.uniqueId));
|
||||
room.broadcastToRoomExceptSelf(response, finalScoreGivenByClient.uniqueId);
|
||||
|
||||
// Spawn won item
|
||||
if (targetSession)
|
||||
if (responseStruct.newTotalEXP >= gradeInfo->gi_exp)
|
||||
{
|
||||
/*
|
||||
Main::Structures::SpawnedItem spawnedItem{};
|
||||
spawnedItem.itemId = gradeInfo->gi_reward_item;
|
||||
spawnedItem.serialInfo.itemNumber = session.getLatestItemNumber() + 1;
|
||||
targetSession->spawnItem(gradeInfo->gi_reward_item, spawnedItem.serialInfo);
|
||||
targetSession->setLatestItemNumber(spawnedItem.serialInfo.itemNumber);
|
||||
*/
|
||||
responseStruct.newTotalMP += gradeInfo->gi_reward_point;
|
||||
room->storeEndMatchStatsFor(finalScoreGivenByClient.uniqueId, responseStruct,
|
||||
clientEndMatchNotificationHeader.blueScore, clientEndMatchNotificationHeader.redScore, true);
|
||||
|
||||
// Give MP proportionally to the new level
|
||||
targetSession->setAccountMicroPoints(targetAccountInfo.microPoints + (newPlayerLevel * 700));
|
||||
const auto newPlayerLevel = targetAccountInfo.playerLevel + 1;
|
||||
response.setCommand(311, 0, 1, newPlayerLevel); // level up packet
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&finalScoreGivenByClient.uniqueId), sizeof(finalScoreGivenByClient.uniqueId));
|
||||
room->broadcastToRoomExceptSelf(response, finalScoreGivenByClient.uniqueId);
|
||||
|
||||
if (targetSession)
|
||||
{
|
||||
// todo: spawn won item
|
||||
// Give MP proportionally to the new level
|
||||
targetSession->setAccountMicroPoints(targetAccountInfo.microPoints + (newPlayerLevel * 700));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
room->storeEndMatchStatsFor(finalScoreGivenByClient.uniqueId, responseStruct,
|
||||
clientEndMatchNotificationHeader.blueScore, clientEndMatchNotificationHeader.redScore, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
room.storeEndMatchStatsFor(finalScoreGivenByClient.uniqueId, responseStruct,
|
||||
room->storeEndMatchStatsFor(finalScoreGivenByClient.uniqueId, responseStruct,
|
||||
clientEndMatchNotificationHeader.blueScore, clientEndMatchNotificationHeader.redScore, false);
|
||||
}
|
||||
|
||||
// TODO: THE SIZE OF THIS PACKET CAN BE >= 1440 BYTES IF THERE ARE MAX NUM OF PLAYERS + MAX NUM OF OBS PLAYERS!
|
||||
// BUT ARE OBS PLAYERS EVEN COUNTED???
|
||||
response.setCommand(request.getOrder(), 0, 1, 0);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&responseStruct), sizeof(responseStruct));
|
||||
room->sendTo(finalScoreGivenByClient.uniqueId, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
room.storeEndMatchStatsFor(finalScoreGivenByClient.uniqueId, responseStruct,
|
||||
clientEndMatchNotificationHeader.blueScore, clientEndMatchNotificationHeader.redScore, false);
|
||||
}
|
||||
|
||||
// TODO: THE SIZE OF THIS PACKET CAN BE >= 1440 BYTES IF THERE ARE MAX NUM OF PLAYERS + MAX NUM OF OBS PLAYERS!
|
||||
// BUT ARE OBS PLAYERS EVEN COUNTED???
|
||||
response.setOrder(request.getOrder());
|
||||
response.setExtra(1);
|
||||
response.setMission(0);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&responseStruct), sizeof(responseStruct));
|
||||
room.sendTo(finalScoreGivenByClient.uniqueId, response);
|
||||
|
||||
room->endMatch();
|
||||
|
||||
// Notify client about match leave, MVR does this as well
|
||||
response.setCommand(256, 0, 33, 0);
|
||||
response.setData(nullptr, 0);
|
||||
session.asyncWrite(response);
|
||||
}
|
||||
|
||||
room.endMatch();
|
||||
|
||||
// Notify client about match leave, MVR does this as well
|
||||
response.setMission(0);
|
||||
response.setOption(0);
|
||||
response.setExtra(33); // match leave
|
||||
response.setOrder(256); // Match leave
|
||||
response.setData(nullptr, 0);
|
||||
session.asyncWrite(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
#include "../../Classes/RoomsManager.h"
|
||||
#include "Network/Packet.h"
|
||||
#include "../../Network/MainSessionManager.h"
|
||||
#include "Utils/Logger.h"
|
||||
|
||||
namespace Main
|
||||
{
|
||||
|
|
@ -13,48 +12,33 @@ namespace Main
|
|||
{
|
||||
inline void handleMatchLeave(const Common::Network::Packet& request, Main::Network::Session& session, Main::Network::SessionsManager& sessionsManager, Main::Classes::RoomsManager& roomsManager)
|
||||
{
|
||||
Utils::Logger& logger = Utils::Logger::getInstance();
|
||||
|
||||
auto foundRoom = roomsManager.getRoomByNumber(session.getRoomNumber());
|
||||
if (foundRoom == std::nullopt)
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(session.getRoomNumber()))
|
||||
{
|
||||
logger.log("Room not found by number!, Utils::LogType::Error, Main::handleMatchLeave");
|
||||
return;
|
||||
}
|
||||
auto& room = foundRoom->get();
|
||||
|
||||
if (room.isHost(session.getAccountInfo().uniqueId))
|
||||
{
|
||||
logger.log("The host " + session.getPlayerInfoAsString() + " is attempting to leave the match. " + room.getRoomInfoAsString(),
|
||||
Utils::LogType::Normal, "Main::handleMatchLeave");
|
||||
|
||||
if (room.removeHostFromMatch())
|
||||
if (room->isHost(session.getAccountInfo().uniqueId))
|
||||
{
|
||||
logger.log("Attempting to close the room " + room.getRoomInfoAsString(),
|
||||
Utils::LogType::Normal, "Main::handleMatchLeave");
|
||||
|
||||
roomsManager.removeRoom(room.getRoomNumber());
|
||||
if (room->removeHostFromMatch())
|
||||
{
|
||||
roomsManager.removeRoom(room->getRoomNumber());
|
||||
}
|
||||
else
|
||||
{
|
||||
// handle error?
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.log("The player " + session.getPlayerInfoAsString() + " is attempting to leave the match. " + room.getRoomInfoAsString(),
|
||||
Utils::LogType::Normal, "Main::handleMatchLeave");
|
||||
else
|
||||
{
|
||||
// Send leave match packet to client
|
||||
auto uniqueId = session.getAccountInfo().uniqueId;
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setCommand(request.getOrder(), 0, 0, 0);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&uniqueId), sizeof(uniqueId));
|
||||
roomsManager.broadcastToRoom(room->getRoomNumber(), response);
|
||||
|
||||
// Send leave match packet to client
|
||||
auto uniqueId = session.getAccountInfo().uniqueId;
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setCommand(request.getOrder(), 0, 0, 0);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&uniqueId), sizeof(uniqueId));
|
||||
roomsManager.broadcastToRoom(room.getRoomNumber(), response);
|
||||
|
||||
// Update server status for this player
|
||||
session.setIsInMatch(false);
|
||||
room.setStateFor(session.getAccountInfo().uniqueId, Common::Enums::STATE_WAITING);
|
||||
|
||||
logger.log("The player " + session.getPlayerInfoAsString() + " has left the match. " + room.getRoomInfoAsString(),
|
||||
Utils::LogType::Normal, "Main::handleMatchLeave");
|
||||
// Update server status for this player
|
||||
session.setIsInMatch(false);
|
||||
room->setStateFor(session.getAccountInfo().uniqueId, Common::Enums::STATE_WAITING);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,22 +19,21 @@ namespace Main
|
|||
|
||||
inline void handleHostChange(const Common::Network::Packet& request, Main::Network::Session& session, Main::Classes::RoomsManager& roomsManager)
|
||||
{
|
||||
auto foundRoom = roomsManager.getRoomByNumber(session.getRoomNumber());
|
||||
if (foundRoom == std::nullopt) return;
|
||||
auto& room = foundRoom.value().get();
|
||||
|
||||
const bool changed = room.changeHost(request.getOption());
|
||||
if (!changed)
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(session.getRoomNumber()))
|
||||
{
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setCommand(request.getOrder(), 0, RoomChangeHostExtra::CHANGE_HOST_SUCCESS, request.getOption());
|
||||
response.setExtra(RoomChangeHostExtra::CHANGE_HOST_DOESNT_EXIST);
|
||||
session.asyncWrite(response);
|
||||
}
|
||||
else
|
||||
{
|
||||
room.broadcastToRoom(const_cast<Common::Network::Packet&>(request));
|
||||
const bool changed = room->changeHost(request.getOption());
|
||||
if (!changed)
|
||||
{
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setCommand(request.getOrder(), 0, RoomChangeHostExtra::CHANGE_HOST_SUCCESS, request.getOption());
|
||||
response.setExtra(RoomChangeHostExtra::CHANGE_HOST_DOESNT_EXIST);
|
||||
session.asyncWrite(response);
|
||||
}
|
||||
else
|
||||
{
|
||||
room->broadcastToRoom(const_cast<Common::Network::Packet&>(request));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ namespace Main
|
|||
CREATION_BOTBATTLE = 61,
|
||||
};
|
||||
|
||||
inline void handleRoomCreation(const Common::Network::Packet& request, Main::Network::Session& session, Main::Classes::RoomsManager& roomsManager)
|
||||
inline void handleRoomCreation(const Common::Network::Packet& request, Main::Network::Session& session, Main::Classes::RoomsManager& roomsManager,
|
||||
const Main::Structures::CompleteRoomInfo& completeRoomInfo)
|
||||
{
|
||||
if (request.getFullSize() == sizeof(Common::Protocol::TcpHeader) + sizeof(Common::Protocol::CommandHeader)) return;
|
||||
|
||||
|
|
@ -42,9 +43,6 @@ namespace Main
|
|||
roomCreator.team = Common::Enums::TEAM_BLUE;
|
||||
|
||||
// request.getOption() ==> server/channel ID
|
||||
Main::Structures::CompleteRoomInfo completeRoomInfo;
|
||||
std::memcpy(&completeRoomInfo, request.getData(), sizeof(completeRoomInfo));
|
||||
|
||||
Main::Classes::Room room{ completeRoomInfo.title, completeRoomInfo.roomSettings, roomCreator, &session };
|
||||
if (request.getDataSize() >= sizeof(Main::Structures::CompleteRoomInfo))
|
||||
{
|
||||
|
|
@ -79,16 +77,11 @@ namespace Main
|
|||
session.asyncWrite(response);
|
||||
room.setStateFor(session.getAccountInfo().uniqueId, Common::Enums::STATE_WAITING);
|
||||
session.setRoomNumber(room.getRoomNumber());
|
||||
session.setIsInLobby(false);
|
||||
|
||||
|
||||
// Disable Team balance for now: it causes issues such as team bugs.
|
||||
if (room.isModeTeamBased())
|
||||
{
|
||||
response.setOrder(121);
|
||||
response.setMission(0);
|
||||
response.setExtra(0);
|
||||
response.setOption(room.getRoomSettings().mode);
|
||||
response.setCommand(121, 0, 0, room.getRoomSettings().mode);
|
||||
auto settings = room.getRoomSettingsUpdate();
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&settings), sizeof(settings));
|
||||
session.asyncWrite(response);
|
||||
|
|
|
|||
|
|
@ -33,223 +33,215 @@ namespace Main
|
|||
JOIN_ASK_PASSWORD = 0xE, // apparently this asks the user to input a password (even if the room doesn't have it) -- but the client already does this
|
||||
JOIN_LEVEL_TOO_HIGH = 0x15, // the host of the room has a low level, higher level players cannot join their room
|
||||
JOIN_KICKED_FROM_ROOM = 0x2A,
|
||||
JOIN_INVALID_PASSWORD = 0x2C,
|
||||
JOIN_INVALID_PASSWORD = 0x2C,
|
||||
};
|
||||
|
||||
// N.B GM grade can't enter observer mode at all seemingly (it's literally disabled)
|
||||
inline void handleRoomJoin(const Common::Network::Packet& request, Main::Network::Session& session, Main::Classes::RoomsManager& roomsManager,
|
||||
bool roomJoinCheckPassword = false)
|
||||
const Main::ClientData::RoomInfo& requestStructure, bool roomJoinCheckPassword = false)
|
||||
{
|
||||
struct RequestStructure
|
||||
{
|
||||
std::uint16_t roomNumber{};
|
||||
std::uint16_t unknown{};
|
||||
char password[8]{};
|
||||
} requestStructure;
|
||||
std::memcpy(&requestStructure, request.getData(), sizeof(requestStructure));
|
||||
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setOrder(request.getOrder());
|
||||
|
||||
auto foundRoom = roomsManager.getRoomByNumber(requestStructure.roomNumber + 1);
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(requestStructure.roomNumber + 1))
|
||||
{
|
||||
auto roomInfo = room->getRoomJoinInfo();
|
||||
const auto& roomSettings = room->getRoomSettings();
|
||||
|
||||
if (foundRoom == std::nullopt)
|
||||
if (roomJoinCheckPassword)
|
||||
{
|
||||
response.setExtra(RoomJoinExtra::JOIN_ASK_PASSWORD);
|
||||
session.asyncWrite(response);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& accountInfo = session.getAccountInfo();
|
||||
// 1. Check password - mods/tester/gm can join in rooms with passwords
|
||||
if (accountInfo.playerGrade >= Common::Enums::PlayerGrade::GRADE_MOD && roomInfo.hasPassword)
|
||||
{
|
||||
std::memcpy(roomInfo.password, room->getPassword().c_str(), 9);
|
||||
}
|
||||
else if (roomSettings.hasPassword && room->getPassword() != std::string{ requestStructure.password })
|
||||
{
|
||||
response.setExtra(RoomJoinExtra::JOIN_INVALID_PASSWORD);
|
||||
session.asyncWrite(response);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Check whether the room is full. If so, try to join the observer team if it isn't full too. Otherwise, one cannot enter the room
|
||||
bool joinedAsObserver = false;
|
||||
if (room->isRoomFullObserverExcluded())
|
||||
{
|
||||
if (room->isObserverFull() || !roomSettings.isObserverModeOn)
|
||||
{
|
||||
response.setExtra(RoomJoinExtra::JOIN_LOBBY_FULL);
|
||||
session.asyncWrite(response);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
joinedAsObserver = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Check whether the player was previously kicked from this room
|
||||
if (room->wasPreviouslyKicked(accountInfo.accountID))
|
||||
{
|
||||
response.setExtra(RoomJoinExtra::JOIN_KICKED_FROM_ROOM);
|
||||
session.asyncWrite(response);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Check whether the host of the room is a low level (<= 15), and whether whoever joined the room is higher than that.
|
||||
// In that case, do not allow it.
|
||||
if (room->getHostLevel() <= 16)
|
||||
{
|
||||
if (session.getAccountInfo().playerLevel > 16)
|
||||
{
|
||||
response.setExtra(RoomJoinExtra::JOIN_LEVEL_TOO_HIGH);
|
||||
session.asyncWrite(response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
response.setCommand(RoomJoinOrder::RoomInfo, room->getRoomInfo().hasPassword, room->getRoomInfo().roomNumber, 8); // Extra + Option = uint16_t = Room Number
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&roomInfo), sizeof(roomInfo));
|
||||
session.asyncWrite(response);
|
||||
|
||||
// Player infos
|
||||
auto allPlayers = room->getAllPlayers();
|
||||
response.setCommand(RoomJoinOrder::RoomPlayersInfos, room->getRoomInfo().hasPassword, 37, allPlayers.size());
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(allPlayers.data()), sizeof(Main::Structures::RoomPlayerInfo) * allPlayers.size());
|
||||
session.asyncWrite(response);
|
||||
|
||||
// Player items -- This can be > 1400 (MAX PACKET SIZE) bytes!
|
||||
response.setOrder(RoomJoinOrder::RoomPlayersItems);
|
||||
|
||||
constexpr std::size_t headerSize = sizeof(Common::Protocol::TcpHeader) + sizeof(Common::Protocol::CommandHeader);
|
||||
auto allPlayersItems = room->getPlayersItems();
|
||||
std::size_t totalSize = headerSize + sizeof(Main::Structures::RoomPlayerItems) * allPlayersItems.size();
|
||||
constexpr std::size_t MAX_PACKET_SIZE = 1440;
|
||||
|
||||
if (totalSize < MAX_PACKET_SIZE)
|
||||
{
|
||||
response.setOption(allPlayersItems.size());
|
||||
response.setExtra(37);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(allPlayersItems.data()), sizeof(Main::Structures::RoomPlayerItems) * allPlayersItems.size());
|
||||
session.asyncWrite(response);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::size_t currentItemIndex = 0;
|
||||
std::uint16_t packetExtra = 0;
|
||||
const std::size_t maxPayloadSize = MAX_PACKET_SIZE - headerSize;
|
||||
const std::size_t itemsToSend = maxPayloadSize / sizeof(Main::Structures::RoomPlayerItems);
|
||||
|
||||
while (currentItemIndex < allPlayersItems.size())
|
||||
{
|
||||
std::vector<Main::Structures::RoomPlayerItems> packetItems(
|
||||
allPlayersItems.begin() + currentItemIndex,
|
||||
allPlayersItems.begin() + std::min(currentItemIndex + itemsToSend, allPlayersItems.size())
|
||||
);
|
||||
|
||||
packetExtra = currentItemIndex == 0 ? 37 : 0;
|
||||
response.setExtra(packetExtra);
|
||||
response.setOption(packetItems.size());
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(packetItems.data()), packetItems.size() * sizeof(Main::Structures::RoomPlayerItems));
|
||||
session.asyncWrite(response);
|
||||
|
||||
currentItemIndex += itemsToSend;
|
||||
}
|
||||
}
|
||||
|
||||
// Player clan infos
|
||||
// option => again num of players (= num of clans)
|
||||
auto allPlayersClans = room->getPlayersClans();
|
||||
response.setCommand(RoomJoinOrder::RoomPlayersClans, 0, 37, allPlayersClans.size());
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(allPlayersClans.data()), sizeof(Main::Structures::PlayerClan) * allPlayersClans.size());
|
||||
session.asyncWrite(response);
|
||||
|
||||
// Success in joining the room
|
||||
response.setCommand(request.getOrder(), 0, joinedAsObserver ? RoomJoinExtra::JOIN_OBSERVER_MODE : RoomJoinExtra::JOIN_SUCCESS, 0);
|
||||
response.setData(nullptr, 0);
|
||||
// extra 0, mission 0 ==> observer mode
|
||||
// extra 0, mission 1 ==> seemingly invisible mode?!
|
||||
session.asyncWrite(response);
|
||||
|
||||
// Latest, missing information about the room
|
||||
response.setCommand(RoomJoinOrder::RoomLatestInfo, 0, 0, roomSettings.mode);
|
||||
if (roomSettings.mode == Common::Enums::FreeForAll)
|
||||
{
|
||||
Main::Structures::ModeInfoFFA info;
|
||||
info.state = room->hasMatchStarted() ? 3 : 0;
|
||||
info.timelimited = roomSettings.time;
|
||||
info.weaponlimited = roomSettings.weaponRestriction;
|
||||
info.winrule = room->getSpecificSetting();
|
||||
info.team_balance = false;
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&info), sizeof(info));
|
||||
}
|
||||
else if (roomSettings.mode == Common::Enums::Scrimmage)
|
||||
{
|
||||
Main::Structures::ModeInfoScrimmage info;
|
||||
info.state = room->hasMatchStarted() ? 3 : 0;
|
||||
info.timelimited = roomSettings.time;
|
||||
info.weaponlimited = roomSettings.weaponRestriction;
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&info), sizeof(info));
|
||||
}
|
||||
else
|
||||
{
|
||||
Main::Structures::ModeInfoTDM info;
|
||||
info.state = room->hasMatchStarted() ? 3 : 0;
|
||||
info.timelimited = roomSettings.time;
|
||||
info.weaponlimited = roomSettings.weaponRestriction;
|
||||
info.winrule = room->getSpecificSetting();
|
||||
info.kitdrop = 1;
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&info), sizeof(info));
|
||||
}
|
||||
session.asyncWrite(response);
|
||||
|
||||
// Send the info of the player that just joined to the whole room
|
||||
Main::Structures::RoomLatestEnteredPlayerInfo latestEnteredPlayerInfo;
|
||||
latestEnteredPlayerInfo.character = accountInfo.latestSelectedCharacter;
|
||||
latestEnteredPlayerInfo.level = accountInfo.playerLevel;
|
||||
latestEnteredPlayerInfo.ping = session.getPing();
|
||||
latestEnteredPlayerInfo.uniqueId = accountInfo.uniqueId;
|
||||
std::memcpy(latestEnteredPlayerInfo.playerName, accountInfo.nickname, 16);
|
||||
auto separatedItems = session.getEquippedItemsSeparated(); // first=items, second=weapons
|
||||
latestEnteredPlayerInfo.equippedItems = separatedItems.first;
|
||||
latestEnteredPlayerInfo.equippedWeapons = separatedItems.second;
|
||||
if (joinedAsObserver)
|
||||
{
|
||||
latestEnteredPlayerInfo.team = Common::Enums::TEAM_OBSERVER;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (room->isModeTeamBased())
|
||||
{
|
||||
latestEnteredPlayerInfo.team = room->calculateNewPlayerTeam();
|
||||
}
|
||||
else
|
||||
{
|
||||
latestEnteredPlayerInfo.team = Common::Enums::Team::TEAM_ALL;
|
||||
}
|
||||
}
|
||||
response.setCommand(RoomJoinOrder::RoomLatestEnteredPlayerInfo, 0, 0, 1);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&latestEnteredPlayerInfo), sizeof(latestEnteredPlayerInfo));
|
||||
room->broadcastToRoom(response);
|
||||
|
||||
if (joinedAsObserver)
|
||||
{
|
||||
room->addObserverPlayer(&session);
|
||||
}
|
||||
else
|
||||
{
|
||||
room->addPlayer(&session, latestEnteredPlayerInfo.team);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
response.setExtra(RoomJoinExtra::JOIN_ROOM_IS_DELETED);
|
||||
session.asyncWrite(response);
|
||||
return;
|
||||
}
|
||||
auto& room = foundRoom.value().get();
|
||||
auto roomInfo = room.getRoomJoinInfo();
|
||||
const auto& roomSettings = room.getRoomSettings();
|
||||
|
||||
if (roomJoinCheckPassword)
|
||||
{
|
||||
response.setExtra(RoomJoinExtra::JOIN_ASK_PASSWORD);
|
||||
session.asyncWrite(response);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& accountInfo = session.getAccountInfo();
|
||||
// 1. Check password - mods/tester/gm can join in rooms with passwords
|
||||
if (accountInfo.playerGrade >= Common::Enums::PlayerGrade::GRADE_MOD && roomInfo.hasPassword)
|
||||
{
|
||||
std::memcpy(roomInfo.password, room.getPassword().c_str(), 9);
|
||||
}
|
||||
else if (roomSettings.hasPassword && room.getPassword() != std::string{ requestStructure.password })
|
||||
{
|
||||
response.setExtra(RoomJoinExtra::JOIN_INVALID_PASSWORD);
|
||||
session.asyncWrite(response);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Check whether the room is full. If so, try to join the observer team if it isn't full too. Otherwise, one cannot enter the room
|
||||
bool joinedAsObserver = false;
|
||||
if (room.isRoomFullObserverExcluded())
|
||||
{
|
||||
if (room.isObserverFull() || !roomSettings.isObserverModeOn)
|
||||
{
|
||||
response.setExtra(RoomJoinExtra::JOIN_LOBBY_FULL);
|
||||
session.asyncWrite(response);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
joinedAsObserver = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Check whether the player was previously kicked from this room
|
||||
if (room.wasPreviouslyKicked(accountInfo.accountID))
|
||||
{
|
||||
response.setExtra(RoomJoinExtra::JOIN_KICKED_FROM_ROOM);
|
||||
session.asyncWrite(response);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Check whether the host of the room is a low level (<= 15), and whether whoever joined the room is higher than that.
|
||||
// In that case, do not allow it.
|
||||
if (room.getHostLevel() <= 16)
|
||||
{
|
||||
if (session.getAccountInfo().playerLevel > 16)
|
||||
{
|
||||
response.setExtra(RoomJoinExtra::JOIN_LEVEL_TOO_HIGH);
|
||||
session.asyncWrite(response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
response.setCommand(RoomJoinOrder::RoomInfo, room.getRoomInfo().hasPassword, room.getRoomInfo().roomNumber, 0); // Extra + Option = uint16_t = Room Number
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&roomInfo), sizeof(roomInfo));
|
||||
session.asyncWrite(response);
|
||||
|
||||
// Player infos
|
||||
auto allPlayers = room.getAllPlayers();
|
||||
response.setCommand(RoomJoinOrder::RoomPlayersInfos, room.getRoomInfo().hasPassword, 37, allPlayers.size());
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(allPlayers.data()), sizeof(Main::Structures::RoomPlayerInfo) * allPlayers.size());
|
||||
session.asyncWrite(response);
|
||||
|
||||
// Player items -- This can be > 1400 (MAX PACKET SIZE) bytes!
|
||||
response.setOrder(RoomJoinOrder::RoomPlayersItems);
|
||||
|
||||
constexpr std::size_t headerSize = sizeof(Common::Protocol::TcpHeader) + sizeof(Common::Protocol::CommandHeader);
|
||||
auto allPlayersItems = room.getPlayersItems();
|
||||
std::size_t totalSize = headerSize + sizeof(Main::Structures::RoomPlayerItems) * allPlayersItems.size();
|
||||
constexpr std::size_t MAX_PACKET_SIZE = 1440;
|
||||
|
||||
if (totalSize < MAX_PACKET_SIZE)
|
||||
{
|
||||
response.setOption(allPlayersItems.size());
|
||||
response.setExtra(37);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(allPlayersItems.data()), sizeof(Main::Structures::RoomPlayerItems) * allPlayersItems.size());
|
||||
session.asyncWrite(response);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::size_t currentItemIndex = 0;
|
||||
std::uint16_t packetExtra = 0;
|
||||
const std::size_t maxPayloadSize = MAX_PACKET_SIZE - headerSize;
|
||||
const std::size_t itemsToSend = maxPayloadSize / sizeof(Main::Structures::RoomPlayerItems);
|
||||
|
||||
while (currentItemIndex < allPlayersItems.size())
|
||||
{
|
||||
std::vector<Main::Structures::RoomPlayerItems> packetItems(
|
||||
allPlayersItems.begin() + currentItemIndex,
|
||||
allPlayersItems.begin() + std::min(currentItemIndex + itemsToSend, allPlayersItems.size())
|
||||
);
|
||||
|
||||
packetExtra = currentItemIndex == 0 ? 37 : 0;
|
||||
response.setExtra(packetExtra);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(packetItems.data()), packetItems.size() * sizeof(Main::Structures::RoomPlayerItems));
|
||||
response.setOption(packetItems.size());
|
||||
session.asyncWrite(response);
|
||||
|
||||
currentItemIndex += itemsToSend;
|
||||
}
|
||||
}
|
||||
|
||||
// Player clan infos
|
||||
// option => again num of players (= num of clans)
|
||||
auto allPlayersClans = room.getPlayersClans();
|
||||
response.setCommand(RoomJoinOrder::RoomPlayersClans, 0, 37, allPlayersClans.size());
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(allPlayersClans.data()), sizeof(Main::Structures::PlayerClan) * allPlayersClans.size());
|
||||
session.asyncWrite(response);
|
||||
|
||||
// Success in joining the room
|
||||
response.setCommand(request.getOrder(), 0, joinedAsObserver ? RoomJoinExtra::JOIN_OBSERVER_MODE : RoomJoinExtra::JOIN_SUCCESS, 1);
|
||||
response.setData(nullptr, 0);
|
||||
// extra 0, mission 0 ==> observer mode
|
||||
// extra 0, mission 1 ==> seemingly invisible mode?!
|
||||
session.asyncWrite(response);
|
||||
|
||||
// Latest, missing information about the room
|
||||
response.setCommand(RoomJoinOrder::RoomLatestInfo, 0, 0, roomSettings.mode);
|
||||
if (roomSettings.mode == Common::Enums::FreeForAll)
|
||||
{
|
||||
Main::Structures::ModeInfoFFA info;
|
||||
info.state = room.hasMatchStarted() + 1;
|
||||
info.timelimited = roomSettings.time;
|
||||
info.weaponlimited = roomSettings.weaponRestriction;
|
||||
info.winrule = room.getSpecificSetting();
|
||||
info.team_balance = false;
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&info), sizeof(info));
|
||||
}
|
||||
else if (roomSettings.mode == Common::Enums::Scrimmage)
|
||||
{
|
||||
Main::Structures::ModeInfoScrimmage info;
|
||||
info.state = room.hasMatchStarted() + 1;
|
||||
info.timelimited = roomSettings.time;
|
||||
info.weaponlimited = roomSettings.weaponRestriction;
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&info), sizeof(info));
|
||||
}
|
||||
else
|
||||
{
|
||||
Main::Structures::ModeInfoTDM info;
|
||||
info.state = room.hasMatchStarted() + 1;
|
||||
info.timelimited = roomSettings.time;
|
||||
info.weaponlimited = roomSettings.weaponRestriction;
|
||||
info.winrule = room.getSpecificSetting();
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&info), sizeof(info));
|
||||
}
|
||||
session.asyncWrite(response);
|
||||
|
||||
// Send the info of the player that just joined to the whole room
|
||||
Main::Structures::RoomLatestEnteredPlayerInfo latestEnteredPlayerInfo;
|
||||
latestEnteredPlayerInfo.character = accountInfo.latestSelectedCharacter;
|
||||
latestEnteredPlayerInfo.level = accountInfo.playerLevel;
|
||||
latestEnteredPlayerInfo.ping = session.getPing();
|
||||
latestEnteredPlayerInfo.uniqueId = accountInfo.uniqueId;
|
||||
std::memcpy(latestEnteredPlayerInfo.playerName, accountInfo.nickname, 16);
|
||||
auto separatedItems = session.getEquippedItemsSeparated(); // first=items, second=weapons
|
||||
latestEnteredPlayerInfo.equippedItems = separatedItems.first;
|
||||
latestEnteredPlayerInfo.equippedWeapons = separatedItems.second;
|
||||
if (joinedAsObserver)
|
||||
{
|
||||
latestEnteredPlayerInfo.team = Common::Enums::TEAM_OBSERVER;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (room.isModeTeamBased())
|
||||
{
|
||||
latestEnteredPlayerInfo.team = room.calculateNewPlayerTeam();
|
||||
}
|
||||
else
|
||||
{
|
||||
latestEnteredPlayerInfo.team = Common::Enums::Team::TEAM_ALL;
|
||||
}
|
||||
}
|
||||
response.setCommand(RoomJoinOrder::RoomLatestEnteredPlayerInfo, 0, 0, 0);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&latestEnteredPlayerInfo), sizeof(latestEnteredPlayerInfo));
|
||||
room.broadcastToRoom(response);
|
||||
|
||||
if (joinedAsObserver)
|
||||
{
|
||||
room.addObserverPlayer(&session);
|
||||
}
|
||||
else
|
||||
{
|
||||
room.addPlayer(&session, latestEnteredPlayerInfo.team);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,38 +40,39 @@ namespace Main
|
|||
}
|
||||
|
||||
inline void handleRoomLeave(const Common::Network::Packet& request, Main::Network::Session& session, Main::Network::SessionsManager& sessionsManager,
|
||||
Main::Classes::RoomsManager& roomsManager, std::uint32_t serverId)
|
||||
Main::Classes::RoomsManager& roomsManager, std::uint32_t serverId, const Main::Structures::UniqueId& uniqueId)
|
||||
{
|
||||
auto roomOpt = roomsManager.getRoomByNumber(session.getRoomNumber());
|
||||
if (roomOpt == std::nullopt)
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(session.getRoomNumber()))
|
||||
{
|
||||
if (request.getExtra() == ClientExtra::KICK_PLAYER)
|
||||
{
|
||||
auto uid = uniqueId;
|
||||
uid.server = serverId;
|
||||
auto* targetSession = sessionsManager.getSessionBySessionId(uid.session);
|
||||
if (targetSession)
|
||||
{
|
||||
if (targetSession->getAccountInfo().playerGrade >= session.getAccountInfo().playerGrade) return; // Add error messages, i.e. "cannot kick same or higher grade account"
|
||||
room->addKickedPlayer(targetSession->getAccountInfo().accountID);
|
||||
room->removePlayer(targetSession, RoomLeaveExtra::LEAVE_KICKED_BY_HOST); // RemovePlayer also takes care of sending the packet to the client.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there are no players left after this player left, or if there were errors while switching to a new host, just close the room to avoid further issues.
|
||||
if (room->removePlayer(&session, RoomLeaveExtra::LEAVE_NORMAL))
|
||||
{
|
||||
roomsManager.removeRoom(room->getRoomNumber());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setCommand(request.getOrder(), 0, RoomLeaveExtra::LEAVE_ERROR, 0);
|
||||
session.asyncWrite(response);
|
||||
return;
|
||||
};
|
||||
auto& room = roomOpt->get();
|
||||
if (request.getExtra() == ClientExtra::KICK_PLAYER)
|
||||
{
|
||||
Main::Structures::UniqueId uniqueId;
|
||||
std::memcpy(&uniqueId, request.getData(), sizeof(uniqueId));
|
||||
uniqueId.server = serverId;
|
||||
auto* targetSession = sessionsManager.getSessionBySessionId(uniqueId.session);
|
||||
if (targetSession)
|
||||
{
|
||||
if (targetSession->getAccountInfo().playerGrade >= session.getAccountInfo().playerGrade) return; // Add error messages, i.e. "cannot kick same or higher grade account"
|
||||
room.addKickedPlayer(targetSession->getAccountInfo().accountID);
|
||||
room.removePlayer(targetSession, RoomLeaveExtra::LEAVE_KICKED_BY_HOST); // RemovePlayer also takes care of sending the packet to the client.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there are no players left after this player left, or if there were errors while switching to a new host, just close the room to avoid further issues.
|
||||
if (room.removePlayer(&session, RoomLeaveExtra::LEAVE_NORMAL))
|
||||
{
|
||||
roomsManager.removeRoom(room.getRoomNumber());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ namespace Main
|
|||
USER_JOINING_FRIEND = 28,
|
||||
};
|
||||
|
||||
// Room invites/join, not fully implemented, also not working in certain scenarios, recheck + refactor this function
|
||||
inline void unknown(const Common::Network::Packet& request, Main::Network::Session& session, Main::Classes::RoomsManager& roomsManager,
|
||||
Main::Network::SessionsManager& sessionsManager)
|
||||
{
|
||||
|
|
@ -56,7 +57,7 @@ namespace Main
|
|||
Common::Network::Packet response;
|
||||
response.setTcpHeader(session.getId(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setOrder(137);
|
||||
Main::Handlers::handleRoomLeave(response, session, sessionsManager, roomsManager, 4);
|
||||
Main::Handlers::handleRoomLeave(response, session, sessionsManager, roomsManager, 4, Details::parseData<Main::Structures::UniqueId>(response));
|
||||
}
|
||||
|
||||
struct JoinInfo
|
||||
|
|
@ -71,14 +72,14 @@ namespace Main
|
|||
response.setMission(0);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&joinInfo), sizeof(joinInfo));
|
||||
|
||||
auto roomOpt = roomsManager.getRoomByNumber(targetRoomNum);
|
||||
if (!roomOpt)
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(session.getRoomNumber()))
|
||||
{
|
||||
Main::Details::sendMessage("Room not found.", session);
|
||||
// Currently passworded room not handled!
|
||||
//Main::Handlers::handleRoomJoin(response, session, roomsManager, !roomOpt->get().getPassword().empty());
|
||||
}
|
||||
else
|
||||
{
|
||||
Main::Handlers::handleRoomJoin(response, session, roomsManager, !roomOpt->get().getPassword().empty());
|
||||
Main::Details::sendMessage("Room not found.", session);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -101,10 +102,8 @@ namespace Main
|
|||
Main::Network::Session* targetSession = sessionsManager.findSessionByName(targetNickname);
|
||||
if (targetSession)
|
||||
{
|
||||
auto foundRoom = roomsManager.getRoomByNumber(session.getRoomNumber());
|
||||
if (foundRoom)
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(session.getRoomNumber()))
|
||||
{
|
||||
auto& actualRoom = foundRoom->get();
|
||||
response.setOrder(319); // Room invite request
|
||||
response.setExtra(44); // Room invite request
|
||||
response.setOption(0);
|
||||
|
|
@ -126,7 +125,7 @@ namespace Main
|
|||
|
||||
Response responseStruct;
|
||||
responseStruct.roomNumber = session.getRoomNumber() - 1;
|
||||
std::ranges::copy(std::span(actualRoom.getRoomTitle().c_str(), sizeof(responseStruct.roomTitle) - 1), responseStruct.roomTitle);
|
||||
std::ranges::copy(std::span(room->getRoomTitle().c_str(), sizeof(responseStruct.roomTitle) - 1), responseStruct.roomTitle);
|
||||
responseStruct.roomTitle[sizeof(responseStruct.roomTitle) - 1] = '\0';
|
||||
std::ranges::copy(std::span(session.getAccountInfo().nickname, sizeof(responseStruct.sourceNickname) - 1), responseStruct.sourceNickname);
|
||||
responseStruct.sourceNickname[sizeof(responseStruct.sourceNickname) - 1] = '\0';
|
||||
|
|
@ -149,149 +148,147 @@ namespace Main
|
|||
inline void handleRoomMiscellaneous(const Common::Network::Packet& request, Main::Network::Session& session, Main::Classes::RoomsManager& roomsManager,
|
||||
std::uint64_t m_latestServerRestart)
|
||||
{
|
||||
auto foundRoom = roomsManager.getRoomByNumber(session.getRoomNumber());
|
||||
if (foundRoom == std::nullopt) return;
|
||||
auto& room = foundRoom.value().get();
|
||||
|
||||
auto response = request;
|
||||
if (request.getOrder() == 121 && request.getExtra() == 28) // votekick
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(session.getRoomNumber()))
|
||||
{
|
||||
struct VotekickResponse
|
||||
auto response = request;
|
||||
if (request.getOrder() == 121 && request.getExtra() == 28) // votekick
|
||||
{
|
||||
Main::Structures::UniqueId targetUniqueId{};
|
||||
Main::Structures::UniqueId selfUniqueId{};
|
||||
std::uint32_t kickReasonId = 0;
|
||||
std::uint32_t totalVoteTime = 0; // here the tick is in ms / 10, because 4 bytes might not be enough for tick in pure milliseconds!
|
||||
} votekickResponse;
|
||||
|
||||
// targetUniqueId and kickReason is provided by the client
|
||||
std::memcpy(&votekickResponse.targetUniqueId, reinterpret_cast<std::uint8_t*>(const_cast<std::uint8_t*>(request.getData())),
|
||||
sizeof(Main::Structures::UniqueId));
|
||||
std::memcpy(&votekickResponse.kickReasonId, reinterpret_cast<std::uint8_t*>(const_cast<std::uint8_t*>(request.getData() + 4)),
|
||||
sizeof(std::uint32_t));
|
||||
|
||||
const auto& accountInfo = session.getAccountInfo();
|
||||
const std::uint32_t totalVoteTime = 30'000; // in ms
|
||||
votekickResponse.selfUniqueId = accountInfo.uniqueId;
|
||||
votekickResponse.totalVoteTime = (static_cast<std::uint32_t>(accountInfo.getUtcTimeMs() - m_latestServerRestart + totalVoteTime) / 10);
|
||||
|
||||
response.setCommand(request.getOrder(), 0, 28, 1);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&votekickResponse), sizeof(votekickResponse));
|
||||
roomsManager.broadcastToRoom(session.getRoomNumber(), response);
|
||||
return;
|
||||
}
|
||||
else if (request.getMission() == 1 && request.getOrder() == 125) // add password without clicking "room settings" first
|
||||
{
|
||||
char newPassword[8]{};
|
||||
std::memcpy(newPassword, request.getData() + 4, sizeof(newPassword));
|
||||
room.updatePassword(newPassword);
|
||||
room.broadcastToRoom(response);
|
||||
return;
|
||||
}
|
||||
else if (request.getMission() == 0 && request.getOrder() == 125) // password removed without clicking "room settings" first
|
||||
{
|
||||
room.updatePassword("");
|
||||
room.broadcastToRoom(response);
|
||||
return;
|
||||
}
|
||||
else if (request.getOrder() == 155) // team switch
|
||||
{
|
||||
response.setOrder(313); // Switch team response to client
|
||||
response.setExtra(1); // Success -- Make sanity checks? Client already prevents this
|
||||
auto uniqueId = session.getAccountInfo().uniqueId;
|
||||
response.setOption(request.getOption());
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&uniqueId), sizeof(uniqueId));
|
||||
room.changePlayerTeam(session.getAccountInfo().uniqueId, request.getOption());
|
||||
room.broadcastToRoom(response);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (request.getDataSize() == sizeof(Main::Structures::RoomSettingsUpdateBase))
|
||||
{
|
||||
Main::Structures::RoomSettingsUpdateBase updatedRoomSettings;
|
||||
std::memcpy(&updatedRoomSettings, request.getData(), request.getDataSize());
|
||||
|
||||
room.updateRoomSettings(updatedRoomSettings, request.getOption());
|
||||
if (request.getOrder() == 125)
|
||||
struct VotekickResponse
|
||||
{
|
||||
room.updatePassword("");
|
||||
Main::Structures::UniqueId targetUniqueId{};
|
||||
Main::Structures::UniqueId selfUniqueId{};
|
||||
std::uint32_t kickReasonId = 0;
|
||||
std::uint32_t totalVoteTime = 0; // here the tick is in ms / 10, because 4 bytes might not be enough for tick in pure milliseconds!
|
||||
} votekickResponse;
|
||||
|
||||
// targetUniqueId and kickReason is provided by the client
|
||||
std::memcpy(&votekickResponse.targetUniqueId, reinterpret_cast<std::uint8_t*>(const_cast<std::uint8_t*>(request.getData())),
|
||||
sizeof(Main::Structures::UniqueId));
|
||||
std::memcpy(&votekickResponse.kickReasonId, reinterpret_cast<std::uint8_t*>(const_cast<std::uint8_t*>(request.getData() + 4)),
|
||||
sizeof(std::uint32_t));
|
||||
|
||||
const auto& accountInfo = session.getAccountInfo();
|
||||
const std::uint32_t totalVoteTime = 30'000; // in ms
|
||||
votekickResponse.selfUniqueId = accountInfo.uniqueId;
|
||||
votekickResponse.totalVoteTime = (static_cast<std::uint32_t>(accountInfo.getUtcTimeMs() - m_latestServerRestart + totalVoteTime) / 10);
|
||||
|
||||
response.setCommand(request.getOrder(), 0, 28, 1);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&votekickResponse), sizeof(votekickResponse));
|
||||
roomsManager.broadcastToRoom(session.getRoomNumber(), response);
|
||||
return;
|
||||
}
|
||||
else if (request.getMission() == 1 && request.getOrder() == 125) // add password without clicking "room settings" first
|
||||
{
|
||||
char newPassword[8]{};
|
||||
std::memcpy(newPassword, request.getData() + 4, sizeof(newPassword));
|
||||
room->updatePassword(newPassword);
|
||||
room->broadcastToRoom(response);
|
||||
return;
|
||||
}
|
||||
else if (request.getMission() == 0 && request.getOrder() == 125) // password removed without clicking "room settings" first
|
||||
{
|
||||
room->updatePassword("");
|
||||
room->broadcastToRoom(response);
|
||||
return;
|
||||
}
|
||||
else if (request.getOrder() == 155) // team switch
|
||||
{
|
||||
response.setOrder(313); // Switch team response to client
|
||||
response.setExtra(1); // Success -- Make sanity checks? Client already prevents this
|
||||
auto uniqueId = session.getAccountInfo().uniqueId;
|
||||
response.setOption(request.getOption());
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&uniqueId), sizeof(uniqueId));
|
||||
room->changePlayerTeam(session.getAccountInfo().uniqueId, request.getOption());
|
||||
room->broadcastToRoom(response);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (request.getDataSize() == sizeof(Main::Structures::RoomSettingsUpdateBase))
|
||||
{
|
||||
Main::Structures::RoomSettingsUpdateBase updatedRoomSettings;
|
||||
std::memcpy(&updatedRoomSettings, request.getData(), request.getDataSize());
|
||||
|
||||
room->updateRoomSettings(updatedRoomSettings, request.getOption());
|
||||
if (request.getOrder() == 125)
|
||||
{
|
||||
room->updatePassword("");
|
||||
}
|
||||
|
||||
// Disable team balance
|
||||
updatedRoomSettings.isTeamBalanceOn = 0;
|
||||
auto data = reinterpret_cast<std::uint8_t*>(&updatedRoomSettings);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&updatedRoomSettings), request.getDataSize());
|
||||
room->broadcastToRoom(response);
|
||||
}
|
||||
else if (request.getDataSize() == sizeof(Main::Structures::RoomSettingsUpdateTitle))
|
||||
{
|
||||
Main::Structures::RoomSettingsUpdateTitle updatedRoomSettings;
|
||||
std::memcpy(&updatedRoomSettings, request.getData(), request.getDataSize());
|
||||
|
||||
room->updateRoomSettings(updatedRoomSettings.roomSettingsUpdateBase, request.getOption());
|
||||
room->updateTitle(updatedRoomSettings.title);
|
||||
|
||||
// Disable team balance
|
||||
updatedRoomSettings.roomSettingsUpdateBase.isTeamBalanceOn = 0;
|
||||
auto data = reinterpret_cast<std::uint8_t*>(&updatedRoomSettings);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&updatedRoomSettings), request.getDataSize());
|
||||
room->broadcastToRoom(response);
|
||||
}
|
||||
else if (request.getDataSize() == sizeof(Main::Structures::RoomSettingsUpdatePassword))
|
||||
{
|
||||
Main::Structures::RoomSettingsUpdatePassword updatedRoomSettings;
|
||||
std::memcpy(&updatedRoomSettings, request.getData(), request.getDataSize());
|
||||
|
||||
room->updateRoomSettings(updatedRoomSettings.roomSettingsUpdateBase, request.getOption());
|
||||
room->updatePassword(updatedRoomSettings.password);
|
||||
|
||||
// Disable team balance
|
||||
updatedRoomSettings.roomSettingsUpdateBase.isTeamBalanceOn = 0;
|
||||
auto data = reinterpret_cast<std::uint8_t*>(&updatedRoomSettings);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&updatedRoomSettings), request.getDataSize());
|
||||
room->broadcastToRoom(response);
|
||||
}
|
||||
else if (request.getDataSize() == sizeof(Main::Structures::RoomSettingsUpdateTitlePassword))
|
||||
{
|
||||
Main::Structures::RoomSettingsUpdateTitlePassword updatedRoomSettings;
|
||||
std::memcpy(&updatedRoomSettings, request.getData(), request.getDataSize());
|
||||
|
||||
room->updateRoomSettings(updatedRoomSettings.roomSettingsUpdateBase, request.getOption());
|
||||
room->updatePassword(updatedRoomSettings.password);
|
||||
room->updateTitle(updatedRoomSettings.title);
|
||||
|
||||
// Disable team balance
|
||||
updatedRoomSettings.roomSettingsUpdateBase.isTeamBalanceOn = 0;
|
||||
auto data = reinterpret_cast<std::uint8_t*>(&updatedRoomSettings);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&updatedRoomSettings), request.getDataSize());
|
||||
room->broadcastToRoom(response);
|
||||
}
|
||||
|
||||
// Disable team balance
|
||||
updatedRoomSettings.isTeamBalanceOn = 0;
|
||||
auto data = reinterpret_cast<std::uint8_t*>(&updatedRoomSettings);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&updatedRoomSettings), request.getDataSize());
|
||||
room.broadcastToRoom(response);
|
||||
}
|
||||
else if (request.getDataSize() == sizeof(Main::Structures::RoomSettingsUpdateTitle))
|
||||
{
|
||||
Main::Structures::RoomSettingsUpdateTitle updatedRoomSettings;
|
||||
std::memcpy(&updatedRoomSettings, request.getData(), request.getDataSize());
|
||||
const auto& newGameMode = room->getRoomSettings().mode;
|
||||
const bool isNewGameModeTeamBased = room->isModeTeamBased();
|
||||
const auto previousGameMode = room->getRoomSettings().mode;
|
||||
const bool wasPreviousGameModeTeamBased = room->isModeTeamBased();
|
||||
|
||||
room.updateRoomSettings(updatedRoomSettings.roomSettingsUpdateBase, request.getOption());
|
||||
room.updateTitle(updatedRoomSettings.title);
|
||||
|
||||
// Disable team balance
|
||||
updatedRoomSettings.roomSettingsUpdateBase.isTeamBalanceOn = 0;
|
||||
auto data = reinterpret_cast<std::uint8_t*>(&updatedRoomSettings);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&updatedRoomSettings), request.getDataSize());
|
||||
room.broadcastToRoom(response);
|
||||
}
|
||||
else if (request.getDataSize() == sizeof(Main::Structures::RoomSettingsUpdatePassword))
|
||||
{
|
||||
Main::Structures::RoomSettingsUpdatePassword updatedRoomSettings;
|
||||
std::memcpy(&updatedRoomSettings, request.getData(), request.getDataSize());
|
||||
|
||||
room.updateRoomSettings(updatedRoomSettings.roomSettingsUpdateBase, request.getOption());
|
||||
room.updatePassword(updatedRoomSettings.password);
|
||||
|
||||
// Disable team balance
|
||||
updatedRoomSettings.roomSettingsUpdateBase.isTeamBalanceOn = 0;
|
||||
auto data = reinterpret_cast<std::uint8_t*>(&updatedRoomSettings);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&updatedRoomSettings), request.getDataSize());
|
||||
room.broadcastToRoom(response);
|
||||
}
|
||||
else if (request.getDataSize() == sizeof(Main::Structures::RoomSettingsUpdateTitlePassword))
|
||||
{
|
||||
Main::Structures::RoomSettingsUpdateTitlePassword updatedRoomSettings;
|
||||
std::memcpy(&updatedRoomSettings, request.getData(), request.getDataSize());
|
||||
|
||||
room.updateRoomSettings(updatedRoomSettings.roomSettingsUpdateBase, request.getOption());
|
||||
room.updatePassword(updatedRoomSettings.password);
|
||||
room.updateTitle(updatedRoomSettings.title);
|
||||
|
||||
// Disable team balance
|
||||
updatedRoomSettings.roomSettingsUpdateBase.isTeamBalanceOn = 0;
|
||||
auto data = reinterpret_cast<std::uint8_t*>(&updatedRoomSettings);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&updatedRoomSettings), request.getDataSize());
|
||||
room.broadcastToRoom(response);
|
||||
}
|
||||
|
||||
const auto& newGameMode = room.getRoomSettings().mode;
|
||||
const bool isNewGameModeTeamBased = room.isModeTeamBased();
|
||||
const auto previousGameMode = room.getRoomSettings().mode;
|
||||
const bool wasPreviousGameModeTeamBased = room.isModeTeamBased();
|
||||
|
||||
|
||||
if (previousGameMode != newGameMode)
|
||||
{
|
||||
if (!wasPreviousGameModeTeamBased && isNewGameModeTeamBased) // Check whether we went from NonTeamBased => TeamBased.
|
||||
if (previousGameMode != newGameMode)
|
||||
{
|
||||
// Disable Team balance for now: it causes issues such as team bugs.
|
||||
response.setOrder(121);
|
||||
response.setMission(0);
|
||||
response.setExtra(0);
|
||||
response.setOption(room.getRoomSettings().mode);
|
||||
auto settings = room.getRoomSettingsUpdate();
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&settings), sizeof(settings));
|
||||
session.asyncWrite(response);
|
||||
if (!wasPreviousGameModeTeamBased && isNewGameModeTeamBased) // Check whether we went from NonTeamBased => TeamBased.
|
||||
{
|
||||
// Disable Team balance for now: it causes issues such as team bugs.
|
||||
response.setOrder(121);
|
||||
response.setMission(0);
|
||||
response.setExtra(0);
|
||||
response.setOption(room->getRoomSettings().mode);
|
||||
auto settings = room->getRoomSettingsUpdate();
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&settings), sizeof(settings));
|
||||
session.asyncWrite(response);
|
||||
|
||||
room.updatePlayersTeamToTeamBased();
|
||||
}
|
||||
else if (wasPreviousGameModeTeamBased && !isNewGameModeTeamBased) // Otherwise, check whether we went from TeamBased => NonTeamBased
|
||||
{
|
||||
room.updatePlayersTeamToNonTeamBased();
|
||||
room->updatePlayersTeamToTeamBased();
|
||||
}
|
||||
else if (wasPreviousGameModeTeamBased && !isNewGameModeTeamBased) // Otherwise, check whether we went from TeamBased => NonTeamBased
|
||||
{
|
||||
room->updatePlayersTeamToNonTeamBased();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,114 +20,42 @@ namespace Main
|
|||
inline void handleRoomStart(const Common::Network::Packet& request, Main::Network::Session& session, Main::Classes::RoomsManager& roomsManager,
|
||||
std::uint64_t timeSinceLastServerRestart)
|
||||
{
|
||||
const auto foundRoom = roomsManager.getRoomByNumber(session.getRoomNumber());
|
||||
if (foundRoom == std::nullopt) return;
|
||||
auto& room = foundRoom.value().get();
|
||||
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
auto selfUniqueId = session.getAccountInfo().uniqueId;
|
||||
|
||||
if (request.getExtra() == 38) // host or non-host clicks on "start" button (n.b: SingleWave's extra is 6)
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(session.getRoomNumber()))
|
||||
{
|
||||
response.setCommand(request.getOrder(), 0, 38, room.getRoomSettings().map);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&selfUniqueId), sizeof(selfUniqueId));
|
||||
room.broadcastToRoom(response);
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
auto selfUniqueId = session.getAccountInfo().uniqueId;
|
||||
|
||||
if (room.isHost(selfUniqueId))
|
||||
if (request.getExtra() == 38) // host or non-host clicks on "start" button (n.b: SingleWave's extra is 6)
|
||||
{
|
||||
Utils::MapInfo mapInfo{ room.getRoomSettings().map, selfUniqueId.session };
|
||||
Utils::IPCManager::ipc_mainToCast(mapInfo, std::to_string(room.getRoomNumber()), "map_info");
|
||||
}
|
||||
|
||||
// 421
|
||||
auto accountInfo = session.getAccountInfo();
|
||||
Main::Structures::RoomLatestEnteredPlayerInfo latestEnteredPlayerInfo;
|
||||
latestEnteredPlayerInfo.character = accountInfo.latestSelectedCharacter;
|
||||
latestEnteredPlayerInfo.level = accountInfo.playerLevel;
|
||||
latestEnteredPlayerInfo.ping = session.getPing();
|
||||
latestEnteredPlayerInfo.uniqueId = accountInfo.uniqueId;
|
||||
std::memcpy(latestEnteredPlayerInfo.playerName, accountInfo.nickname, 16);
|
||||
auto separatedItems = session.getEquippedItemsSeparated(); // first=items, second=weapons
|
||||
latestEnteredPlayerInfo.equippedItems = separatedItems.first;
|
||||
latestEnteredPlayerInfo.equippedWeapons = separatedItems.second;
|
||||
if (false) // joined as observer
|
||||
{
|
||||
latestEnteredPlayerInfo.team = Common::Enums::TEAM_OBSERVER;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (room.isModeTeamBased())
|
||||
{
|
||||
latestEnteredPlayerInfo.team = room.calculateNewPlayerTeam();
|
||||
}
|
||||
else
|
||||
{
|
||||
latestEnteredPlayerInfo.team = Common::Enums::Team::TEAM_ALL;
|
||||
}
|
||||
}
|
||||
response.setCommand(RoomJoinOrder::RoomLatestEnteredPlayerInfo, 0, 0, 0);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&latestEnteredPlayerInfo), sizeof(latestEnteredPlayerInfo));
|
||||
room.broadcastToRoom(response);
|
||||
|
||||
// 409
|
||||
auto roomSettings = room.getRoomSettings();
|
||||
response.setCommand(RoomJoinOrder::RoomLatestInfo, 0, 0, roomSettings.mode);
|
||||
if (roomSettings.mode == Common::Enums::FreeForAll)
|
||||
{
|
||||
Main::Structures::ModeInfoFFA info;
|
||||
info.state = room.hasMatchStarted() + 1;
|
||||
info.timelimited = roomSettings.time;
|
||||
info.weaponlimited = roomSettings.weaponRestriction;
|
||||
info.winrule = room.getSpecificSetting();
|
||||
info.team_balance = false;
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&info), sizeof(info));
|
||||
}
|
||||
else if (roomSettings.mode == Common::Enums::Scrimmage)
|
||||
{
|
||||
Main::Structures::ModeInfoScrimmage info;
|
||||
info.state = room.hasMatchStarted() + 1;
|
||||
info.timelimited = roomSettings.time;
|
||||
info.weaponlimited = roomSettings.weaponRestriction;
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&info), sizeof(info));
|
||||
}
|
||||
else
|
||||
{
|
||||
Main::Structures::ModeInfoTDM info;
|
||||
info.state = room.hasMatchStarted() + 1;
|
||||
info.timelimited = roomSettings.time;
|
||||
info.weaponlimited = roomSettings.weaponRestriction;
|
||||
info.winrule = room.getSpecificSetting();
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&info), sizeof(info));
|
||||
}
|
||||
session.asyncWrite(response);
|
||||
|
||||
// 312
|
||||
response.setOrder(312);
|
||||
response.setOption(11);
|
||||
response.setMission(0);
|
||||
response.setExtra(0);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&accountInfo.uniqueId), sizeof(accountInfo));
|
||||
session.asyncWrite(response);
|
||||
}
|
||||
else if (request.getExtra() == 41)
|
||||
{
|
||||
session.setIsInMatch(true);
|
||||
|
||||
if (room.isHost(selfUniqueId)) // broadcast the tick to the room
|
||||
{
|
||||
std::uint64_t roomTick = getUtcTimeMs() - timeSinceLastServerRestart;
|
||||
room.setTick(roomTick);
|
||||
response.setCommand(258, 0, 1, 0);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&roomTick), sizeof(roomTick));
|
||||
room.broadcastToRoom(response);
|
||||
room.startMatch(selfUniqueId);
|
||||
}
|
||||
else // Tell the other players in the match that we joined
|
||||
{
|
||||
response.setCommand(415, 0, 1, 0);
|
||||
response.setCommand(request.getOrder(), 0, 38, room->getRoomSettings().map);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&selfUniqueId), sizeof(selfUniqueId));
|
||||
room.broadcastToRoom(response);
|
||||
room->broadcastToRoom(response);
|
||||
|
||||
if (room->isHost(selfUniqueId))
|
||||
{
|
||||
Utils::MapInfo mapInfo{ room->getRoomSettings().map, selfUniqueId.session };
|
||||
Utils::IPCManager::ipc_mainToCast(mapInfo, std::to_string(room->getRoomNumber()), "map_info");
|
||||
}
|
||||
}
|
||||
else if (request.getExtra() == 41)
|
||||
{
|
||||
session.setIsInMatch(true);
|
||||
|
||||
if (room->isHost(selfUniqueId)) // broadcast the tick to the room
|
||||
{
|
||||
std::uint64_t roomTick = getUtcTimeMs() - timeSinceLastServerRestart;
|
||||
response.setCommand(258, 0, 1, 0);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&roomTick), sizeof(roomTick));
|
||||
room->broadcastToRoom(response);
|
||||
room->startMatch(selfUniqueId);
|
||||
}
|
||||
else // Tell the other players in the match that we joined
|
||||
{
|
||||
response.setCommand(415, 0, 1, 0);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&selfUniqueId), sizeof(selfUniqueId));
|
||||
room->broadcastToRoom(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace Main
|
|||
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setCommand(request.getOrder(), 0, 38, 0);
|
||||
response.setCommand(request.getOrder(), 0, 37, 0);
|
||||
response.setData(message.data(), message.size());
|
||||
session.asyncWrite(response);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,34 +11,30 @@ namespace Main
|
|||
{
|
||||
namespace Handlers
|
||||
{
|
||||
inline void handleBattery(const Common::Network::Packet& request, Main::Network::Session& session, Main::Classes::RoomsManager& roomsManager)
|
||||
inline void handleBattery(const Common::Network::Packet& request, Main::Network::Session& session, Main::Classes::RoomsManager& roomsManager,
|
||||
const Main::Structures::UniqueId& targetUniqueId)
|
||||
{
|
||||
auto room = roomsManager.getRoomByNumber(session.getRoomNumber());
|
||||
if (room == std::nullopt) return;
|
||||
auto& actualRoom = room->get();
|
||||
|
||||
std::array<std::uint32_t, 8> weightedBatteries = { 0, 0, 0, 0, 30, 30, 50, 100 };
|
||||
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
static std::uniform_int_distribution<std::size_t> dis(0, weightedBatteries.size() - 1);
|
||||
std::uint32_t selectedBattery = weightedBatteries[dis(gen)];
|
||||
|
||||
if (!selectedBattery) return; // No battery needs to be given
|
||||
|
||||
Main::Structures::UniqueId targetUniqueId;
|
||||
auto data = request.getData();
|
||||
std::memcpy(&targetUniqueId, data, sizeof(targetUniqueId));
|
||||
|
||||
auto* targetSession = actualRoom.getPlayer(targetUniqueId);
|
||||
if (targetSession)
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(session.getRoomNumber()))
|
||||
{
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(targetSession->getId(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setCommand(request.getOrder(), 0, 1, selectedBattery);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&selectedBattery), sizeof(selectedBattery));
|
||||
targetSession->asyncWrite(response);
|
||||
targetSession->addBatteryObtainedInMatch(selectedBattery);
|
||||
std::array<std::uint32_t, 8> weightedBatteries = { 0, 0, 0, 0, 30, 30, 50, 100 };
|
||||
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
static std::uniform_int_distribution<std::size_t> dis(0, weightedBatteries.size() - 1);
|
||||
std::uint32_t selectedBattery = weightedBatteries[dis(gen)];
|
||||
|
||||
if (!selectedBattery) return; // No battery needs to be given
|
||||
|
||||
auto* targetSession = room->getPlayer(targetUniqueId);
|
||||
if (targetSession)
|
||||
{
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(targetSession->getId(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setCommand(request.getOrder(), 0, 1, selectedBattery);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&selectedBattery), sizeof(selectedBattery));
|
||||
targetSession->asyncWrite(response);
|
||||
targetSession->addBatteryObtainedInMatch(selectedBattery);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,42 +14,40 @@ namespace Main
|
|||
template<Main::Enums::RoomSimpleSetting T>
|
||||
inline void handleSimpleRoomSetting(const Common::Network::Packet& request, Main::Network::Session& session, Main::Classes::RoomsManager& roomsManager)
|
||||
{
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setCommand(request.getOrder(), request.getMission(), 0, request.getOption());
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(session.getRoomNumber()))
|
||||
{
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(request.getSession(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setCommand(request.getOrder(), request.getMission(), 0, request.getOption());
|
||||
|
||||
auto foundRoom = roomsManager.getRoomByNumber(session.getRoomNumber());
|
||||
if (foundRoom == std::nullopt) return;
|
||||
auto& room = foundRoom.value().get();
|
||||
|
||||
if constexpr (T == Main::Enums::RoomSimpleSetting::SETTING_MAP)
|
||||
{
|
||||
response.setExtra(request.getExtra());
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(const_cast<std::uint8_t*>(request.getData())), request.getDataSize());
|
||||
room.updateMap(request.getExtra());
|
||||
}
|
||||
else if constexpr (T == Main::Enums::RoomSimpleSetting::SETTING_PLAYERS_PER_TEAM)
|
||||
{
|
||||
room.setPlayersPerTeam(request.getOption() / 2); // for square mode where 1 player is chosen, this results in 0 and is taken care elsewhere!
|
||||
}
|
||||
else if constexpr (T == Main::Enums::RoomSimpleSetting::SETTING_TIME)
|
||||
{
|
||||
room.setTime(request.getOption());
|
||||
}
|
||||
else if constexpr (T == Main::Enums::RoomSimpleSetting::SETTING_SPECIFIC)
|
||||
{
|
||||
room.setSpecificSetting(request.getOption());
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr (T == Main::Enums::SETTING_TEAMBALANCE)
|
||||
if constexpr (T == Main::Enums::RoomSimpleSetting::SETTING_MAP)
|
||||
{
|
||||
return; // For now, team balance is not supported: it causes issues such as the team bug.
|
||||
response.setExtra(request.getExtra());
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(const_cast<std::uint8_t*>(request.getData())), request.getDataSize());
|
||||
room->updateMap(request.getExtra());
|
||||
}
|
||||
|
||||
room.switchSimpleSetting<T>();
|
||||
else if constexpr (T == Main::Enums::RoomSimpleSetting::SETTING_PLAYERS_PER_TEAM)
|
||||
{
|
||||
room->setPlayersPerTeam(request.getOption() / 2); // for square mode where 1 player is chosen, this results in 0 and is taken care elsewhere!
|
||||
}
|
||||
else if constexpr (T == Main::Enums::RoomSimpleSetting::SETTING_TIME)
|
||||
{
|
||||
room->setTime(request.getOption());
|
||||
}
|
||||
else if constexpr (T == Main::Enums::RoomSimpleSetting::SETTING_SPECIFIC)
|
||||
{
|
||||
room->setSpecificSetting(request.getOption());
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr (T == Main::Enums::SETTING_TEAMBALANCE)
|
||||
{
|
||||
return; // For now, team balance is not supported: it causes issues such as the team bug.
|
||||
}
|
||||
room->switchSimpleSetting<T>();
|
||||
}
|
||||
room->broadcastToRoom(response);
|
||||
}
|
||||
room.broadcastToRoom(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,18 +47,6 @@ namespace Main
|
|||
void asyncAcceptAuthServer();
|
||||
void initializeAllCommands();
|
||||
void initializeBoxes();
|
||||
|
||||
template<typename T>
|
||||
T parseData(const Common::Network::Packet& request)
|
||||
{
|
||||
assert(sizeof(T) == request.getDataSize());
|
||||
|
||||
T t;
|
||||
std::memcpy(&t, request.getData(), request.getDataSize());
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,10 +46,6 @@ namespace Main
|
|||
disconnectPlayerIfOnline(request.substr(17));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Error during read: " << ec.message() << std::endl;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -61,10 +57,6 @@ namespace Main
|
|||
asio::async_write(m_socket, asio::buffer(totalPlayersOnline),
|
||||
[this, self](asio::error_code ec, std::size_t length)
|
||||
{
|
||||
if (ec)
|
||||
{
|
||||
std::cerr << "Error during write: " << ec.message() << std::endl;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -81,10 +73,6 @@ namespace Main
|
|||
asio::async_write(m_socket, asio::buffer("Invalid account ID\n"),
|
||||
[this, self](asio::error_code ec, std::size_t length)
|
||||
{
|
||||
if (ec)
|
||||
{
|
||||
std::cerr << "Error during write: " << ec.message() << std::endl;
|
||||
}
|
||||
});
|
||||
response = "not_removed";
|
||||
}
|
||||
|
|
@ -103,10 +91,6 @@ namespace Main
|
|||
asio::async_write(m_socket, asio::buffer(response),
|
||||
[this, self](asio::error_code ec, std::size_t length)
|
||||
{
|
||||
if (ec)
|
||||
{
|
||||
std::cerr << "Error during write: " << ec.message() << std::endl;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -121,8 +121,6 @@ namespace Main
|
|||
|
||||
void setAccountMicroPoints(std::uint32_t mp);
|
||||
|
||||
void setAccountCoins(std::uint16_t coins);
|
||||
|
||||
void setAccountLatestCharacterSelected(std::uint16_t latestCharacterSelected);
|
||||
|
||||
void setLevel(std::uint16_t level);
|
||||
|
|
@ -131,7 +129,6 @@ namespace Main
|
|||
|
||||
bool addEnergyToItem(const Main::Structures::ItemSerialInfo& itemSerialInfo, std::uint32_t energyAdded);
|
||||
|
||||
|
||||
void addFriend(const Main::Structures::Friend& ffriend);
|
||||
|
||||
bool isFriend(std::uint32_t accountId);
|
||||
|
|
@ -150,8 +147,6 @@ namespace Main
|
|||
|
||||
std::pair<std::array<std::uint32_t, 10>, std::array<std::uint32_t, 7>> getEquippedItemsSeparated() const;
|
||||
|
||||
void setIsInLobby(bool val);
|
||||
|
||||
bool isInLobby() const;
|
||||
|
||||
void switchItemEquip(std::uint32_t characterId, std::uint64_t itemNumber);
|
||||
|
|
@ -184,7 +179,6 @@ namespace Main
|
|||
|
||||
Common::Enums::PlayerState getPlayerState() const;
|
||||
|
||||
|
||||
void addLuckyPoints(std::uint32_t points);
|
||||
|
||||
void setLuckyPoints(std::uint32_t points);
|
||||
|
|
|
|||
|
|
@ -109,7 +109,6 @@ namespace Main
|
|||
playerInfoStructure.accountKey = static_cast<std::uint32_t>(query.getColumn("AccountKey").getInt());
|
||||
playerInfoStructure.totalKills = static_cast<std::uint32_t>(query.getColumn("Kills").getInt());
|
||||
playerInfoStructure.deaths = static_cast<std::uint32_t>(query.getColumn("Deaths").getInt());
|
||||
//playerInfoStructure.assists = static_cast<std::uint32_t>(query.getColumn("Assists").getInt());
|
||||
playerInfoStructure.wins = static_cast<std::uint32_t>(query.getColumn("Wins").getInt());
|
||||
playerInfoStructure.losses = static_cast<std::uint32_t>(query.getColumn("Loses").getInt());
|
||||
playerInfoStructure.draws = static_cast<std::uint32_t>(query.getColumn("Draws").getInt());
|
||||
|
|
@ -128,7 +127,6 @@ namespace Main
|
|||
playerInfoStructure.playerLevel = static_cast<std::uint64_t>(query.getColumn("Level").getInt()) + 1;
|
||||
playerInfoStructure.battery = static_cast<std::uint64_t>(query.getColumn("Battery").getInt());
|
||||
playerInfoStructure.luckyPoints = static_cast<std::uint64_t>(query.getColumn("LuckyPoints").getInt());
|
||||
//playerInfoStructure.coins = static_cast<std::uint64_t>(query.getColumn("Coins").getInt());
|
||||
playerInfoStructure.playerGrade = static_cast<std::uint64_t>(query.getColumn("Grade").getInt());
|
||||
playerInfoStructure.experience = static_cast<std::uint32_t>(query.getColumn("Experience").getInt());
|
||||
playerInfoStructure.microPoints = static_cast<std::uint64_t>(query.getColumn("MicroPoints").getInt64());
|
||||
|
|
@ -139,7 +137,6 @@ namespace Main
|
|||
playerInfoStructure.singleWaveAttempts = static_cast<std::uint32_t>(query.getColumn("SingleWaveAttempts").getInt());
|
||||
playerInfoStructure.highestSinglewaveStage = static_cast<std::uint32_t>(query.getColumn("SingleWaveAttempts").getInt());
|
||||
playerInfoStructure.highestSingleWaveScore = static_cast<std::uint32_t>(query.getColumn("HighestSinglewaveScore").getInt());
|
||||
//playerInfoStructure.vipExperience = static_cast<std::uint32_t>(query.getColumn("VipExperience").getInt());
|
||||
playerInfoStructure.clanContribution = static_cast<std::uint64_t>(query.getColumn("ClanContribution").getInt64());
|
||||
playerInfoStructure.clanLogoFrontId = static_cast<std::uint64_t>(query.getColumn("ClanFrontIcon").getInt());
|
||||
playerInfoStructure.clanLogoBackId = static_cast<std::uint64_t>(query.getColumn("ClanBackIcon").getInt());
|
||||
|
|
@ -259,7 +256,6 @@ namespace Main
|
|||
}
|
||||
|
||||
|
||||
// Returing const& causes exceptions later...?
|
||||
auto getPlayerItems(std::uint32_t playerID) const
|
||||
-> std::pair<std::vector<Item>, std::unordered_map<std::uint16_t, std::vector<EquippedItem>>>
|
||||
{
|
||||
|
|
@ -306,44 +302,8 @@ namespace Main
|
|||
}
|
||||
item.expirationDate = static_cast<__time32_t>(newExpDate);
|
||||
}
|
||||
|
||||
// REMOVE THIS
|
||||
//Main::ConstantDatabase::CdbUtil cdbUtil(item.id);
|
||||
//auto durability = *(cdbUtil.getItemDurability());
|
||||
//auto duration = *(cdbUtil.getItemDuration());
|
||||
////
|
||||
|
||||
item.durability = static_cast<std::uint16_t>(allItemsQuery.getColumn("durability").getInt());
|
||||
item.energy = static_cast<std::uint16_t>(allItemsQuery.getColumn("energy").getInt());
|
||||
|
||||
/*item.isSealed = static_cast<std::uint32_t>(allItemsQuery.getColumn("isSealed").getInt());
|
||||
item.sealLevel = static_cast<std::uint32_t>(allItemsQuery.getColumn("sealLevel").getInt());
|
||||
item.experienceEnhancement = static_cast<std::uint32_t>(allItemsQuery.getColumn("expEnhancement").getInt());
|
||||
item.mpEnhancement = static_cast<std::uint32_t>(allItemsQuery.getColumn("mpEnhancement").getInt());
|
||||
item.unknown = static_cast<std::uint32_t>(allItemsQuery.getColumn("unknown"));
|
||||
*/
|
||||
|
||||
// REMOVE THIS
|
||||
/*
|
||||
SQLite::Statement updateDurabilityQuery(db, "UPDATE UserItems SET durability = :durability WHERE rowid = :rowid");
|
||||
updateDurabilityQuery.bind(":durability", durability);
|
||||
updateDurabilityQuery.bind(":rowid", rowId);
|
||||
if (!updateDurabilityQuery.exec())
|
||||
{
|
||||
std::cerr << "DurabilityUpdate error in getPlayerItems(): " << updateDurabilityQuery.getExtendedErrorCode() << '\n';
|
||||
std::cerr << "Error message: " << updateDurabilityQuery.getErrorMsg() << '\n';
|
||||
}
|
||||
|
||||
SQLite::Statement updateDuration(db, "UPDATE UserItems SET ItemDuration = :duration WHERE rowid = :rowid");
|
||||
updateDuration.bind(":duration", duration);
|
||||
updateDuration.bind(":rowid", rowId);
|
||||
if (!updateDuration.exec())
|
||||
{
|
||||
std::cerr << "DurabilityUpdate error in getPlayerItems(): " << updateDuration.getExtendedErrorCode() << '\n';
|
||||
std::cerr << "Error message: " << updateDuration.getErrorMsg() << '\n';
|
||||
}*/
|
||||
////
|
||||
|
||||
if (allItemsQuery.getColumn("IsEquipped").getInt() == 1)
|
||||
{
|
||||
Main::Structures::EquippedItem equippedItem{ item };
|
||||
|
|
@ -627,7 +587,6 @@ namespace Main
|
|||
query.bind(9, updatedAccountInfo.totalKills);
|
||||
query.bind(10, updatedAccountInfo.deaths);
|
||||
query.bind(11, static_cast<std::uint32_t>(updatedAccountInfo.headshots));
|
||||
// query.bind(12, updatedAccountInfo.assists);
|
||||
query.bind(13, updatedAccountInfo.experience);
|
||||
query.bind(14, static_cast<std::uint32_t>(updatedAccountInfo.microPoints));
|
||||
query.bind(15, updatedAccountInfo.wins);
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
#ifndef CLIENT_PING_DATA_MAIN_H
|
||||
#define CLIENT_PING_DATA_MAIN_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Main
|
||||
{
|
||||
namespace ClientData
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
struct Ping
|
||||
{
|
||||
std::uint32_t unused : 10 = 0; // recheck whether this really is unused
|
||||
std::uint32_t ping : 10 = 0;
|
||||
std::uint32_t rest : 12 = 0;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
53
MainServer/include/Structures/ClientData/Structures.h
Normal file
53
MainServer/include/Structures/ClientData/Structures.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef CLIENT_REQUEST_STRUCTURES_H
|
||||
#define CLIENT_REQUEST_STRUCTURES_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Main
|
||||
{
|
||||
namespace ClientData
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
struct Ping
|
||||
{
|
||||
std::uint32_t unused : 10 = 0; // recheck whether this really is unused
|
||||
std::uint32_t ping : 10 = 0;
|
||||
std::uint32_t rest : 12 = 0;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct ItemRefund
|
||||
{
|
||||
Main::Structures::ItemSerialInfo serialInfo{};
|
||||
std::uint32_t mpToAdd{};
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct ItemUpgrade
|
||||
{
|
||||
Main::Structures::ItemSerialInfo serialInfo{};
|
||||
std::uint32_t usedEnergy{};
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct MailboxMessage
|
||||
{
|
||||
char nickname[16]{};
|
||||
char message[256]{};
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct RoomInfo
|
||||
{
|
||||
std::uint16_t roomNumber{};
|
||||
std::uint16_t unknown{};
|
||||
char password[8]{};
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -14,8 +14,8 @@ namespace Main
|
|||
std::uint32_t accountId{};
|
||||
std::uint32_t timestamp{};
|
||||
std::uint32_t hasBeenRead{};
|
||||
char nickname[16]{"test2"};
|
||||
char message[256]{"this is the message ahha aisdansrnajsd"};
|
||||
char nickname[16]{};
|
||||
char message[256]{};
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,17 @@ namespace Main
|
|||
PLAYER_ITEMS_BROADCAST = 414,
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
T parseData(const Common::Network::Packet& request, std::uint32_t offset = 0)
|
||||
{
|
||||
// this is not always necessarily true:
|
||||
// assert(sizeof(T) == request.getDataSize());
|
||||
|
||||
T t;
|
||||
std::memcpy(&t, request.getData() + offset, request.getDataSize());
|
||||
return t;
|
||||
}
|
||||
|
||||
inline void sendMessage(const std::string& message, Main::Network::Session& session)
|
||||
{
|
||||
Common::Network::Packet response;
|
||||
|
|
@ -35,13 +46,20 @@ namespace Main
|
|||
session.asyncWrite(response);
|
||||
}
|
||||
|
||||
inline void sendPlayerState(Main::Network::Session& session, Main::Structures::UniqueId uniqueId)
|
||||
{
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(session.getId(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setCommand(312, 0, 0, 2);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&uniqueId), sizeof(uniqueId));
|
||||
session.asyncWrite(response);
|
||||
}
|
||||
|
||||
inline void broadcastPlayerItems(Main::Classes::RoomsManager& roomsManager, Main::Network::Session& session, const Common::Network::Packet& request)
|
||||
{
|
||||
auto foundRoom = roomsManager.getRoomByNumber(session.getRoomNumber());
|
||||
if (foundRoom)
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(session.getRoomNumber()))
|
||||
{
|
||||
auto& room = foundRoom->get();
|
||||
room.updatePlayerInfo(&session);
|
||||
room->updatePlayerInfo(&session);
|
||||
|
||||
using setItems = Common::ConstantDatabase::CdbSingleton<Common::ConstantDatabase::SetItemInfo>;
|
||||
struct Resp
|
||||
|
|
@ -67,17 +85,12 @@ namespace Main
|
|||
{
|
||||
for (auto currentTypeNotNull : Common::Utils::getPartTypesWhereSetItemInfoTypeNotNull(*entry))
|
||||
{
|
||||
std::cout << "(in set) Item found for type: " << type << '\n';
|
||||
resp.items[currentTypeNotNull].equippedItemId = item.id;
|
||||
resp.items[currentTypeNotNull].type = currentTypeNotNull;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Item found for type: " << type << '\n';
|
||||
resp.items[type] = item;
|
||||
}
|
||||
else resp.items[type] = item;
|
||||
}
|
||||
|
||||
Common::Network::Packet response;
|
||||
|
|
|
|||
|
|
@ -21,16 +21,13 @@ namespace Main
|
|||
return;
|
||||
}
|
||||
|
||||
auto foundRoom = roomsManager.getRoomByNumber(session.getRoomNumber());
|
||||
if (foundRoom == std::nullopt)
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(session.getRoomNumber()))
|
||||
{
|
||||
this->m_confirmationMessage += "error: room not found";
|
||||
this->m_confirmationMessage += "command under maintenance";
|
||||
sendConfirmation(response, session);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& room = foundRoom.value().get();
|
||||
const bool changed = room.changeHostByNickname(m_value);
|
||||
return;
|
||||
|
||||
const bool changed = false; //room->changeHostByNickname(m_value);
|
||||
if (!changed)
|
||||
{
|
||||
this->m_confirmationMessage += "error";
|
||||
|
|
@ -42,6 +39,11 @@ namespace Main
|
|||
sendConfirmation(response, session);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_confirmationMessage += "error: room not found";
|
||||
sendConfirmation(response, session);
|
||||
}
|
||||
}
|
||||
|
||||
void ChangeHost::getCommandUsage(Main::Network::Session& session, Common::Network::Packet& response)
|
||||
|
|
|
|||
|
|
@ -27,26 +27,26 @@ namespace Main
|
|||
return;
|
||||
}
|
||||
|
||||
auto roomOpt = roomsManager.getRoomByNumber(session.getRoomNumber());
|
||||
if (roomOpt == std::nullopt)
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(session.getRoomNumber()))
|
||||
{
|
||||
if (!room->kickPlayer(m_value.c_str()))
|
||||
{
|
||||
this->m_confirmationMessage += "Error: the player is either not in the room or they're >= MOD grade.";
|
||||
sendConfirmation(response, session);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_confirmationMessage += "success";
|
||||
sendConfirmation(response, session);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_confirmationMessage += "You must be inside a room to kick a player.";
|
||||
sendConfirmation(response, session);
|
||||
return;
|
||||
}
|
||||
|
||||
Main::Classes::Room& room = roomOpt.value().get();
|
||||
const bool kicked = room.kickPlayer(m_value.c_str());
|
||||
|
||||
if (!kicked)
|
||||
{
|
||||
this->m_confirmationMessage += "Error: the player is either not in the room or they're >= MOD grade.";
|
||||
sendConfirmation(response, session);
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_confirmationMessage += "success";
|
||||
sendConfirmation(response, session);
|
||||
}
|
||||
|
||||
void KickPlayer::getCommandUsage(Main::Network::Session& session, Common::Network::Packet& response)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ namespace Main
|
|||
};
|
||||
session.setAccountMicroPoints(536870912);
|
||||
session.setAccountRockTotens(536870912);
|
||||
session.setAccountCoins(100);
|
||||
|
||||
const auto& accountInfo = session.getAccountInfo();
|
||||
Message message{ accountInfo.rockTotens, accountInfo.microPoints };
|
||||
|
|
|
|||
|
|
@ -22,20 +22,13 @@ namespace Main
|
|||
void Breakroom::execute(Main::Network::Session& session, Main::Classes::RoomsManager& roomsManager, std::size_t roomNumber, Common::Network::Packet& response)
|
||||
{
|
||||
this->m_confirmationMessage += "success";
|
||||
|
||||
response.setOrder(137);
|
||||
response.setExtra(0x1B);
|
||||
|
||||
auto foundRoom = roomsManager.getRoomByNumber(roomNumber);
|
||||
if (foundRoom == std::nullopt)
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(roomNumber))
|
||||
{
|
||||
this->m_confirmationMessage += "error";
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& room = foundRoom.value().get();
|
||||
// kick whole room
|
||||
room.broadcastToRoom(response);
|
||||
room->broadcastToRoom(response);
|
||||
|
||||
// notify room
|
||||
response.setOrder(316);
|
||||
|
|
@ -45,12 +38,16 @@ namespace Main
|
|||
message += "The room has been closed by a MOD/GM";
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(message.data()), message.size());
|
||||
response.setOption(message.size());
|
||||
room.broadcastToRoom(response);
|
||||
room->broadcastToRoom(response);
|
||||
|
||||
// delete the room
|
||||
room.breakroom();
|
||||
room->breakroom();
|
||||
roomsManager.removeRoom(roomNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_confirmationMessage += "error";
|
||||
}
|
||||
sendConfirmation(response, session);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,17 +21,14 @@ namespace Main
|
|||
|
||||
void Muteroom::execute(Main::Network::Session& session, Main::Classes::RoomsManager& roomsManager, std::size_t roomNumber, Common::Network::Packet& response)
|
||||
{
|
||||
this->m_confirmationMessage += "success";
|
||||
|
||||
auto foundRoom = roomsManager.getRoomByNumber(roomNumber);
|
||||
if (foundRoom == std::nullopt)
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(roomNumber))
|
||||
{
|
||||
this->m_confirmationMessage += "error";
|
||||
room->muteRoom();
|
||||
this->m_confirmationMessage += "success";
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& room = foundRoom.value().get();
|
||||
room.muteRoom();
|
||||
this->m_confirmationMessage += "error";
|
||||
}
|
||||
sendConfirmation(response, session);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,17 +21,14 @@ namespace Main
|
|||
|
||||
void UnmuteRoom::execute(Main::Network::Session& session, Main::Classes::RoomsManager& roomsManager, std::size_t roomNumber, Common::Network::Packet& response)
|
||||
{
|
||||
this->m_confirmationMessage += "success";
|
||||
|
||||
auto foundRoom = roomsManager.getRoomByNumber(roomNumber);
|
||||
if (foundRoom == std::nullopt)
|
||||
if (Main::Classes::Room* room = roomsManager.getRoomByNumber(roomNumber))
|
||||
{
|
||||
this->m_confirmationMessage += "error";
|
||||
room->unmuteRoom();
|
||||
this->m_confirmationMessage += "success";
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& room = foundRoom.value().get();
|
||||
room.unmuteRoom();
|
||||
this->m_confirmationMessage += "error";
|
||||
}
|
||||
sendConfirmation(response, session);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,11 +100,6 @@ namespace Main
|
|||
m_accountInfo.microPoints = mp;
|
||||
}
|
||||
|
||||
void Player::setAccountCoins(std::uint16_t coins)
|
||||
{
|
||||
//m_accountInfo.coins = coins;
|
||||
}
|
||||
|
||||
void Player::setAccountLatestCharacterSelected(std::uint16_t latestCharacterSelected)
|
||||
{
|
||||
m_accountInfo.latestSelectedCharacter = latestCharacterSelected;
|
||||
|
|
@ -135,14 +130,10 @@ namespace Main
|
|||
return m_playerState;
|
||||
}
|
||||
|
||||
void Player::setIsInLobby(bool val)
|
||||
{
|
||||
m_isInLobby = val;
|
||||
}
|
||||
|
||||
|
||||
bool Player::isInLobby() const
|
||||
{
|
||||
return m_isInLobby;
|
||||
return m_roomNumber == 0;
|
||||
}
|
||||
|
||||
Main::Structures::MuteInfo Player::getMuteInfo() const
|
||||
|
|
@ -413,15 +404,11 @@ namespace Main
|
|||
{
|
||||
auto& itemMap = m_equippedItemByCharacter[character == -1 ? m_accountInfo.latestSelectedCharacter : character];
|
||||
if (!itemMap.contains(itemType)) return;
|
||||
std::cout << "Unequipping for Character: " << m_accountInfo.latestSelectedCharacter << '\n';
|
||||
|
||||
auto itemNumber = itemMap.at(itemType).serialInfo.itemNumber;
|
||||
m_itemsByItemNumber[itemNumber] = Item{ itemMap.at(itemType) };
|
||||
itemMap.erase(itemType);
|
||||
--m_totalEquippedItems;
|
||||
|
||||
std::cout << "Item Unequipped with Type: " << itemType << '\n';
|
||||
|
||||
scheduler.addRepetitiveCallback(m_accountInfo.accountID, &Main::Persistence::PersistentDatabase::unequipItem,
|
||||
m_accountInfo.accountID, static_cast<std::uint64_t>(itemNumber));
|
||||
}
|
||||
|
|
@ -444,7 +431,6 @@ namespace Main
|
|||
{
|
||||
for (auto currentTypeNotNull : Common::Utils::getPartTypesWhereSetItemInfoTypeNotNull(*entry))
|
||||
{
|
||||
std::cout << "Set Part Found. Unequipping (Type: " << currentTypeNotNull << ")\n";
|
||||
unequipItemImpl(currentTypeNotNull, scheduler, character);
|
||||
}
|
||||
}
|
||||
|
|
@ -455,7 +441,6 @@ namespace Main
|
|||
// Again, special case: the user has an already equipped set. We need to unequip it if the user is now equipping a part type that is already present in said set.
|
||||
if (itemMap.contains(Common::Enums::ItemType::SET))
|
||||
{
|
||||
std::cout << "User has a Set Equipped. Unequipping the set before equipping the parts...\n";
|
||||
using setItems = Common::ConstantDatabase::CdbSingleton<Common::ConstantDatabase::SetItemInfo>;
|
||||
const auto entry = setItems::getInstance().getEntry("si_id", itemMap[Common::Enums::ItemType::SET].id >> 1);
|
||||
|
||||
|
|
@ -465,7 +450,6 @@ namespace Main
|
|||
{
|
||||
if (equippedItem.type == currentTypeNotNull)
|
||||
{
|
||||
std::cout << "Set Found. Unequipping...\n";
|
||||
unequipItemImpl(Common::Enums::SET, scheduler, character);
|
||||
break;
|
||||
}
|
||||
|
|
@ -479,8 +463,6 @@ namespace Main
|
|||
// now proceed normally: check if equippedItems already has such a type
|
||||
if (itemMap.contains(equippedItem.type))
|
||||
{
|
||||
std::cout << "Unequipping Item...\n";
|
||||
|
||||
auto toUnequipItemNumber = itemMap.at(equippedItem.type).serialInfo.itemNumber;
|
||||
m_itemsByItemNumber[toUnequipItemNumber] = Item{ itemMap.at(equippedItem.type) };
|
||||
itemMap.erase(equippedItem.type);
|
||||
|
|
@ -508,7 +490,6 @@ namespace Main
|
|||
|
||||
if (!itemMap.contains(itemType))
|
||||
{
|
||||
std::cout << "Item NOT unequipped!\n";
|
||||
return std::nullopt;
|
||||
}
|
||||
std::uint64_t itemNumber = itemMap.at(itemType).serialInfo.itemNumber;
|
||||
|
|
@ -516,7 +497,6 @@ namespace Main
|
|||
m_itemsByItemNumber[itemNumber] = Item{ itemMap.at(itemType) };
|
||||
itemMap.erase(itemType);
|
||||
--m_totalEquippedItems;
|
||||
std::cout << "Item Unequipped\n";
|
||||
return itemNumber;
|
||||
}
|
||||
|
||||
|
|
@ -539,7 +519,6 @@ namespace Main
|
|||
{
|
||||
if (!m_equippedItemByCharacter.contains(characterId))
|
||||
{
|
||||
std::cout << "Char Not Found [unequip]\n";
|
||||
return false;
|
||||
}
|
||||
auto& itemMap = m_equippedItemByCharacter.at(characterId);
|
||||
|
|
@ -551,7 +530,6 @@ namespace Main
|
|||
return true;
|
||||
}
|
||||
}
|
||||
std::cout << "Item not found [unequip]\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -559,7 +537,6 @@ namespace Main
|
|||
{
|
||||
if (!m_equippedItemByCharacter.contains(characterId))
|
||||
{
|
||||
std::cout << "Char Not Found [equip]\n";
|
||||
return;
|
||||
}
|
||||
auto& itemMap = m_equippedItemByCharacter.at(characterId);
|
||||
|
|
@ -567,7 +544,6 @@ namespace Main
|
|||
{
|
||||
if (equippedItem.serialInfo.itemNumber == itemNumber)
|
||||
{
|
||||
std::cout << "itemnumber found in equipped, no need to re-equip [requip]\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -735,7 +711,6 @@ namespace Main
|
|||
void Player::leaveRoom()
|
||||
{
|
||||
setRoomNumber(0);
|
||||
setIsInLobby(true);
|
||||
setIsInMatch(false);
|
||||
m_batteryObtainedInMatch = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <Enums/PlayerEnums.h>
|
||||
#include <Utils/Logger.h>
|
||||
#include <range/v3/all.hpp>
|
||||
#include "../../include/Utilities.h"
|
||||
|
||||
namespace Main
|
||||
{
|
||||
|
|
@ -27,13 +28,11 @@ namespace Main
|
|||
{
|
||||
const auto pair = std::pair{ player, session };
|
||||
m_players.push_back(pair);
|
||||
m_settings = settings;
|
||||
|
||||
m_playerSessionIdToVecIdx[session->getId()] = m_players.size() - 1;
|
||||
m_isTeamBalanceOn = false; // For now, team balance isn't supported as it causes issues e.g. team bug.
|
||||
//m_isTeamBalanceOn = isModeTeamBased() ? true : false; // Team balance is by default on for team-based modes
|
||||
}
|
||||
|
||||
void Room::addPlayer(Main::Network::Session* session, std::uint32_t team)
|
||||
Main::Structures::RoomPlayerInfo Room::createRoomPlayerInfo(Main::Network::Session* session, std::uint32_t team) const
|
||||
{
|
||||
const auto& accountInfo = session->getAccountInfo();
|
||||
Main::Structures::RoomPlayerInfo roomPlayerInfo;
|
||||
|
|
@ -41,42 +40,36 @@ namespace Main
|
|||
roomPlayerInfo.level = accountInfo.playerLevel;
|
||||
roomPlayerInfo.ping = session->getPing();
|
||||
std::memcpy(roomPlayerInfo.playerName, accountInfo.nickname, 16);
|
||||
roomPlayerInfo.state = Common::Enums::STATE_WAITING;
|
||||
roomPlayerInfo.uniqueId = accountInfo.uniqueId;
|
||||
roomPlayerInfo.team = team;
|
||||
roomPlayerInfo.state = Common::Enums::STATE_WAITING;
|
||||
return roomPlayerInfo;
|
||||
}
|
||||
|
||||
m_players.push_back(std::pair{ roomPlayerInfo, session });
|
||||
void Room::addPlayer(Main::Network::Session* session, std::uint32_t team)
|
||||
{
|
||||
auto roomPlayerInfo = createRoomPlayerInfo(session, team);
|
||||
m_players.emplace_back(roomPlayerInfo, session);
|
||||
m_playerSessionIdToVecIdx[session->getId()] = m_players.size() - 1;
|
||||
session->setRoomNumber(m_number);
|
||||
}
|
||||
|
||||
void Room::addObserverPlayer(Main::Network::Session* session)
|
||||
{
|
||||
const auto& accountInfo = session->getAccountInfo();
|
||||
Main::Structures::RoomPlayerInfo roomPlayerInfo;
|
||||
roomPlayerInfo.ping = session->getPing();
|
||||
roomPlayerInfo.character = accountInfo.latestSelectedCharacter;
|
||||
roomPlayerInfo.level = accountInfo.playerLevel;
|
||||
std::memcpy(roomPlayerInfo.playerName, accountInfo.nickname, 16);
|
||||
roomPlayerInfo.uniqueId = accountInfo.uniqueId;
|
||||
roomPlayerInfo.team = Common::Enums::Team::TEAM_OBSERVER;
|
||||
roomPlayerInfo.state = Common::Enums::STATE_WAITING;
|
||||
|
||||
m_observerPlayers.push_back(std::pair{ roomPlayerInfo, session });
|
||||
auto roomPlayerInfo = createRoomPlayerInfo(session, Common::Enums::Team::TEAM_OBSERVER);
|
||||
m_observerPlayers.emplace_back(roomPlayerInfo, session);
|
||||
m_obsPlayerSessionIdToVecIdx[session->getId()] = m_observerPlayers.size() - 1;
|
||||
session->setRoomNumber(m_number);
|
||||
}
|
||||
|
||||
void Room::setTick(std::uint64_t tick)
|
||||
{
|
||||
m_tick = tick;
|
||||
}
|
||||
|
||||
std::uint32_t Room::getPlayerIdx(std::uint64_t playerId) const
|
||||
{
|
||||
for (std::uint32_t idx = 0; const auto& [roomInfo, session] : m_players)
|
||||
auto indexIter = m_playerSessionIdToVecIdx.find(playerId);
|
||||
if (indexIter != m_playerSessionIdToVecIdx.end())
|
||||
{
|
||||
if (session->getId() == playerId) return idx;
|
||||
++idx;
|
||||
return indexIter->second;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Room::setPassword(const std::string& password)
|
||||
|
|
@ -96,15 +89,12 @@ namespace Main
|
|||
|
||||
void Room::updatePlayerInfo(Main::Network::Session* session)
|
||||
{
|
||||
for (auto& [roomInfo, playerSession] : ranges::views::concat(m_players, m_observerPlayers))
|
||||
auto indexIter = m_playerSessionIdToVecIdx.find(session->getId());
|
||||
if (indexIter != m_playerSessionIdToVecIdx.end())
|
||||
{
|
||||
if (playerSession->getId() == session->getId())
|
||||
{
|
||||
const auto& accountInfo = session->getAccountInfo();
|
||||
roomInfo.character = accountInfo.latestSelectedCharacter;
|
||||
roomInfo.level = accountInfo.playerLevel;
|
||||
break;
|
||||
}
|
||||
const auto& accountInfo = session->getAccountInfo();
|
||||
m_players[indexIter->second].first.character = accountInfo.latestSelectedCharacter;
|
||||
m_players[indexIter->second].first.level = accountInfo.playerLevel;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -152,6 +142,8 @@ namespace Main
|
|||
|
||||
removePlayer(m_players);
|
||||
removePlayer(m_observerPlayers);
|
||||
m_obsPlayerSessionIdToVecIdx.clear();
|
||||
m_playerSessionIdToVecIdx.clear();
|
||||
}
|
||||
|
||||
// Returns the index of the player with the best ms, and if no player is found that meets the requirements, -1 is returned to signal that.
|
||||
|
|
@ -233,6 +225,9 @@ namespace Main
|
|||
hostChange.setExtra(Common::Enums::CHANGE_HOST_SUCCESS);
|
||||
broadcastToRoom(hostChange);
|
||||
|
||||
// Unmap original host
|
||||
m_playerSessionIdToVecIdx.erase(originalHostSessionId);
|
||||
|
||||
// Leave match + room packets.
|
||||
m_players[bestMsPlayerIdxInMatch].second->asyncWrite(removePlayerFromRoomServerRequest);
|
||||
m_players[bestMsPlayerIdxInMatch].second->leaveRoom();
|
||||
|
|
@ -276,6 +271,9 @@ namespace Main
|
|||
+ ", idx of new host: " + std::to_string(bestMsIndexPlayerOutsideMatch),
|
||||
Utils::LogType::Normal, "Room::removeHostFromMatch");
|
||||
|
||||
// Unmap original host
|
||||
m_playerSessionIdToVecIdx.erase(originalHostSessionId);
|
||||
|
||||
// If a new match-host has been taken, notify whole room about it.
|
||||
hostChange.setOption(bestMsIndexPlayerOutsideMatch);
|
||||
hostChange.setExtra(Common::Enums::CHANGE_HOST_SUCCESS);
|
||||
|
|
@ -310,59 +308,6 @@ namespace Main
|
|||
return true;
|
||||
}
|
||||
}
|
||||
else // If the host was alone in the whole room (e.g. SquareMode, AI, BossBattle, and none outside the match), remove it from the room and close it.
|
||||
{
|
||||
logger.log("The host is leaving and no other host can be picked up. Leaving the room and closing it...",
|
||||
Utils::LogType::Normal, "Room::removeHostFromMatch");
|
||||
|
||||
m_players[0].second->asyncWrite(removePlayerFromRoomServerRequest);
|
||||
m_players[0].second->leaveRoom();
|
||||
m_players.clear();
|
||||
|
||||
for (auto& [unused, obsSession] : m_observerPlayers)
|
||||
{
|
||||
obsSession->asyncWrite(removePlayerFromRoomServerRequest);
|
||||
obsSession->leaveRoom();
|
||||
}
|
||||
m_observerPlayers.clear();
|
||||
m_hasMatchStarted = false;
|
||||
|
||||
logger.log(getRoomInfoAsString(), Utils::LogType::Normal, "Room::removeHostFromMatch");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Room::changeHostByNickname(const std::string& newHostNickname)
|
||||
{
|
||||
// find player index inside the room through to their nickname
|
||||
std::uint32_t targetIndex = 0;
|
||||
std::uint32_t currentIndex = 0;
|
||||
std::uint32_t sessionId = 0;
|
||||
for (const auto& [roomInfo, session] : m_players)
|
||||
{
|
||||
if (std::strncmp(roomInfo.playerName, newHostNickname.c_str(), sizeof(roomInfo.playerName)) == 0)
|
||||
{
|
||||
targetIndex = currentIndex;
|
||||
sessionId = roomInfo.uniqueId.session;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
++currentIndex;
|
||||
}
|
||||
}
|
||||
if (currentIndex >= m_players.size()) return false; // player with target nickname not found
|
||||
if (changeHost(targetIndex))
|
||||
{
|
||||
Common::Network::Packet hostChange;
|
||||
hostChange.setTcpHeader(sessionId, Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
hostChange.setOrder(124);
|
||||
hostChange.setOption(targetIndex);
|
||||
hostChange.setExtra(Common::Enums::CHANGE_HOST_SUCCESS);
|
||||
broadcastToRoom(hostChange);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns true if the room must be also be closed (e.g. due to host-switch errors, or because no other player is inside the room), false otherwise.
|
||||
|
|
@ -374,6 +319,7 @@ namespace Main
|
|||
removePlayerFromRoomServerRequest.setTcpHeader(session->getId(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
removePlayerFromRoomServerRequest.setOrder(137);
|
||||
removePlayerFromRoomServerRequest.setExtra(extra);
|
||||
std::uint32_t originalSessionId = session->getId();
|
||||
|
||||
auto playerIter = std::find_if(m_players.begin(), m_players.end(), [session](const auto& currentSession) { return currentSession.second == session; });
|
||||
|
||||
|
|
@ -431,6 +377,9 @@ namespace Main
|
|||
Main::Handlers::notifyRoomPlayerLeaves(playerIter->second->getAccountInfo().uniqueId, *this);
|
||||
m_players.erase(playerIter);
|
||||
|
||||
// unmap original host
|
||||
m_playerSessionIdToVecIdx.erase(originalSessionId);
|
||||
|
||||
logger.log("Removed player from room. " + playerIter->second->getPlayerInfoAsString(),
|
||||
Utils::LogType::Normal, "Room::removePlayer");
|
||||
logger.log(getRoomInfoAsString(), Utils::LogType::Normal, "Room::removePlayer");
|
||||
|
|
@ -449,6 +398,7 @@ namespace Main
|
|||
observerIter->second->leaveRoom();
|
||||
Main::Handlers::notifyRoomPlayerLeaves(observerIter->second->getAccountInfo().uniqueId, *this);
|
||||
m_observerPlayers.erase(observerIter);
|
||||
m_obsPlayerSessionIdToVecIdx.erase(originalSessionId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -494,7 +444,6 @@ namespace Main
|
|||
return m_settings;
|
||||
}
|
||||
|
||||
// Specific setting is missing here!
|
||||
Main::Structures::RoomJoin Room::getRoomJoinInfo() const
|
||||
{
|
||||
Main::Structures::RoomJoin roomJoinInfo;
|
||||
|
|
@ -558,6 +507,8 @@ namespace Main
|
|||
}
|
||||
m_players.clear();
|
||||
m_observerPlayers.clear();
|
||||
m_obsPlayerSessionIdToVecIdx.clear();
|
||||
m_playerSessionIdToVecIdx.clear();
|
||||
}
|
||||
|
||||
// Broadcasts to whole room (room + match)
|
||||
|
|
@ -570,8 +521,6 @@ namespace Main
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Room::broadcastToRoomExceptSelf(Common::Network::Packet& packet, const Main::Structures::UniqueId& uniqueId)
|
||||
{
|
||||
for (auto& currentPlayer : ranges::views::concat(m_players, m_observerPlayers))
|
||||
|
|
@ -584,21 +533,17 @@ namespace Main
|
|||
|
||||
void Room::broadcastToTeamExceptSelf(Common::Network::Packet& packet, const Main::Structures::UniqueId& uniqueId, bool checkInsideMatch)
|
||||
{
|
||||
Common::Enums::Team targetTeam = Common::Enums::Team::TEAM_ALL;
|
||||
for (const auto& [roomInfo, session] : m_players)
|
||||
auto indexIter = m_playerSessionIdToVecIdx.find(uniqueId.session);
|
||||
if (indexIter != m_playerSessionIdToVecIdx.end())
|
||||
{
|
||||
if (roomInfo.uniqueId == uniqueId)
|
||||
Common::Enums::Team targetTeam = static_cast<Common::Enums::Team>(m_players[indexIter->second].first.team);
|
||||
for (auto& [roomInfo, session] : m_players)
|
||||
{
|
||||
targetTeam = static_cast<Common::Enums::Team>(roomInfo.team);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (auto& [roomInfo, session] : m_players)
|
||||
{
|
||||
if (roomInfo.uniqueId != uniqueId && roomInfo.team == targetTeam && ((checkInsideMatch && session->isInMatch()) || (!checkInsideMatch && !session->isInMatch())))
|
||||
{
|
||||
packet.setTcpHeader(session->getSessionId(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
session->asyncWrite(packet);
|
||||
if (roomInfo.uniqueId != uniqueId && roomInfo.team == targetTeam && ((checkInsideMatch && session->isInMatch()) || (!checkInsideMatch && !session->isInMatch())))
|
||||
{
|
||||
packet.setTcpHeader(session->getSessionId(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
session->asyncWrite(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -612,16 +557,18 @@ namespace Main
|
|||
else
|
||||
{
|
||||
bool broadcastOnlyToObs = false;
|
||||
auto indexIter = m_obsPlayerSessionIdToVecIdx.find(uniqueId.session);
|
||||
if (indexIter != m_obsPlayerSessionIdToVecIdx.end())
|
||||
{
|
||||
// >= MOD grade messages are broadcast to whole room, even outside observer
|
||||
if (m_observerPlayers[indexIter->second].second->getAccountInfo().playerGrade < Common::Enums::GRADE_MOD)
|
||||
{
|
||||
broadcastOnlyToObs = true;
|
||||
}
|
||||
}
|
||||
for (auto& [roomInfo, session] : m_observerPlayers)
|
||||
{
|
||||
if (roomInfo.uniqueId == uniqueId)
|
||||
{
|
||||
if (session->getAccountInfo().playerGrade < Common::Enums::GRADE_MOD) // >= MOD grade messages are broadcast to whole room, even outside observer
|
||||
{
|
||||
broadcastOnlyToObs = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (roomInfo.uniqueId == uniqueId) continue;
|
||||
if (session->isInMatch())
|
||||
{
|
||||
packet.setTcpHeader(session->getSessionId(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
|
|
@ -680,23 +627,22 @@ namespace Main
|
|||
// this is used by both (!) manual AND automatic host-changes
|
||||
bool Room::changeHost(std::size_t newHostIdx)
|
||||
{
|
||||
Utils::Logger& logger = Utils::Logger::getInstance();
|
||||
|
||||
if (newHostIdx >= m_players.size())
|
||||
{
|
||||
logger.log("The newHostIdx is not found inside m_players! (newHostIdx: " + std::to_string(newHostIdx) + ", m_players.size(): " + std::to_string(m_players.size()),
|
||||
Utils::LogType::Normal, "Room::changeHost");
|
||||
return false;
|
||||
}
|
||||
std::swap(m_players[0], m_players[newHostIdx]);
|
||||
m_playerSessionIdToVecIdx[m_players[0].second->getId()] = 0; // map the new host
|
||||
m_playerSessionIdToVecIdx[m_players[newHostIdx].second->getId()] = newHostIdx;
|
||||
return true;
|
||||
}
|
||||
|
||||
Main::Network::Session* Room::getPlayer(const Main::Structures::UniqueId& uniqueId)
|
||||
{
|
||||
for (auto& [roomInfo, session] : m_players)
|
||||
auto indexIter = m_playerSessionIdToVecIdx.find(uniqueId.session);
|
||||
if (indexIter != m_playerSessionIdToVecIdx.end())
|
||||
{
|
||||
if (roomInfo.uniqueId == uniqueId) return session;
|
||||
return m_players[indexIter->second].second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -717,69 +663,61 @@ namespace Main
|
|||
}
|
||||
|
||||
// Returns new team for this player, to notify the client. Nullopt for failure.
|
||||
std::optional<std::uint32_t> Room::changePlayerTeam(const Main::Structures::UniqueId& uniqueId, std::uint32_t newTeam)
|
||||
{
|
||||
Utils::Logger& logger = Utils::Logger::getInstance();
|
||||
|
||||
for (auto it = m_players.begin(); it != m_players.end(); ++it)
|
||||
std::optional<std::uint32_t> Room::changePlayerTeam(const Main::Structures::UniqueId& uniqueId, std::uint32_t newTeam) {
|
||||
auto playerIt = m_playerSessionIdToVecIdx.find(uniqueId.session);
|
||||
if (playerIt != m_playerSessionIdToVecIdx.end())
|
||||
{
|
||||
if (it->first.uniqueId == uniqueId)
|
||||
auto index = playerIt->second;
|
||||
if (newTeam == Common::Enums::TEAM_OBSERVER)
|
||||
{
|
||||
if (newTeam == Common::Enums::TEAM_OBSERVER)
|
||||
{
|
||||
if (m_observerPlayers.size() >= 10) return std::nullopt;
|
||||
auto playerInfo = std::move(*it);
|
||||
playerInfo.first.team = Common::Enums::TEAM_OBSERVER;
|
||||
m_observerPlayers.push_back(std::move(playerInfo));
|
||||
m_players.erase(it);
|
||||
if (m_observerPlayers.size() >= 10) return std::nullopt;
|
||||
auto playerInfo = std::move(m_players[index]);
|
||||
playerInfo.first.team = Common::Enums::TEAM_OBSERVER;
|
||||
m_observerPlayers.push_back(std::move(playerInfo));
|
||||
m_players.erase(m_players.begin() + index);
|
||||
m_playerSessionIdToVecIdx.erase(uniqueId.session);
|
||||
m_obsPlayerSessionIdToVecIdx[uniqueId.session] = m_observerPlayers.size() - 1;
|
||||
}
|
||||
else if (newTeam == Common::Enums::TEAM_ZOMBIE)
|
||||
{
|
||||
m_players[index].first.team = newTeam;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_players[index].first.team = m_players[index].first.team == Common::Enums::TEAM_BLUE ? Common::Enums::TEAM_RED : Common::Enums::TEAM_BLUE;
|
||||
}
|
||||
return newTeam;
|
||||
}
|
||||
|
||||
logger.log("The player " + playerInfo.second->getPlayerInfoAsString() + " changed team from Player to Observer",
|
||||
Utils::LogType::Normal, "Room::switchPlayerTeam");
|
||||
}
|
||||
else if (newTeam == Common::Enums::TEAM_ZOMBIE)
|
||||
auto observerIt = m_obsPlayerSessionIdToVecIdx.find(uniqueId.session);
|
||||
if (observerIt != m_obsPlayerSessionIdToVecIdx.end())
|
||||
{
|
||||
auto index = observerIt->second;
|
||||
if (newTeam == Common::Enums::TEAM_ALL || newTeam == Common::Enums::TEAM_RED || newTeam == Common::Enums::TEAM_BLUE)
|
||||
{
|
||||
if (m_players.size() >= m_settings.playersPerTeam * 2)
|
||||
{
|
||||
it->first.team = newTeam;
|
||||
return std::nullopt;
|
||||
}
|
||||
else
|
||||
else if (isModeTeamBased())
|
||||
{
|
||||
it->first.team = it->first.team == Common::Enums::TEAM_BLUE ? Common::Enums::TEAM_RED : Common::Enums::TEAM_BLUE;
|
||||
m_observerPlayers[index].first.team = calculateNewPlayerTeam();
|
||||
}
|
||||
logger.log("The player " + it->second->getPlayerInfoAsString() + " changed team to: " + std::to_string(it->first.team),
|
||||
Utils::LogType::Normal, "Room::switchPlayerTeam");
|
||||
|
||||
else
|
||||
{
|
||||
m_observerPlayers[index].first.team = Common::Enums::TEAM_ALL;
|
||||
}
|
||||
auto playerInfo = std::move(m_observerPlayers[index]);
|
||||
std::uint32_t newTeam = playerInfo.first.team;
|
||||
m_players.push_back(std::move(playerInfo));
|
||||
m_observerPlayers.erase(m_observerPlayers.begin() + index);
|
||||
m_obsPlayerSessionIdToVecIdx.erase(uniqueId.session);
|
||||
m_playerSessionIdToVecIdx[uniqueId.session] = m_players.size() - 1;
|
||||
return newTeam;
|
||||
}
|
||||
return std::nullopt; // Observer player cannot change to another team other than the first if...
|
||||
}
|
||||
for (auto it = m_observerPlayers.begin(); it != m_observerPlayers.end(); ++it)
|
||||
{
|
||||
if (it->first.uniqueId == uniqueId)
|
||||
{
|
||||
if (newTeam == Common::Enums::TEAM_ALL || newTeam == Common::Enums::TEAM_RED || newTeam == Common::Enums::TEAM_BLUE)
|
||||
{
|
||||
if (m_players.size() >= m_settings.playersPerTeam * 2)
|
||||
{
|
||||
logger.log("Could not switch from ObserverTeam => PlayerTeam because there are too many players in the room",
|
||||
Utils::LogType::Warning, "Room::switchPlayerTeam");
|
||||
return std::nullopt;
|
||||
}
|
||||
else if (isModeTeamBased())
|
||||
{
|
||||
it->first.team = calculateNewPlayerTeam();
|
||||
}
|
||||
else
|
||||
{
|
||||
it->first.team = Common::Enums::TEAM_ALL;
|
||||
}
|
||||
auto playerInfo = std::move(*it);
|
||||
std::uint32_t newTeam = playerInfo.first.team;
|
||||
m_players.push_back(std::move(playerInfo));
|
||||
m_observerPlayers.erase(it);
|
||||
|
||||
return newTeam;
|
||||
}
|
||||
return std::nullopt; // Makes no sense: observer player cannot change to another team other than the first if...
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool Room::isModeTeamBased() const
|
||||
|
|
@ -793,16 +731,10 @@ namespace Main
|
|||
// Called when non-team-based mode changed to team-based-mode, and thus all teams go from '0' to either '1' or '2'.
|
||||
void Room::updatePlayersTeamToTeamBased()
|
||||
{
|
||||
Utils::Logger& logger = Utils::Logger::getInstance();
|
||||
|
||||
for (std::size_t i = 0; auto& [roomPlayerInfo, session] : m_players)
|
||||
{
|
||||
roomPlayerInfo.team = (i % 2 == 0) ? Common::Enums::TEAM_BLUE : Common::Enums::TEAM_RED;
|
||||
++i;
|
||||
|
||||
logger.log(std::string(session->getAccountInfo().nickname) + " new team: " +
|
||||
(roomPlayerInfo.team == Common::Enums::TEAM_BLUE ? "TEAM_BLUE" : "TEAM_RED"),
|
||||
::Utils::LogType::Info, "Room::updatePlayersTeam");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -824,10 +756,6 @@ namespace Main
|
|||
if (playerInfo.team == Common::Enums::Team::TEAM_BLUE) ++totalBlueTeam;
|
||||
else if (playerInfo.team == Common::Enums::Team::TEAM_RED) ++totalRedTeam;
|
||||
}
|
||||
Utils::Logger& logger = Utils::Logger::getInstance();
|
||||
logger.log("Total BLUE team: " + std::to_string(totalBlueTeam) + ", Total RED team: " + std::to_string(totalRedTeam),
|
||||
Utils::LogType::Normal, "Room::calculateNewPlayerTeam");
|
||||
|
||||
if (totalRedTeam >= totalBlueTeam) return Common::Enums::TEAM_BLUE;
|
||||
return Common::Enums::TEAM_RED;
|
||||
}
|
||||
|
|
@ -854,43 +782,36 @@ namespace Main
|
|||
return static_cast<std::uint32_t>(m_players.size()) >= maxPossiblePlayers;
|
||||
}
|
||||
|
||||
void Room::setStateFor(const Main::Structures::UniqueId& uniqueId, const Common::Enums::PlayerState& playerState)
|
||||
void Room::setStateFor(const Main::Structures::UniqueId& uniqueId, const Common::Enums::PlayerState& playerState)
|
||||
{
|
||||
for (auto& [roomInfo, session] : ranges::views::concat(m_players, m_observerPlayers))
|
||||
auto playerIt = m_playerSessionIdToVecIdx.find(uniqueId.session);
|
||||
if (playerIt != m_playerSessionIdToVecIdx.end())
|
||||
{
|
||||
if (roomInfo.uniqueId == uniqueId)
|
||||
{
|
||||
roomInfo.state = playerState;
|
||||
session->setPlayerState(playerState);
|
||||
auto index = playerIt->second;
|
||||
m_players[index].first.state = playerState;
|
||||
m_players[index].second->setPlayerState(playerState);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
auto observerIt = m_obsPlayerSessionIdToVecIdx.find(uniqueId.session);
|
||||
if (observerIt != m_obsPlayerSessionIdToVecIdx.end())
|
||||
{
|
||||
auto index = observerIt->second;
|
||||
m_observerPlayers[index].first.state = playerState;
|
||||
m_observerPlayers[index].second->setPlayerState(playerState);
|
||||
}
|
||||
}
|
||||
|
||||
void Room::startMatch(const Main::Structures::UniqueId& uniqueId)
|
||||
{
|
||||
auto allPlayers = ranges::views::concat(m_players, m_observerPlayers);
|
||||
|
||||
if (m_hasMatchStarted)
|
||||
{
|
||||
for (auto& [roomInfo, session] : allPlayers)
|
||||
for (auto& [roomInfo, session] : ranges::views::concat(m_players, m_observerPlayers))
|
||||
{
|
||||
if (roomInfo.uniqueId == uniqueId)
|
||||
{
|
||||
roomInfo.state = 2;
|
||||
session->setIsInMatch(true);
|
||||
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(session->getId(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
|
||||
/*
|
||||
response.setOrder(312);
|
||||
response.setOption(2);
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&roomInfo.uniqueId), sizeof(uniqueId));
|
||||
session->asyncWrite(response);
|
||||
Main::Details::sendPlayerState(*session, uniqueId);
|
||||
setStateFor(uniqueId, static_cast<Common::Enums::PlayerState>(2));
|
||||
*/
|
||||
session->setIsInMatch(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -899,12 +820,12 @@ namespace Main
|
|||
{
|
||||
m_players[0].first.state = Common::Enums::STATE_PLAYING;
|
||||
m_players[0].second->setIsInMatch(true);
|
||||
|
||||
for (auto& [roomInfo, session] : allPlayers)
|
||||
for (auto& [roomInfo, session] : ranges::views::concat(m_players, m_observerPlayers))
|
||||
{
|
||||
if (roomInfo.state == Common::Enums::STATE_READY)
|
||||
{
|
||||
roomInfo.state = 2;
|
||||
Main::Details::sendPlayerState(*session, uniqueId);
|
||||
setStateFor(uniqueId, static_cast<Common::Enums::PlayerState>(2));
|
||||
session->setIsInMatch(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -992,7 +913,6 @@ namespace Main
|
|||
{
|
||||
m_settings.hasPassword = true;
|
||||
}
|
||||
std::cout << "Password set: " << newPassword << '\n';
|
||||
m_password = newPassword;
|
||||
}
|
||||
|
||||
|
|
@ -1009,13 +929,17 @@ namespace Main
|
|||
|
||||
void Room::sendTo(const Main::Structures::UniqueId& uniqueId, const Common::Network::Packet& packet)
|
||||
{
|
||||
for (auto& [roomInfo, session] : ranges::views::concat(m_players, m_observerPlayers))
|
||||
auto playerIter = m_playerSessionIdToVecIdx.find(uniqueId.session);
|
||||
if (playerIter != m_playerSessionIdToVecIdx.end())
|
||||
{
|
||||
if (roomInfo.uniqueId == uniqueId)
|
||||
{
|
||||
session->asyncWrite(packet);
|
||||
return;
|
||||
}
|
||||
m_players[playerIter->second].second->asyncWrite(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
auto observerIter = m_obsPlayerSessionIdToVecIdx.find(uniqueId.session);
|
||||
if (observerIter != m_obsPlayerSessionIdToVecIdx.end())
|
||||
{
|
||||
m_observerPlayers[observerIter->second].second->asyncWrite(packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1026,7 +950,6 @@ namespace Main
|
|||
{
|
||||
if (roomInfo.uniqueId == uniqueId)
|
||||
{
|
||||
std::cout << "storeEndMatchStatsFor: UniqueID found\n";
|
||||
Main::Enums::MatchEnd matchEnd;
|
||||
if (redScore == blueScore)
|
||||
{
|
||||
|
|
@ -1049,12 +972,16 @@ namespace Main
|
|||
|
||||
Main::Network::Session::AccountInfo Room::getAccountInfoFor(const Main::Structures::UniqueId& uniqueId) const
|
||||
{
|
||||
for (auto& [roomInfo, session] : ranges::views::concat(m_players, m_observerPlayers))
|
||||
auto playerIter = m_playerSessionIdToVecIdx.find(uniqueId.session);
|
||||
if (playerIter != m_playerSessionIdToVecIdx.end())
|
||||
{
|
||||
if (roomInfo.uniqueId == uniqueId)
|
||||
{
|
||||
return session->getAccountInfo();
|
||||
}
|
||||
return m_players[playerIter->second].second->getAccountInfo();
|
||||
}
|
||||
|
||||
auto observerIter = m_obsPlayerSessionIdToVecIdx.find(uniqueId.session);
|
||||
if (observerIter != m_obsPlayerSessionIdToVecIdx.end())
|
||||
{
|
||||
return m_observerPlayers[observerIter->second].second->getAccountInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,13 +13,12 @@ namespace Main
|
|||
m_roomByNumber.emplace(room.getRoomNumber(), room);
|
||||
}
|
||||
|
||||
void RoomsManager::removeRoom(std::uint16_t roomNum)
|
||||
void RoomsManager::removeRoom(std::uint16_t roomNum)
|
||||
{
|
||||
if (m_roomByNumber.contains(roomNum))
|
||||
{
|
||||
m_roomByNumber[roomNum].removeAllPlayers();
|
||||
m_roomByNumber.erase(roomNum);
|
||||
}
|
||||
auto it = m_roomByNumber.find(roomNum);
|
||||
if (it == m_roomByNumber.end()) return;
|
||||
it->second.removeAllPlayers();
|
||||
m_roomByNumber.erase(it);
|
||||
}
|
||||
|
||||
std::size_t RoomsManager::getTotalRooms() const
|
||||
|
|
@ -30,6 +29,7 @@ namespace Main
|
|||
std::vector<Main::Structures::SingleRoom> RoomsManager::getRoomsList() const
|
||||
{
|
||||
std::vector<Main::Structures::SingleRoom> roomsList;
|
||||
roomsList.reserve(m_roomByNumber.size());
|
||||
for (const auto& [roomNumber, room] : m_roomByNumber)
|
||||
{
|
||||
roomsList.push_back(room.getRoomInfo());
|
||||
|
|
@ -37,41 +37,43 @@ namespace Main
|
|||
return roomsList;
|
||||
}
|
||||
|
||||
std::optional<std::reference_wrapper<Main::Classes::Room>> RoomsManager::getRoomByNumber(std::uint16_t roomNumber)
|
||||
Main::Classes::Room* RoomsManager::getRoomByNumber(std::uint16_t roomNumber)
|
||||
{
|
||||
if (m_roomByNumber.contains(roomNumber))
|
||||
auto it = m_roomByNumber.find(roomNumber);
|
||||
if (it != m_roomByNumber.end())
|
||||
{
|
||||
return std::ref(m_roomByNumber[roomNumber]);
|
||||
return &it->second;
|
||||
}
|
||||
return std::nullopt;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void RoomsManager::broadcastToRoom(std::uint16_t roomNumber, Common::Network::Packet& packet)
|
||||
{
|
||||
if (!m_roomByNumber.contains(roomNumber)) return;
|
||||
auto& room = m_roomByNumber[roomNumber];
|
||||
room.broadcastToRoom(packet);
|
||||
auto it = m_roomByNumber.find(roomNumber);
|
||||
if (it == m_roomByNumber.end()) return;
|
||||
it->second.broadcastToRoom(packet);
|
||||
}
|
||||
|
||||
void RoomsManager::broadcastToRoomExceptSelf(std::uint16_t roomNumber, const Main::Structures::UniqueId& selfUniqueId, Common::Network::Packet& packet)
|
||||
{
|
||||
if (!m_roomByNumber.contains(roomNumber)) return;
|
||||
auto& room = m_roomByNumber[roomNumber];
|
||||
room.broadcastToRoomExceptSelf(packet, selfUniqueId);
|
||||
auto it = m_roomByNumber.find(roomNumber);
|
||||
if (it == m_roomByNumber.end()) return;
|
||||
it->second.broadcastToRoomExceptSelf(packet, selfUniqueId);
|
||||
}
|
||||
|
||||
void RoomsManager::broadcastToMatchExceptSelf(std::uint16_t roomNumber, const Main::Structures::UniqueId& selfUniqueId, Common::Network::Packet& packet, std::uint32_t extra)
|
||||
{
|
||||
if (!m_roomByNumber.contains(roomNumber)) return;
|
||||
auto& room = m_roomByNumber[roomNumber];
|
||||
room.broadcastToMatchExceptSelf(packet, selfUniqueId, extra);
|
||||
auto it = m_roomByNumber.find(roomNumber);
|
||||
if (it == m_roomByNumber.end()) return;
|
||||
it->second.broadcastToMatchExceptSelf(packet, selfUniqueId, extra);
|
||||
}
|
||||
|
||||
void RoomsManager::broadcastOutsideMatchExceptSelf(std::uint16_t roomNumber, const Main::Structures::UniqueId& selfUniqueId, Common::Network::Packet& packet, std::uint32_t extra)
|
||||
{
|
||||
if (!m_roomByNumber.contains(roomNumber)) return;
|
||||
auto& room = m_roomByNumber[roomNumber];
|
||||
room.broadcastOutsideMatchExceptSelf(packet, selfUniqueId, extra);
|
||||
auto it = m_roomByNumber.find(roomNumber);
|
||||
if (it == m_roomByNumber.end()) return;
|
||||
it->second.broadcastOutsideMatchExceptSelf(packet, selfUniqueId, extra);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,15 +67,16 @@ namespace Main
|
|||
|
||||
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(52, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handlePlayerBlock(request, session, m_sessionsManager, m_database); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(53, Main::Handlers::handlePlayerUnblock);
|
||||
Main::Network::Session& session) { Main::Handlers::handlePlayerBlock(request, session, m_sessionsManager, m_database, Details::parseData<std::array<char, 16>>(request)); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(53, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handlePlayerUnblock(request, session, Details::parseData<std::uint32_t>(request)); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(54, Main::Handlers::handleBlockedPlayerList);
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(57, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleLobbyClanList(request, session, m_sessionsManager); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(61, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleGeneralFriendRequests(request, session, m_sessionsManager, m_database); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(62, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleFriendDeletion(request, session, m_sessionsManager); });
|
||||
Main::Network::Session& session) { Main::Handlers::handleFriendDeletion(request, session, m_sessionsManager, Details::parseData<std::uint32_t>(request)); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(63, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleFriendList(request, session, m_sessionsManager, m_database); });
|
||||
|
||||
|
|
@ -85,28 +86,34 @@ namespace Main
|
|||
Common::Network::Session::addCallback<Main::Network::Session>(68, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleInitialPlayerInfos(request, session, m_sessionsManager, m_database, m_timeSinceLastRestart, m_serverId); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(71, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handlePing(request, session, m_roomsManager, parseData<Main::ClientData::Ping>(request)); });
|
||||
Main::Network::Session& session) { Main::Handlers::handlePing(request, session, m_roomsManager, Details::parseData<Main::ClientData::Ping>(request)); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(74, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleCharacterSelection(request, session, m_roomsManager); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(84, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleLobbyUserList(request, session, m_sessionsManager); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(85, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleLobbyAccountInfo(request, session, m_sessionsManager, m_serverId); });
|
||||
Main::Network::Session& session) { Main::Handlers::handleLobbyAccountInfo(request, session, m_sessionsManager, m_serverId,
|
||||
Details::parseData<Main::Structures::UniqueId>(request)); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(86, Main::Handlers::handleBoughtItem);
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(87, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleEquippedItemSwitch(request, session, m_roomsManager); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(88, Main::Handlers::handleItemDelete);
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(88, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleItemDelete(request, session, Details::parseData<Main::Structures::ItemSerialInfo>(request)); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(89, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleBattery(request, session, m_roomsManager); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(96, Main::Handlers::handleItemRefund);
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(97, Main::Handlers::handleItemUpgrade);
|
||||
Main::Network::Session& session) { Main::Handlers::handleBattery(request, session, m_roomsManager, Details::parseData<Main::Structures::UniqueId>(request)); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(96, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleItemRefund(request, session, Details::parseData<Main::ClientData::ItemRefund>(request)); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(97, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleItemUpgrade(request, session, Details::parseData<Main::ClientData::ItemUpgrade>(request)); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(98, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleGeneralItem(request, session, m_database, m_boxes); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(99, Main::Handlers::handleMailboxDelete);
|
||||
Main::Network::Session& session) { Main::Handlers::handleGeneralItem(request, session, m_database, m_boxes, Details::parseData<Main::Structures::ItemSerialInfo>(request)); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(99, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleMailboxDelete(request, session, Details::parseData<std::uint32_t>(request, 4)); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(100, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleMailboxCommunication(request, session, m_sessionsManager, m_database); });
|
||||
Main::Network::Session& session) { Main::Handlers::handleMailboxCommunication(request, session, m_sessionsManager, m_database,
|
||||
Details::parseData<Main::ClientData::MailboxMessage>(request)); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(101, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleReadMailbox(request, session, m_database); });
|
||||
Main::Network::Session& session) { Main::Handlers::handleReadMailbox(request, session, m_database, Details::parseData<std::uint32_t>(request, 4)); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(102, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleMailboxDisplay(request, session, m_sessionsManager, m_database); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(103, [&](const Common::Network::Packet& request,
|
||||
|
|
@ -138,11 +145,12 @@ namespace Main
|
|||
Common::Network::Session::addCallback<Main::Network::Session>(131, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleSimpleRoomSetting<Main::Enums::SETTING_TIME>(request, session, m_roomsManager); }); // time
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(134, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleRoomCreation(request, session, m_roomsManager); });
|
||||
Main::Network::Session& session) { Main::Handlers::handleRoomCreation(request, session, m_roomsManager, Details::parseData<Main::Structures::CompleteRoomInfo>(request)); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(136, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleRoomJoin(request, session, m_roomsManager); });
|
||||
Main::Network::Session& session) { Main::Handlers::handleRoomJoin(request, session, m_roomsManager, Details::parseData<Main::ClientData::RoomInfo>(request)); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(137, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleRoomLeave(request, session, m_sessionsManager, m_roomsManager, m_serverId); });
|
||||
Main::Network::Session& session) { Main::Handlers::handleRoomLeave(request, session, m_sessionsManager, m_roomsManager, m_serverId,
|
||||
Details::parseData<Main::Structures::UniqueId>(request)); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(138, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleRoomsList(request, session, m_roomsManager); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(154, [&](const Common::Network::Packet& request,
|
||||
|
|
@ -153,6 +161,10 @@ namespace Main
|
|||
Main::Network::Session& session) { Main::Handlers::handleLobbyChatMessage(request, session, m_sessionsManager, m_chatCommands, m_roomsManager, m_database); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(157, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleRoomChatMessage(request, session, m_sessionsManager, m_chatCommands, m_roomsManager, m_database); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(256, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleMatchLeave(request, session, m_sessionsManager, m_roomsManager); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(259, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleEliminationNextRound(request, session, m_roomsManager); });
|
||||
|
||||
/*
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(202, [&](const Common::Network::Packet& request,
|
||||
|
|
@ -160,14 +172,8 @@ namespace Main
|
|||
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(232, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleMapEvents(request, session, m_database); });
|
||||
*/
|
||||
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(256, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleMatchLeave(request, session, m_sessionsManager, m_roomsManager); });
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(259, [&](const Common::Network::Packet& request,
|
||||
Main::Network::Session& session) { Main::Handlers::handleEliminationNextRound(request, session, m_roomsManager); });
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// These 2 following handlers must be fully implemented still. Also check whether they're related to Bomb Battle (for host side)!
|
||||
// Also requires to be refactored
|
||||
Common::Network::Session::addCallback<Main::Network::Session>(156, [&](const Common::Network::Packet& request,
|
||||
|
|
|
|||
|
|
@ -309,13 +309,6 @@ namespace Main
|
|||
m_player.getAccountID(), mp, Main::Enums::ItemCurrencyType::ITEM_MP);
|
||||
}
|
||||
|
||||
void Session::setAccountCoins(std::uint16_t coins)
|
||||
{
|
||||
m_player.setAccountCoins(coins);
|
||||
m_scheduler.addCallback(m_player.getAccountID(), 3, &Main::Persistence::PersistentDatabase::updatePlayerCurrencyByType,
|
||||
m_player.getAccountID(), coins, Main::Enums::ItemCurrencyType::ITEM_COIN);
|
||||
}
|
||||
|
||||
void Session::setAccountLatestCharacterSelected(std::uint16_t latestCharacterSelected)
|
||||
{
|
||||
m_player.setAccountLatestCharacterSelected(latestCharacterSelected);
|
||||
|
|
@ -344,7 +337,6 @@ namespace Main
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Session::addFriend(const Main::Structures::Friend& ffriend)
|
||||
{
|
||||
m_player.addOfflineFriend(ffriend);
|
||||
|
|
@ -401,7 +393,6 @@ namespace Main
|
|||
m_scheduler.addRepetitiveCallback(m_player.getAccountID(), &Main::Persistence::PersistentDatabase::removePlayerItem,
|
||||
m_player.getAccountID(), static_cast<std::uint32_t>(itemSerialInfoToDelete.itemNumber));
|
||||
}
|
||||
std::cout << "Was removed? " << std::boolalpha << removed << '\n';
|
||||
response.setExtra(removed ? 1 : 0);
|
||||
asyncWrite(response);
|
||||
return removed;
|
||||
|
|
@ -421,7 +412,6 @@ namespace Main
|
|||
Message message{ accountInfo.rockTotens, accountInfo.microPoints + mpToAdd };
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&message), sizeof(message));
|
||||
asyncWrite(response);
|
||||
|
||||
setAccountMicroPoints(accountInfo.microPoints + mpToAdd);
|
||||
}
|
||||
|
||||
|
|
@ -447,17 +437,11 @@ namespace Main
|
|||
return m_player.getEquippedItemsSeparated();
|
||||
}
|
||||
|
||||
void Session::setIsInLobby(bool val)
|
||||
{
|
||||
m_player.setIsInLobby(val);
|
||||
}
|
||||
|
||||
bool Session::isInLobby() const
|
||||
{
|
||||
return m_player.isInLobby();
|
||||
}
|
||||
|
||||
|
||||
void Session::switchItemEquip(std::uint32_t characterId, std::uint64_t itemNumber)
|
||||
{
|
||||
if (!m_player.unequipItemIfEquipped(itemNumber, characterId, m_scheduler))
|
||||
|
|
@ -570,10 +554,6 @@ namespace Main
|
|||
|
||||
void Session::setRoomNumber(std::uint16_t roomNumber)
|
||||
{
|
||||
if (roomNumber)
|
||||
{
|
||||
m_player.setIsInLobby(false);
|
||||
}
|
||||
m_player.setRoomNumber(roomNumber);
|
||||
}
|
||||
|
||||
|
|
@ -594,7 +574,6 @@ namespace Main
|
|||
|
||||
void Session::setIsInMatch(bool val)
|
||||
{
|
||||
std::cout << "Set Is In Match set to: " << val << '\n';
|
||||
m_player.setIsInMatch(val);
|
||||
}
|
||||
|
||||
|
|
@ -610,7 +589,7 @@ namespace Main
|
|||
|
||||
void Session::sendBattery(std::uint32_t battery)
|
||||
{
|
||||
// currently does not work:
|
||||
// todo: recheck whether this works
|
||||
Common::Network::Packet response;
|
||||
response.setTcpHeader(getId(), Common::Enums::USER_LARGE_ENCRYPTION);
|
||||
response.setOrder(89);
|
||||
|
|
@ -638,7 +617,6 @@ namespace Main
|
|||
previousAccountInfo.totalKills += stats.totalKills;
|
||||
previousAccountInfo.deaths += stats.deaths;
|
||||
previousAccountInfo.headshots += stats.headshots;
|
||||
//previousAccountInfo.assists += stats.assists;
|
||||
previousAccountInfo.experience = stats.newTotalEXP;
|
||||
previousAccountInfo.microPoints = stats.newTotalMP;
|
||||
if (matchEnd == Main::Enums::MATCH_WON) previousAccountInfo.wins += 1;
|
||||
|
|
|
|||
|
|
@ -28,22 +28,18 @@ namespace Main
|
|||
targetFriendSession.second->updateFriendSession(m_sessionsBySessionId[sessionId], true);
|
||||
}
|
||||
// Reset room state
|
||||
if (m_sessionsBySessionId[sessionId]->getRoomNumber())
|
||||
if (Main::Classes::Room* room = roomsManager->getRoomByNumber(m_sessionsBySessionId[sessionId]->getRoomNumber()))
|
||||
{
|
||||
auto roomOpt = roomsManager->getRoomByNumber(m_sessionsBySessionId[sessionId]->getRoomNumber());
|
||||
if (roomOpt == std::nullopt) return;
|
||||
auto& room = roomOpt.value().get();
|
||||
|
||||
if (m_sessionsBySessionId[sessionId]->isInMatch())
|
||||
{
|
||||
// if host, remove host from both match + room. removeHostFromMatch does that.
|
||||
if (room.isHost(m_sessionsBySessionId[sessionId]->getAccountInfo().uniqueId))
|
||||
if (room->isHost(m_sessionsBySessionId[sessionId]->getAccountInfo().uniqueId))
|
||||
{
|
||||
// This will also remove the host from the Room + notify the room that the host left the room
|
||||
bool roomMustBeClosed = room.removeHostFromMatch(); // Also notifies cast whether the room must be broken
|
||||
bool roomMustBeClosed = room->removeHostFromMatch(); // Also notifies cast whether the room must be broken
|
||||
if (roomMustBeClosed)
|
||||
{
|
||||
roomsManager->removeRoom(room.getRoomNumber());
|
||||
roomsManager->removeRoom(room->getRoomNumber());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -56,19 +52,19 @@ namespace Main
|
|||
response.setExtra(0);
|
||||
auto uniqueId = m_sessionsBySessionId[sessionId]->getAccountInfo().uniqueId;
|
||||
response.setData(reinterpret_cast<std::uint8_t*>(&uniqueId), sizeof(uniqueId));
|
||||
room.broadcastToRoom(response);
|
||||
room->broadcastToRoom(response);
|
||||
m_sessionsBySessionId[sessionId]->setIsInMatch(false);
|
||||
|
||||
room.removePlayer(m_sessionsBySessionId[sessionId], 1);
|
||||
room->removePlayer(m_sessionsBySessionId[sessionId], 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool roomMustBeClosed = room.removePlayer(m_sessionsBySessionId[sessionId], 1); // 1 = extra = leave room normally
|
||||
bool roomMustBeClosed = room->removePlayer(m_sessionsBySessionId[sessionId], 1); // 1 = extra = leave room normally
|
||||
// nb. removePlayer does NOT notify cast that the room must be removed.
|
||||
if (roomMustBeClosed)
|
||||
{
|
||||
roomsManager->removeRoom(room.getRoomNumber());
|
||||
roomsManager->removeRoom(room->getRoomNumber());
|
||||
}
|
||||
}
|
||||
m_sessionsBySessionId[sessionId]->leaveRoom();
|
||||
|
|
@ -82,8 +78,6 @@ namespace Main
|
|||
{
|
||||
m_sessionsVector.erase(it);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue