diff --git a/.gitignore b/.gitignore
index 2e3d0fbf..c579ae3c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -415,4 +415,11 @@ Common/x64/
ExternalLibraries/vcpkg/
MainServer/x64/
MainServer/Release/
-Microvolts-Emulator-V2/
\ No newline at end of file
+Microvolts-Emulator-V2/
+
+ExternalLibraries/CommonLib/Common.lib
+E x t e r n a l L i b r a r i e s / C o m m o n . l i b
+
+ E x t e r n a l L i b r a r i e s / C o m m o n . l i b
+
+
\ No newline at end of file
diff --git a/AuthServer/AuthServer.vcxproj b/AuthServer/AuthServer.vcxproj
deleted file mode 100644
index f01aff20..00000000
--- a/AuthServer/AuthServer.vcxproj
+++ /dev/null
@@ -1,181 +0,0 @@
-
-
-
-
- Debug
- Win32
-
-
- Release
- Win32
-
-
- Debug
- x64
-
-
- Release
- x64
-
-
-
- 16.0
- Win32Proj
- {9b06c7ac-41f2-459f-b8de-1404c0ddd262}
- AuthServer
- 10.0
-
-
-
- Application
- true
- v143
- Unicode
-
-
- Application
- false
- v143
- true
- Unicode
-
-
- Application
- true
- v143
- Unicode
-
-
- Application
- false
- v143
- true
- Unicode
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- $(SolutionDir)$(Platform)\
-
-
- ..\ExternalLibraries\vcpkg\installed
-
-
- ..\ExternalLibraries\vcpkg\vcpkg_installed
-
-
- ..\ExternalLibraries\vcpkg\vcpkg_installed
-
-
-
- Level3
- true
- WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
- true
- stdcpp20
- ..\Common\include; ..\ExternalLibraries\asio-1.24.0\include; ..\ExternalLibraries
- stdc17
-
-
- Console
- true
- ..\ExternalLibraries\CommonLib\Common.lib
-
-
-
-
-
-
-
-
- Level3
- true
- true
- true
- WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
- true
- stdcpp20
-
-
- Console
- true
- true
- true
-
-
- xcopy "$(SolutionDir)SharedFiles\GameDatabase.db" "$(TargetDir)"
-
-
-
-
- Level3
- true
- _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
- true
- stdcpp20
- ..\Common\include; ..\ExternalLibraries\asio-1.24.0\include; ..\ExternalLibraries
-
-
- Console
- true
- ..\ExternalLibraries\CommonLib\Common.lib
-
-
-
-
- Level3
- true
- true
- true
- NDEBUG;_CONSOLE;%(PreprocessorDefinitions); _CRT_SECURE_NO_WARNINGS
- true
- ..\Common\include; ..\ExternalLibraries\asio-1.24.0\include; ..\ExternalLibraries;
- stdcpp20
-
-
- Console
- true
- true
- true
- ..\ExternalLibraries\CommonLib\Common.lib
- ..\ExternalLibraries\vcpkg\vcpkg_installed\x64-windows\lib
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/AuthServer/AuthServer.vcxproj.filters b/AuthServer/AuthServer.vcxproj.filters
deleted file mode 100644
index 0a92089e..00000000
--- a/AuthServer/AuthServer.vcxproj.filters
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
-
- {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
- cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
-
-
- {93995380-89BD-4b04-88EB-625FBE52EBFB}
- h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
-
-
- {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
- rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
-
-
-
-
- File di origine
-
-
- File di origine
-
-
- File di origine
-
-
- File di origine
-
-
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
-
\ No newline at end of file
diff --git a/AuthServer/AuthServerMain.cpp b/AuthServer/AuthServerMain.cpp
index 143841ac..bc9fcdfa 100644
--- a/AuthServer/AuthServerMain.cpp
+++ b/AuthServer/AuthServerMain.cpp
@@ -1,26 +1,46 @@
-#include
+#include "Utils/Logger.h"
#include
#include
#include
-#include "include/AuthServer.h"
+#include "../include/AuthServer.h"
+
+#include
+#include
+#include "Utils/Utils.h"
-void printInitialInformation()
+int main()
{
+ Common::Utils::setConsoleTitle(L"Microvolts Auth Server");
+
auto const time = std::chrono::current_zone()->to_local(std::chrono::system_clock::now());
auto const time_s = std::format("{:%Y-%m-%d %X}", time);
- std::cout << "Auth server initialized on " << time_s << "\n\n";
-}
+ Utils::Logger::log("Auth server initialized on " + time_s, Utils::LogType::Info, "AuthServer");
+ auto parsedServerInfo = Common::Utils::SetupParser::getInstance().getAuthSetup();
-int main()
-{
-#ifdef WIN32
- SetConsoleTitleW(L"Microvolts Auth Server");
-#endif
- asio::io_context io_context;
- Auth::AuthServer srv(io_context, 13001);
+ Utils::Logger::log(std::format("Server Information: IP: {}, Port: {}",
+ parsedServerInfo.ip, parsedServerInfo.port), Utils::LogType::Normal);
- printInitialInformation();
+ const std::string banner = R"(
+ _____ __ __ ____ _ ______ _ _
+ / ____| \ \ / / | _ \ (_) | ____| | | | |
+ | (___ __\ \ /\ / /__| |_) | ___ __ _ _ _ __ | |__ _ __ ___ _ _| | __ _| |_ ___ _ __
+ \___ \ / _ \ \/ \/ / _ \ _ < / _ \/ _` | | '_ \ | __| | '_ ` _ \| | | | |/ _` | __/ _ \| '__|
+ ____) | (_) \ /\ / __/ |_) | __/ (_| | | | | | | |____| | | | | | |_| | | (_| | || (_) | |
+ |_____/ \___/ \/ \/ \___|____/ \___|\__, |_|_| |_| |______|_| |_| |_|\__,_|_|\__,_|\__\___/|_|
+ __/ |
+ |___/
+
+ GitHub: https://github.com/SoWeBegin/MicrovoltsEmulator
+
+)";
+
+ Utils::Logger::log(banner, Utils::LogType::Info);
+
+
+
+ asio::io_context io_context;
+ Auth::AuthServer srv(io_context, parsedServerInfo.ip, parsedServerInfo.port);
srv.asyncAccept();
io_context.run();
-}
\ No newline at end of file
+}
diff --git a/AuthServer/CMakeLists.txt b/AuthServer/CMakeLists.txt
new file mode 100644
index 00000000..b53303d8
--- /dev/null
+++ b/AuthServer/CMakeLists.txt
@@ -0,0 +1,27 @@
+project(AuthServer LANGUAGES CXX)
+
+
+file(GLOB_RECURSE AUTH_SOURCES CONFIGURE_DEPENDS
+ ${CMAKE_CURRENT_LIST_DIR}/*.cpp
+)
+
+add_executable(AuthServer
+ ${AUTH_SOURCES}
+)
+
+target_include_directories(AuthServer PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
+
+target_link_libraries(AuthServer PUBLIC
+ Common
+ unofficial::mariadb-connector-cpp::mariadbcpp
+)
+
+if (WIN32)
+ target_link_libraries(AuthServer PUBLIC wsock32 ws2_32)
+endif()
+
+
+set_target_properties(AuthServer PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}
+)
+
diff --git a/AuthServer/include/Structures/AuthAccountInfo.h b/AuthServer/include/Structures/AuthAccountInfo.h
index 6ee1c6ca..1e103922 100644
--- a/AuthServer/include/Structures/AuthAccountInfo.h
+++ b/AuthServer/include/Structures/AuthAccountInfo.h
@@ -2,12 +2,13 @@
#define AUTH_ACCOUNTINFO_H
#include
+#include "Macros.h"
namespace Auth
{
namespace Structures
{
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct BasicAccountInfo
{
std::uint32_t accountId{};
@@ -29,7 +30,7 @@ namespace Auth
// commandHeader.option = player grade
// commandHeader.extra = login type
};
-#pragma pack(pop)
+PACK_POP()
}
}
diff --git a/AuthServer/include/Structures/AuthChannels.h b/AuthServer/include/Structures/AuthChannels.h
index 9917ac64..811d1788 100644
--- a/AuthServer/include/Structures/AuthChannels.h
+++ b/AuthServer/include/Structures/AuthChannels.h
@@ -8,8 +8,8 @@ namespace Auth
{
namespace Structures
{
-#pragma pack(push, 1)
- struct ChannelsInfo
+PACK_PUSH(1)
+struct ChannelsInfo
{
std::vector channels{};
@@ -22,7 +22,7 @@ namespace Auth
}
}
};
-#pragma pack(pop)
+PACK_POP()
}
}
diff --git a/AuthServer/src/DbPlayerInfo.cpp b/AuthServer/src/DbPlayerInfo.cpp
index 1ce79d41..3ad0b42c 100644
--- a/AuthServer/src/DbPlayerInfo.cpp
+++ b/AuthServer/src/DbPlayerInfo.cpp
@@ -141,8 +141,10 @@ namespace Auth
playerInfo.setExtra(Auth::Enums::Login::SUCCESS);
playerInfoStructure.accountId = static_cast(res->getInt("AccountID"));
- strcpy_s(playerInfoStructure.playerName, res->getString("Nickname").c_str());
- strcpy_s(playerInfoStructure.clanName, res->getString("Clanname").c_str());
+ std::strncpy(playerInfoStructure.playerName, res->getString("Nickname").c_str(), sizeof(playerInfoStructure.playerName) - 1);
+ playerInfoStructure.playerName[sizeof(playerInfoStructure.playerName) - 1] = '\0';
+ std::strncpy(playerInfoStructure.clanName, res->getString("Clanname").c_str(), sizeof(playerInfoStructure.clanName) - 1);
+ playerInfoStructure.clanName[sizeof(playerInfoStructure.clanName) - 1] = '\0';
playerInfo.setOption(static_cast(res->getInt("Grade")));
playerInfoStructure.level = static_cast(res->getInt("Level")) + 1;
@@ -231,8 +233,14 @@ namespace Auth
updateStmt->setString(1, username);
updateStmt->executeUpdate();
- if (nonHashedPassword != std::to_string(auth::generateToken(secret)))
- {
+ auto generatedToken = auth::generateToken(secret);
+
+ std::ostringstream tokenStream;
+ tokenStream << std::setw(6) << std::setfill('0') << generatedToken;
+ auto tokenString = tokenStream.str();
+
+ if (nonHashedPassword != tokenString)
+ {
playerInfo.setExtra(Auth::Enums::Login::INCORRECT);
return std::pair{ playerInfo, Auth::Structures::BasicAccountInfo{} };
}
diff --git a/AuthServer/src/main.cpp b/AuthServer/src/main.cpp
deleted file mode 100644
index e49e113a..00000000
--- a/AuthServer/src/main.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "Utils/Logger.h"
-#include
-#include
-#include
-#include "../include/AuthServer.h"
-
-#include
-#include
-
-
-int main()
-{
- SetConsoleTitleW(L"Microvolts Auth Server");
-
- auto const time = std::chrono::current_zone()->to_local(std::chrono::system_clock::now());
- auto const time_s = std::format("{:%Y-%m-%d %X}", time);
- Utils::Logger::log("Auth server initialized on " + time_s, Utils::LogType::Info, "AuthServer");
-
- auto parsedServerInfo = Common::Utils::SetupParser::getInstance().getAuthSetup();
- Utils::Logger::log(std::format("Server Information: IP: {}, Port: {}",
- parsedServerInfo.ip, parsedServerInfo.port), Utils::LogType::Normal);
-
- asio::io_context io_context;
- Auth::AuthServer srv(io_context, parsedServerInfo.ip, parsedServerInfo.port);
- srv.asyncAccept();
- io_context.run();
-}
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 00000000..3cf1f5a1
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,34 @@
+
+cmake_minimum_required(VERSION 3.26)
+project(Microvolts-Emulator-V2 LANGUAGES C CXX ASM)
+
+set(CMAKE_CXX_STANDARD 23)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+set(Boost_NO_BOOST_CMAKE ON)
+set(Boost_NO_BOOST_VERSION_CHECK ON)
+
+if (WIN32)
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
+else()
+ set(CMAKE_EXECUTABLE_SUFFIX ".elf")
+ set(CMAKE_EXE_LINKER_FLAGS
+ "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-multiple-definition -Wl,-rpath=. -Wl,-rpath=/data/data/com.termux/files/usr/lib -Wl,--enable-new-dtags"
+ )
+
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/Output)
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/Output)
+ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/Output)
+endif()
+
+find_package(Boost REQUIRED COMPONENTS system json beast asio)
+find_package(OpenSSL REQUIRED)
+find_package(cryptopp CONFIG REQUIRED)
+find_package(range-v3 CONFIG REQUIRED)
+find_package(unofficial-mariadb-connector-cpp CONFIG REQUIRED)
+
+include_directories(PUBLIC ${CMAKE_SOURCE_DIR}/ExternalLibraries)
+add_subdirectory(Common)
+add_subdirectory(AuthServer)
+add_subdirectory(CastServer)
+add_subdirectory(MainServer)
diff --git a/CastServer/CMakeLists.txt b/CastServer/CMakeLists.txt
new file mode 100644
index 00000000..63507a84
--- /dev/null
+++ b/CastServer/CMakeLists.txt
@@ -0,0 +1,33 @@
+project(CastServer LANGUAGES CXX)
+
+
+file(GLOB_RECURSE CAST_SOURCES CONFIGURE_DEPENDS
+ ${CMAKE_CURRENT_LIST_DIR}/*.cpp
+)
+
+add_executable(CastServer
+ ${CAST_SOURCES}
+)
+
+
+target_include_directories(CastServer PUBLIC
+ ${CMAKE_CURRENT_LIST_DIR}/include
+)
+
+find_package(directxmath CONFIG REQUIRED)
+
+target_link_libraries(CastServer
+ PUBLIC
+ Common
+ Boost::system
+)
+
+
+if (WIN32)
+ target_link_libraries(CastServer PUBLIC wsock32 ws2_32)
+endif()
+
+set_target_properties(CastServer PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}
+)
+
diff --git a/CastServer/CastServer.vcxproj b/CastServer/CastServer.vcxproj
deleted file mode 100644
index 12826dac..00000000
--- a/CastServer/CastServer.vcxproj
+++ /dev/null
@@ -1,191 +0,0 @@
-
-
-
-
- Debug
- Win32
-
-
- Release
- Win32
-
-
- Debug
- x64
-
-
- Release
- x64
-
-
-
- 16.0
- Win32Proj
- {8e0e7ff9-66ac-4f7d-9ee6-a67db4e27b24}
- CastServer
- 10.0
-
-
-
- Application
- true
- v143
- Unicode
-
-
- Application
- false
- ClangCL
- true
- Unicode
-
-
- Application
- true
- v143
- Unicode
-
-
- Application
- false
- v143
- true
- Unicode
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- $(SolutionDir)$(Platform)\
-
-
- ..\ExternalLibraries\vcpkg\installed
-
-
- ..\ExternalLibraries\vcpkg\vcpkg_installed
-
-
- ..\ExternalLibraries\vcpkg\vcpkg_installed
-
-
- ..\ExternalLibraries\vcpkg\vcpkg_installed
-
-
-
- Level3
- true
- WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
- true
- ..\Common\include; ..\ExternalLibraries\asio-1.24.0\include;
- stdcpp20
-
-
- Console
- true
- ..\ExternalLibraries\CommonLib\Common.lib
-
-
-
-
- Level3
- true
- true
- true
- WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
- true
- stdcpplatest
- stdc17
- Speed
- ..\Common\include; ..\ExternalLibraries\asio-1.24.0\include; ..\ExternalLibraries
-
-
- Console
- true
- true
- true
- ..\ExternalLibraries\CommonLib\Common.lib
-
-
-
-
- Level3
- true
- _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
- true
- ..\Common\include; ..\ExternalLibraries\asio-1.24.0\include; ..\ExternalLibraries
- stdcpplatest
-
-
- Console
- true
- ..\ExternalLibraries\CommonLib\Common.lib
-
-
-
-
- Level3
- true
- true
- true
- NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS
- true
- ..\Common\include; ..\ExternalLibraries\asio-1.24.0\include; ..\ExternalLibraries; ..\ExternalLibraries\vcpkg\vcpkg_installed\x64-windows\include
- stdcpplatest
- MaxSpeed
- Speed
- AnySuitable
- -O2 %(AdditionalOptions)
- true
-
-
- Console
- false
- true
- true
- ..\ExternalLibraries\CommonLib\Common.lib
- ..\ExternalLibraries\vcpkg\vcpkg_installed\x64-windows\lib
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/CastServer/CastServer.vcxproj.filters b/CastServer/CastServer.vcxproj.filters
deleted file mode 100644
index e861b74e..00000000
--- a/CastServer/CastServer.vcxproj.filters
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
- {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
- cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
-
-
- {93995380-89BD-4b04-88EB-625FBE52EBFB}
- h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
-
-
- {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
- rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
-
-
-
-
- File di origine
-
-
- File di origine
-
-
- File di origine
-
-
- File di origine
-
-
- File di origine
-
-
- File di origine
-
-
- File di origine
-
-
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
-
\ No newline at end of file
diff --git a/CastServer/include/CastServer.h b/CastServer/include/CastServer.h
index 05c548fc..5ab4010d 100644
--- a/CastServer/include/CastServer.h
+++ b/CastServer/include/CastServer.h
@@ -24,6 +24,7 @@ namespace Cast
std::uint16_t m_serverId;
Cast::Network::SessionsManager m_sessionsManager{};
static inline Cast::Classes::RoomsManager m_roomsManager{};
+ std::shared_ptr m_positionTimer;
tcp::acceptor m_mainServerAcceptor;
std::optional m_mainSocket;
@@ -34,6 +35,7 @@ namespace Cast
CastServer(ioContext& io_context, const std::string& serverIp, std::uint16_t port, std::uint16_t mainPort, std::uint16_t serverId);
void asyncAccept();
void asyncAcceptMainServer();
+ void tickPositionFlush();
};
}
diff --git a/CastServer/include/Classes/Room.h b/CastServer/include/Classes/Room.h
index 330a067a..64b29bf2 100644
--- a/CastServer/include/Classes/Room.h
+++ b/CastServer/include/Classes/Room.h
@@ -27,9 +27,13 @@ namespace Cast
std::uint32_t m_roomNumber = -1;
std::uint32_t m_serverId{};
+ std::vector m_pendingPositions;
+
public:
bool m_hasMatchStarted{};
bool m_isInvisible{};
+ std::uint32_t m_roomTick{};
+
// Arena Mode
bool m_isArenaMode{};
@@ -92,6 +96,8 @@ namespace Cast
void broadcastToMatch(Common::Network::UnecryptedPacket& packet);
+ void broadcastToMatchExceptSelf(Common::Network::UnecryptedPacket& packet, std::uint32_t selfId);
+
void playerForwardToHost(std::uint64_t hostSessionId, std::uint64_t senderSessionId, Common::Network::UnecryptedPacket& packet);
void hostForwardToPlayer(std::uint64_t, std::uint64_t playerId, Common::Network::UnecryptedPacket& packet, bool useHostIdInTcpHeader = true);
@@ -122,6 +128,10 @@ namespace Cast
void shuffleCoordinates();
void respawnEveryoneArena();
+
+ void enqueuePosition(Common::Network::UnecryptedPacket&& pkt);
+
+ void flushPendingPositions();
};
}
}
diff --git a/CastServer/include/Classes/RoomsManager.h b/CastServer/include/Classes/RoomsManager.h
index c27575ae..044b2105 100644
--- a/CastServer/include/Classes/RoomsManager.h
+++ b/CastServer/include/Classes/RoomsManager.h
@@ -14,8 +14,14 @@ namespace Cast
{
private:
std::array, Common::Constants::maxSessionsPerServer + 1> m_playerSessionIdToRoom{};
+ std::vector> m_rooms{};
public:
+ const auto& getAllRooms() const
+ {
+ return m_rooms;
+ }
+
void addRoom(std::shared_ptr room, std::uint64_t playerId);
void switchRoomJoinOrExit(std::shared_ptr session, std::uint64_t hostSessionId = -1);
@@ -28,15 +34,19 @@ namespace Cast
void broadcastToMatch(std::uint64_t sessionId, Common::Network::UnecryptedPacket& packet);
+ void broadcastToMatchExceptSelf(std::uint64_t sessionId, Common::Network::UnecryptedPacket& packet);
+
void playerForwardToHost(std::uint64_t hostSessionId, std::uint64_t senderSessionId, Common::Network::UnecryptedPacket& packet);
+ void setRoomTick(std::uint64_t hostSessionId, std::uint64_t tick);
+
void hostForwardToPlayer(std::uint64_t hostSessionId, std::uint64_t receiverSessionId, Common::Network::UnecryptedPacket& packet, bool useHostSessionIdInTcpHeader = true);
void setMapFor(std::uint64_t playerId, std::uint32_t map);
void setModeFor(std::uint64_t playerId, std::uint32_t mode);
- void setRoomNumberFor(std::uint64_t playerId, std::uint32_t roomNum);
+ bool setRoomNumberFor(std::uint64_t playerId, std::uint32_t roomNum);
void endMatch(std::uint64_t hostId);
diff --git a/CastServer/include/Handlers/IpcMainHandlers.h b/CastServer/include/Handlers/IpcMainHandlers.h
index 33f45372..e70fe3f3 100644
--- a/CastServer/include/Handlers/IpcMainHandlers.h
+++ b/CastServer/include/Handlers/IpcMainHandlers.h
@@ -5,6 +5,7 @@
#include "Network/Session.h"
#include "../Classes/RoomsManager.h"
#include "../../../MainServer/include/Structures/ClientData/Structures.h"
+#include
namespace Cast
{
@@ -26,16 +27,13 @@ namespace Cast
if (!roomOpt) return;
auto& room = *roomOpt;
- if (auto s = sm.getSession(session->getId()))
+ if (auto s = sm.getSession(request.getSession()))
{
if (request.getExtra() == 0) s->m_isInvisible = false;
else if (request.getExtra() == 1) s->m_isInvisible = true;
}
- else
- {
- if (request.getExtra() == 2) room->m_isInvisible = true;
- else if (request.getExtra() == 3) room->m_isInvisible = false;
- }
+ if (request.getExtra() == 2) room->m_isInvisible = true;
+ else if (request.getExtra() == 3) room->m_isInvisible = false;
}
inline void handleAssassinMode(const Common::Network::UnecryptedPacket& request, std::shared_ptr session,
@@ -54,12 +52,12 @@ namespace Cast
session->asyncWrite(request);
}
- inline void handleRoomNumber(const Common::Network::UnecryptedPacket& request, std::shared_ptr session,
- Cast::Classes::RoomsManager& roomsManager)
- {
- roomsManager.setRoomNumberFor(request.getSession(), request.getExtra());
- session->asyncWrite(request);
- }
+ inline void handleRoomNumber(const Common::Network::UnecryptedPacket& request, std::shared_ptr session,
+ Cast::Classes::RoomsManager& roomsManager)
+ {
+ roomsManager.setRoomNumberFor(request.getSession(), request.getExtra());
+ session->asyncWrite(request);
+ }
inline void handleIpReq(const Common::Network::UnecryptedPacket& request, std::shared_ptr session)
{
@@ -106,4 +104,4 @@ namespace Cast
}
}
-#endif
\ No newline at end of file
+#endif
diff --git a/CastServer/include/Handlers/PlayerPositionHandler.h b/CastServer/include/Handlers/PlayerPositionHandler.h
index fd4d6077..f9e0c039 100644
--- a/CastServer/include/Handlers/PlayerPositionHandler.h
+++ b/CastServer/include/Handlers/PlayerPositionHandler.h
@@ -11,6 +11,7 @@
#include "AntiCheat/Event.h"
#include "../Utils/Utilities.h"
#include
+#include
namespace Cast
{
@@ -26,9 +27,15 @@ namespace Cast
if (!roomOpt) return;
auto& room = *roomOpt;
- // if (room->m_isInvisible || session->m_isInvisible) return;
Cast::Structures::ClientPlayerInfoBasic playerPositionFromClient = Cast::Details::parseData(request);
if (playerPositionFromClient.isBad()) return;
+ room->m_roomTick = playerPositionFromClient.matchTick;
+
+
+ if (room->m_isInvisible || session->m_isInvisible)
+ {
+ playerPositionFromClient.position.positionZ = 0;
+ }
if (room->m_isAssassinMode)
{
@@ -44,7 +51,7 @@ namespace Cast
}
else
{
- acManager.submitEvent(std::make_unique(session, 14, 1000, "Speed hack (Cheat Engine)", 281));
+ acManager.submitEvent(std::make_unique(session, 20, 1000, "Speed hack (Cheat Engine)", 281));
}
static Common::Network::UnecryptedPacket response{ 1440, 322, 1 };
@@ -52,20 +59,15 @@ namespace Cast
const auto fullSize = request.getFullSize();
- if (fullSize == 36)
+ if (fullSize == 36)
{
Cast::Structures::ClientPlayerInfoBullet playerPositionBullet{};
std::memcpy(&playerPositionBullet, request.getData(), sizeof(playerPositionBullet));
- if (playerPositionBullet.isBad())
- {
- ::Utils::Logger::log("Bad Player Respawn Position", ::Utils::LogType::Warning, "Cast::handlePlayerPosition");
- return;
- }
+ if (playerPositionBullet.isBad()) return;
PlayerInfoResponseWithBullets playerInfoResponseWithBullets;
playerInfoResponseWithBullets.specificInfo.enableBullet = true;
-
- playerInfoResponseWithBullets.tick = playerPositionFromClient.matchTick;
+ playerInfoResponseWithBullets.specificInfo.enableJump = false;
playerInfoResponseWithBullets.position = playerPositionFromClient.position;
playerInfoResponseWithBullets.direction = playerPositionFromClient.direction;
playerInfoResponseWithBullets.specificInfo.animation1 = playerPositionFromClient.animation1;
@@ -78,9 +80,8 @@ namespace Cast
playerInfoResponseWithBullets.currentWeapon = playerPositionBullet.bulletStruct.bullet4;
response.setData(reinterpret_cast(&playerInfoResponseWithBullets), sizeof(playerInfoResponseWithBullets));
-
}
- else if (fullSize == 40)
+ else if (fullSize == 40) // bullet+jump+movement+rotation (simplified)
{
Cast::Structures::ClientPlayerInfoComplete playerPositionComplete{};
std::memcpy(&playerPositionComplete, request.getData(), request.getDataSize());
@@ -92,8 +93,9 @@ namespace Cast
PlayerInfoResponseWithBullets playerInfoResponseWithBullets;
playerInfoResponseWithBullets.specificInfo.enableBullet = true;
+ playerInfoResponseWithBullets.specificInfo.enableJump = true;
- playerInfoResponseWithBullets.tick = playerPositionFromClient.matchTick;
+ // playerInfoResponseWithBullets.tick = playerPositionFromClient.matchTick;
playerInfoResponseWithBullets.position = playerPositionFromClient.position;
playerInfoResponseWithBullets.direction = playerPositionFromClient.direction;
playerInfoResponseWithBullets.specificInfo.animation1 = playerPositionFromClient.animation1;
@@ -104,9 +106,7 @@ namespace Cast
playerInfoResponseWithBullets.specificInfo.sessionId = static_cast(session->getId());
playerInfoResponseWithBullets.bullets = playerPositionBullet.bulletStruct;
playerInfoResponseWithBullets.currentWeapon = playerPositionBullet.bulletStruct.bullet4;
-
PlayerInfoResponseComplete playerInfoResponseComplete{ playerInfoResponseWithBullets };
- playerInfoResponseComplete.playerInfoBasicResponse.specificInfo.enableJump = true;
playerInfoResponseComplete.jump = playerPositionComplete.jumpStruct;
response.setData(reinterpret_cast(&playerInfoResponseComplete), sizeof(playerInfoResponseComplete));
@@ -114,7 +114,7 @@ namespace Cast
else
{
PlayerInfoBasicResponse playerInfoBasicResponse;
- playerInfoBasicResponse.tick = playerPositionFromClient.matchTick;
+ // playerInfoBasicResponse.tick = playerPositionFromClient.matchTick;
playerInfoBasicResponse.position = playerPositionFromClient.position;
playerInfoBasicResponse.direction = playerPositionFromClient.direction;
playerInfoBasicResponse.currentWeapon = playerPositionFromClient.weapon;
@@ -124,7 +124,8 @@ namespace Cast
playerInfoBasicResponse.rotation2 = request.getOption();
playerInfoBasicResponse.rotation3 = playerPositionFromClient.rotation;
playerInfoBasicResponse.specificInfo.sessionId = static_cast(session->getId());
-
+ playerInfoBasicResponse.specificInfo.enableJump = false;
+ playerInfoBasicResponse.specificInfo.enableBullet = false;
if (fullSize == 28)
{
@@ -134,7 +135,6 @@ namespace Cast
{
playerInfoBasicResponse.specificInfo.enableJump = true;
PlayerInfoResponseWithJump playerInfoResponseWithJump{ playerInfoBasicResponse };
-
Cast::Structures::ClientPlayerInfoJump playerPositionJump{};
std::memcpy(&playerPositionJump, request.getData(), request.getDataSize());
@@ -150,8 +150,7 @@ namespace Cast
}
}
- // reminder: this is correct, dont use exceptSelf as that causes log errors in SysLog (host receives [322] command not found)
- room->broadcastToRoom(response);
+ room->enqueuePosition(std::move(response));
}
}
}
diff --git a/CastServer/include/Handlers/SimpleHandlers.h b/CastServer/include/Handlers/SimpleHandlers.h
index e43ff0da..7dc172f5 100644
--- a/CastServer/include/Handlers/SimpleHandlers.h
+++ b/CastServer/include/Handlers/SimpleHandlers.h
@@ -12,6 +12,10 @@
#include "../Network/SessionsManager.h"
#include "../Structures/Rest.h"
#include
+#include "AntiCheat/AntiCheat.h"
+#include "AntiCheat/Event.h"
+#include
+#include
namespace Cast
{
@@ -208,7 +212,7 @@ namespace Cast
Cast::Network::SessionsManager& sessionsManager, std::uint32_t m_serverId)
{
Common::Network::UnecryptedPacket response;
- response.setTcpHeader(request.getSession());
+ response.setTcpHeader(session->getId());
response.setCommand(72, 1, 0, request.getOption());
session->asyncWrite(response);
@@ -303,7 +307,8 @@ namespace Cast
inline void handlePlayerRespawn(const Common::Network::UnecryptedPacket& request, std::shared_ptr session,
Cast::Classes::RoomsManager& roomsManager,
- Cast::Network::SessionsManager& sessionsManager)
+ Cast::Network::SessionsManager& sessionsManager,
+ Ac::AntiCheatManager& acManager)
{
auto roomOpt = roomsManager.getRoom(session->getId());
if (!roomOpt) return;
@@ -355,6 +360,8 @@ namespace Cast
if (auto targetSession = sessionsManager.getSession(playerRespawnPosition.targetUniqueId.session); targetSession)
{
+ if (targetSession->m_team == Common::Enums::TEAM_OBSERVER) return;
+
targetSession->isDead = (room->isArenaMode() && room->m_hasMatchStarted) ? true : false;
targetSession->m_isInMatch = true;
session->m_isInMatch = true;
@@ -430,6 +437,8 @@ namespace Cast
inline void handleItemPickup(const Common::Network::UnecryptedPacket& request, std::shared_ptr session,
Cast::Classes::RoomsManager& roomsManager)
{
+ if (session->m_team == Common::Enums::TEAM_OBSERVER || !session->m_isInMatch) return;
+
if constexpr (PlayerType == Common::Enums::HOST)
{
roomsManager.broadcastToMatch(session->getId(), const_cast(request));
@@ -446,6 +455,8 @@ namespace Cast
inline void handleZombieAbility(const Common::Network::UnecryptedPacket& request, std::shared_ptr session,
Cast::Classes::RoomsManager& roomsManager)
{
+ if (session->m_team == Common::Enums::TEAM_OBSERVER || !session->m_isInMatch) return;
+
if constexpr (PlayerType == Common::Enums::HOST)
{
roomsManager.broadcastToMatch(session->getId(), const_cast(request));
@@ -460,4 +471,4 @@ namespace Cast
}
}
-#endif
\ No newline at end of file
+#endif
diff --git a/CastServer/include/Handlers/WeaponKillHandlers.h b/CastServer/include/Handlers/WeaponKillHandlers.h
index 9e98be24..dbdb3c94 100644
--- a/CastServer/include/Handlers/WeaponKillHandlers.h
+++ b/CastServer/include/Handlers/WeaponKillHandlers.h
@@ -82,13 +82,30 @@ namespace Cast
Cast::Classes::RoomsManager& roomsManager, Cast::Network::SessionsManager& sessionsManager, Ac::AntiCheatManager& acManager)
{
auto roomOpt = roomsManager.getRoom(session->getId());
- if (!roomOpt) return;
+ if (!roomOpt)
+ {
+ session->asyncWrite(const_cast(request));
+ return;
+ }
auto& room = *roomOpt;
const auto attackerUid = Cast::Details::parseData(request, 16);
const auto targetUid = Cast::Details::parseData(request, 20);
const std::uint16_t targetHp = Cast::Details::parseData(request, 24);
+ if (room->getMode() == Common::Enums::AiBattle || room->getMode() == Common::Enums::BossBattle)
+ {
+ roomsManager.broadcastToMatch(session->getId(), const_cast(request));
+ return;
+ }
+
+ auto attackerSession = sessionsManager.getSession(attackerUid.session);
+ if (attackerSession &&
+ (attackerSession->m_team == Common::Enums::TEAM_OBSERVER || !attackerSession->m_isInMatch))
+ {
+ return;
+ }
+
if (auto targetSession = sessionsManager.getSession(targetUid.session))
{
if (targetHp)
@@ -117,7 +134,7 @@ namespace Cast
{
Cast::Handlers::sendPlayerStateUpdate(targetSession->getAccountId(), true);
}
- if (auto attackerSession = sessionsManager.getSession(attackerUid.session))
+ if (attackerSession)
{
acManager.submitEvent(std::make_unique(attackerSession, 4, 1000, "Room Rape (flooding)", 265));
}
@@ -127,19 +144,37 @@ namespace Cast
}
// mg & shotgun
+ // issue: in boss battle, mg/shotgun work for NPCs, but they don't disappear when killed with mg/shotgun
inline void handleSpecialWeaponDamage(const Common::Network::UnecryptedPacket& request, std::shared_ptr session,
Cast::Classes::RoomsManager& roomsManager,
Cast::Network::SessionsManager& sessionsManager,
Ac::AntiCheatManager& acManager)
{
auto roomOpt = roomsManager.getRoom(session->getId());
- if (!roomOpt) return;
+ if (!roomOpt)
+ {
+ session->asyncWrite(const_cast(request));
+ return;
+ }
auto& room = *roomOpt;
std::uint16_t targetHp = Cast::Details::parseDataFromEnd(request, 6);
auto targetUid = Cast::Details::parseDataFromEnd(request, 8);
auto attackerUid = Cast::Details::parseData(request, 16);
+ if (room->getMode() == Common::Enums::AiBattle || room->getMode() == Common::Enums::BossBattle)
+ {
+ roomsManager.broadcastToMatch(session->getId(), const_cast(request));
+ return;
+ }
+
+ auto attackerSession = sessionsManager.getSession(attackerUid.session);
+ if (attackerSession &&
+ (attackerSession->m_team == Common::Enums::TEAM_OBSERVER || !attackerSession->m_isInMatch))
+ {
+ return;
+ }
+
if (auto targetSession = sessionsManager.getSession(targetUid.session))
{
if (targetHp)
@@ -167,7 +202,7 @@ namespace Cast
{
Cast::Handlers::sendPlayerStateUpdate(targetSession->getAccountId(), true);
}
- if (auto attackerSession = sessionsManager.getSession(attackerUid.session))
+ if (attackerSession)
{
acManager.submitEvent(std::make_unique(attackerSession, 4, 1000, "Room Rape (flooding)", 265));
}
@@ -181,10 +216,14 @@ namespace Cast
Cast::Network::SessionsManager& sessionsManager)
{
auto roomOpt = roomsManager.getRoom(session->getId());
- if (!roomOpt) return;
+ if (!roomOpt)
+ {
+ session->asyncWrite(const_cast(request));
+ return;
+ }
auto& room = *roomOpt;
- if (request.getOption() == 0)
+ if (request.getOption() == 0 || room->getMode() == Common::Enums::AiBattle || room->getMode() == Common::Enums::BossBattle)
{
roomsManager.broadcastToMatch(session->getId(), const_cast(request));
}
diff --git a/CastServer/include/Network/CastSession.h b/CastServer/include/Network/CastSession.h
index e6118f37..211339ac 100644
--- a/CastServer/include/Network/CastSession.h
+++ b/CastServer/include/Network/CastSession.h
@@ -13,21 +13,21 @@
#include "../../../MainServer/include/Structures/AccountInfo/MainAccountInfo.h"
#include "Network/Session.h"
#include "../Structures/PlayerPositionFromClient.h"
+#include "../include/Enums/PlayerEnums.h"
namespace Cast
{
namespace Network
{
-
class Session final : public Common::Network::Session
{
protected:
std::uint32_t m_roomNumber{};
public:
+ Common::Enums::Team m_team{};
bool isDead{};
bool m_isInMatch{ 0 };
- Common::Enums::Team m_team{};
std::string m_nickname;
bool m_isInvisible{};
diff --git a/CastServer/include/Structures/PlayerPositionFromClient.h b/CastServer/include/Structures/PlayerPositionFromClient.h
index aa639b59..c8778f60 100644
--- a/CastServer/include/Structures/PlayerPositionFromClient.h
+++ b/CastServer/include/Structures/PlayerPositionFromClient.h
@@ -2,8 +2,9 @@
#define PLAYER_POSITION_STRUCTURE_H
#include
-#include "DirectXPackedVector.h"
+#include
#include "AntiCheat/Event.h"
+#include "Macros.h"
namespace Cast
{
@@ -54,7 +55,7 @@ namespace Cast
return (sign << 31) | 0x7F800000; // Infinity case
}
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct PositionStruct
{
DirectX::PackedVector::HALF positionX{};
@@ -67,9 +68,9 @@ namespace Cast
return isBadPosition(positionX) || isBadPosition(positionY) || isBadPosition(positionZ);
}
};
-#pragma pack(pop)
+PACK_POP()
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct DirectionStruct
{
DirectX::PackedVector::HALF directionX{};
@@ -82,10 +83,9 @@ namespace Cast
return isBadPosition(directionX) || isBadPosition(directionY) || isBadPosition(directionZ);
}
};
+PACK_POP()
-#pragma pack(pop)
-
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct BulletsStruct
{
DirectX::PackedVector::HALF bullet1{};
@@ -100,10 +100,10 @@ namespace Cast
return isBadPosition(bullet1) || isBadPosition(bullet2) || isBadPosition(bullet3) || isBadPosition(bullet4);
}
};
+PACK_POP()
-#pragma pack(pop)
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct JumpStruct
{
DirectX::PackedVector::HALF jump1;
@@ -115,11 +115,9 @@ namespace Cast
return isBadPosition(jump1) || isBadPosition(jump2);
}
};
-
-#pragma pack(pop)
-
+PACK_POP()
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct ClientPlayerInfoBasic
{
PositionStruct position;
@@ -135,11 +133,11 @@ namespace Cast
{
return position.isBadPos() || direction.isBadDir();
}
- };
-#pragma pack(pop)
+ };
+PACK_POP()
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct ClientPlayerInfoJump
{
ClientPlayerInfoBasic playerPositionBasic;
@@ -150,10 +148,10 @@ namespace Cast
return playerPositionBasic.isBad() || jumpStruct.isBadJump();
}
};
+PACK_POP()
-#pragma pack(pop)
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct ClientPlayerInfoBullet
{
ClientPlayerInfoBasic playerPositionBasic;
@@ -164,9 +162,10 @@ namespace Cast
return playerPositionBasic.isBad() || bulletStruct.isBadBullets();
}
};
-#pragma pack(pop)
-
-#pragma pack(push, 1)
+PACK_POP()
+
+
+PACK_PUSH(1)
struct ClientPlayerInfoComplete
{
ClientPlayerInfoBasic playerPositionBasic;
@@ -178,19 +177,18 @@ namespace Cast
return playerPositionBasic.isBad() || bulletStruct.isBadBullets() || jumpStruct.isBadJump();
}
};
-#pragma pack(pop)
-
+PACK_POP()
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct SinglePlayerJoinInfo
{
char u0[16]{};
Main::Structures::UniqueId uid;
std::uint32_t unknown{};
};
-#pragma pack(pop)
+PACK_POP()
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct SinglePlayerJoinInfoResponse
{
Main::Structures::UniqueId uid;
@@ -198,9 +196,9 @@ namespace Cast
std::uint32_t mode : 5 = 0; // client checks whether the mode is zombie for some reason
std::uint32_t playerState : 4 = 0;
};
-#pragma pack(pop)
+PACK_POP()
-#pragma pack(push, 1
+PACK_PUSH(1)
struct PlayerRespawnPosition
{
std::uint16_t x{};
@@ -218,6 +216,7 @@ namespace Cast
return *this;
}
};
+PACK_POP()
}
}
-#endif
\ No newline at end of file
+#endif
diff --git a/CastServer/include/Structures/PlayerPositionFromServer.h b/CastServer/include/Structures/PlayerPositionFromServer.h
index 39352ec3..83f2e53e 100644
--- a/CastServer/include/Structures/PlayerPositionFromServer.h
+++ b/CastServer/include/Structures/PlayerPositionFromServer.h
@@ -4,13 +4,14 @@
#include
#include "PlayerPositionFromClient.h"
+#include "Macros.h"
namespace Cast
{
namespace Structures
{
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct SpecificInfo
{
std::uint32_t sessionId : 14 = 0;
@@ -22,12 +23,12 @@ namespace Cast
std::uint32_t unknown : 1 = true;
std::uint32_t enableJump : 1 = false;
};
-#pragma pack(pop)
+PACK_POP()
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct PlayerInfoBasicResponse
{
- std::uint32_t tick{};
+ // std::uint32_t tick{};
SpecificInfo specificInfo{};
Cast::Structures::PositionStruct position;
Cast::Structures::DirectionStruct direction;
@@ -36,20 +37,20 @@ namespace Cast
std::uint32_t rotation3 : 9 = 0;
std::uint32_t currentWeapon : 4 = 0;
};
-#pragma pack(pop)
+PACK_POP()
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct PlayerInfoResponseWithJump
{
PlayerInfoBasicResponse playerInfoBasicResponse;
Cast::Structures::JumpStruct jump{};
};
-#pragma pack(pop)
+PACK_POP()
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct PlayerInfoResponseWithBullets
{
- std::uint32_t tick{};
+ // std::uint32_t tick{};
SpecificInfo specificInfo{};
Cast::Structures::PositionStruct position;
Cast::Structures::DirectionStruct direction;
@@ -59,16 +60,15 @@ namespace Cast
std::uint32_t rotation3 : 9 = 0;
std::uint32_t currentWeapon : 4 = 0;
};
-#pragma pack(pop)
+PACK_POP()
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct PlayerInfoResponseComplete
{
PlayerInfoResponseWithBullets playerInfoBasicResponse;
Cast::Structures::JumpStruct jump{};
};
-#pragma pack(pop)
-
+PACK_POP()
}
}
diff --git a/CastServer/include/Structures/Rest.h b/CastServer/include/Structures/Rest.h
index 1033802e..1927a5ad 100644
--- a/CastServer/include/Structures/Rest.h
+++ b/CastServer/include/Structures/Rest.h
@@ -4,29 +4,30 @@
#include
#include "../../../MainServer/include/Structures/AccountInfo/MainAccountUniqueId.h"
-
+#include "Macros.h"
namespace Cast
{
namespace Structures
{
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct SpecialItem // Used to send special items for assassin mode
{
std::uint32_t number{};
std::uint32_t itemId{};
Main::Structures::UniqueId uid{};
};
-#pragma pack(pop)
+PACK_POP()
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct SpecialItemUse
{
std::uint32_t itemId{};
Main::Structures::UniqueId uid{};
};
-#pragma pack(pop)
+PACK_POP()
+PACK_PUSH(1)
struct RespawnCoord
{
std::int32_t x;
@@ -34,6 +35,7 @@ namespace Cast
std::int32_t z;
std::int32_t w = 0;
};
+PACK_POP()
}
}
diff --git a/CastServer/include/Structures/SuicideStruct.h b/CastServer/include/Structures/SuicideStruct.h
index 457fefb5..62e0f5de 100644
--- a/CastServer/include/Structures/SuicideStruct.h
+++ b/CastServer/include/Structures/SuicideStruct.h
@@ -4,13 +4,13 @@
#include
#include "../../../MainServer/include/Structures/AccountInfo/MainAccountUniqueId.h"
-
+#include "Macros.h"
namespace Cast
{
namespace Structures
{
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct SuicideStructure
{
std::uint16_t posX;
@@ -21,7 +21,7 @@ namespace Cast
Main::Structures::UniqueId uniqueId;
std::uint32_t newHp = 0;
};
-#pragma pack(pop)
+PACK_POP()
}
}
diff --git a/CastServer/include/Utils/Utilities.h b/CastServer/include/Utils/Utilities.h
index e67c954b..6a03b214 100644
--- a/CastServer/include/Utils/Utilities.h
+++ b/CastServer/include/Utils/Utilities.h
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
namespace Cast
{
@@ -72,7 +73,7 @@ namespace Cast
return parseDataImpl(request, offset, location);
}
- bool mustBroadcastDeath(std::uint32_t mode)
+ inline bool mustBroadcastDeath(std::uint32_t mode)
{
return (mode == Common::Enums::Elimination || mode == Common::Enums::CaptureTheBattery
|| mode == Common::Enums::BombBattle || mode == Common::Enums::Clan_BombBattle
diff --git a/CastServer/src/CastServer.cpp b/CastServer/src/CastServer.cpp
index 43f57784..010f65e8 100644
--- a/CastServer/src/CastServer.cpp
+++ b/CastServer/src/CastServer.cpp
@@ -4,16 +4,33 @@
#include "../include/Handlers/PlayerPositionHandler.h"
#include "../include/Handlers/IpcMainHandlers.h"
#include "../include/Handlers/WeaponKillHandlers.h"
+#include
namespace Cast
{
+ void CastServer::tickPositionFlush()
+ {
+ for (auto& room : m_roomsManager.getAllRooms())
+ {
+ room->flushPendingPositions();
+ }
+
+ m_positionTimer->expires_after(std::chrono::milliseconds(50));
+ m_positionTimer->async_wait([this](auto) { tickPositionFlush(); });
+ }
CastServer::CastServer(ioContext& io_context, const std::string& serverIp, std::uint16_t port, std::uint16_t mainPort, std::uint16_t serverId)
: m_io_context{ io_context }
, m_acceptor{ io_context, tcp::endpoint(asio::ip::address::from_string(serverIp), port) }
, m_serverId{ serverId }
- , m_mainServerAcceptor{ io_context, tcp::endpoint(asio::ip::address::from_string(Common::Utils::SetupParser::getInstance().getSelfCastServerInfo().ip), mainPort)}
+ , m_mainServerAcceptor{ io_context, tcp::endpoint(asio::ip::address::from_string(Common::Utils::SetupParser::getInstance().getSelfCastServerInfo().ip), mainPort) }
{
+ using namespace std::chrono;
+
+ m_sessionsManager.setRoomsManager(&m_roomsManager);
+ m_positionTimer = std::make_shared(m_io_context);
+ tickPositionFlush();
+
namespace CN = Common::Network;
using namespace Cast::Network;
@@ -42,14 +59,14 @@ namespace Cast
// Player respawn request
Common::Network::Session::addCallback(166, [&](const Common::Network::UnecryptedPacket& request,
std::shared_ptr session) {
- if (request.getDataSize() != 0) return;
+ if (m_roomsManager.getModeOf(session->getId()) != Common::Enums::BossBattle && request.getDataSize() != 0) return;
session->isDead = false;
m_roomsManager.playerForwardToHost(request.getSession(), session->getId(), const_cast(request));
});
// Room creation
Common::Network::Session::addCallback(277, [&](const Common::Network::UnecryptedPacket& request,
- std::shared_ptr session) { m_roomsManager.addRoom(std::make_shared(session->getId(), session),
+ std::shared_ptr session) { m_roomsManager.addRoom(std::make_shared(session->getId(), session),
session->getId()); });
// Leaving a room
@@ -86,9 +103,27 @@ namespace Cast
// Unknown
Common::Network::Session::addCallback(280, [&](const Common::Network::UnecryptedPacket& request,
std::shared_ptr session) {
- m_roomsManager.playerForwardToHost(session->getId(), request.getSession(), const_cast(request));
+ m_roomsManager.playerForwardToHost(request.getSession(), session->getId(), const_cast(request));
});
+ // AI Battle
+ Common::Network::Session::addCallback(286, [&](const Common::Network::UnecryptedPacket& request,
+ std::shared_ptr session) {
+ if (m_roomsManager.getModeOf(session->getId()) == Common::Enums::AiBattle)
+ {
+ m_roomsManager.broadcastToMatch(session->getId(), const_cast(request));
+ }
+ });
+
+ Common::Network::Session::addCallback(285, [&](const Common::Network::UnecryptedPacket& request,
+ std::shared_ptr session) {
+ if (m_roomsManager.getModeOf(session->getId()) == Common::Enums::AiBattle)
+ {
+ m_roomsManager.broadcastToMatch(session->getId(), const_cast(request));
+ }
+ });
+
+
Common::Network::Session::addCallback(281, [&](const Common::Network::UnecryptedPacket& request,
std::shared_ptr session) { Cast::Handlers::handlePlayerPosition(request, session, m_roomsManager, m_serverId, m_sessionsManager,
m_acManager); });
@@ -102,8 +137,8 @@ namespace Cast
// Match leave
Common::Network::Session::addCallback(256, [&](const Common::Network::UnecryptedPacket& request,
- std::shared_ptr session) {
- session->setIsInMatch(false);
+ std::shared_ptr session) {
+ session->setIsInMatch(false);
auto roomOpt = m_roomsManager.getRoom(session->getId());
if (!roomOpt) return;
@@ -118,11 +153,12 @@ namespace Cast
std::shared_ptr session)
{
// Not sure what this is for -- each player in the room sends this to host (through request.getSession())
+ m_roomsManager.broadcastToMatch(session->getId(), const_cast(request));
});
// Player sync (needed because otherwise the player: 1. does not get the time left of the match, and 2. they don't respawn at all)
Common::Network::Session::addCallback(309, [&](const Common::Network::UnecryptedPacket& request,
- std::shared_ptr session) { m_roomsManager.hostForwardToPlayer(session->getId(), request.getSession(),
+ std::shared_ptr session) { m_roomsManager.hostForwardToPlayer(session->getId(), request.getSession(),
const_cast(request)); });
// without this e.g. the bomb in "bomb battle" doesn't exist seemingly
@@ -134,9 +170,13 @@ namespace Cast
// Room tick sync request:
// When Option==9 in packet order 257: the non host's client sends packet 79 to the server, which dispatches to the host
// This packet asks the host to provide the room sync to the non-host
- Common::Network::Session::addCallback < CN::PacketType::UNECRYPTED, Session>(79, [&](const Common::Network::UnecryptedPacket& request,
- std::shared_ptr session) { m_roomsManager.playerForwardToHost(request.getSession(), session->getId(),
- const_cast(request)); });
+ Common::Network::Session::addCallback(
+ 79,
+ [&](const Common::Network::UnecryptedPacket& request, std::shared_ptr session) {
+ m_roomsManager.playerForwardToHost(request.getSession(), session->getId(), const_cast(request));
+ }
+ );
+
// In-room info request, apparenly contains "isDeath" data??
Common::Network::Session::addCallback(306, [&](const Common::Network::UnecryptedPacket& request,
@@ -151,12 +191,12 @@ namespace Cast
// Zombie team broadcast for players that join the match late
Common::Network::Session::addCallback(78, [&](const Common::Network::UnecryptedPacket& request,
- std::shared_ptr session) { m_roomsManager.playerForwardToHost(request.getSession(), session->getId(),
+ std::shared_ptr session) { m_roomsManager.playerForwardToHost(request.getSession(), session->getId(),
const_cast(request)); });
// Next round handler, this is covered in main, not sure why client sends it in cast -- but in any case cast sv must do nothing with it
// otherwise if we resend this packet (host=>player or player=>host or broadcast) next round never starts
- Common::Network::Session::addCallback(259, [&](const Common::Network::UnecryptedPacket& request,
+ Common::Network::Session::addCallback(259, [&](const Common::Network::UnecryptedPacket& request,
std::shared_ptr session) {});
// CTB battery respawn for host, Other weapon reload
@@ -165,12 +205,12 @@ namespace Cast
// Bomb Battle related -- NON host
Common::Network::Session::addCallback(155, [&](const Common::Network::UnecryptedPacket& request,
- std::shared_ptr session) { m_roomsManager.playerForwardToHost(request.getSession(), session->getId(),
+ std::shared_ptr session) { m_roomsManager.playerForwardToHost(request.getSession(), session->getId(),
const_cast(request)); });
// Bomb battle drop bomb
Common::Network::Session::addCallback(156, [&](const Common::Network::UnecryptedPacket& request,
- std::shared_ptr session) { m_roomsManager.playerForwardToHost(request.getSession(), session->getId(),
+ std::shared_ptr session) { m_roomsManager.playerForwardToHost(request.getSession(), session->getId(),
const_cast(request)); });
// Bomb battle for host
@@ -189,14 +229,19 @@ namespace Cast
std::shared_ptr session) { Cast::Handlers::handleMatchInitialLoading(request, session, m_roomsManager, m_serverId); });
Common::Network::Session::addCallback(276, [&](const Common::Network::UnecryptedPacket& request,
- std::shared_ptr session) { Cast::Handlers::handlePlayerRespawn(request, session, m_roomsManager, m_sessionsManager); });
+ std::shared_ptr session) { Cast::Handlers::handlePlayerRespawn(request, session, m_roomsManager, m_sessionsManager,
+ m_acManager); });
// Room tick providing:
// After the host client receives packet 78 from the non-host, it provides the non-host with the updated room tick
// Without this handler, the player never respawns (not even TAB shows anything) => The player keeps being in a waiting initial state
Common::Network::Session::addCallback(408, [&](const Common::Network::UnecryptedPacket& request,
- std::shared_ptr session) { m_roomsManager.hostForwardToPlayer(session->getId(), request.getSession(),
- const_cast(request)); });
+ std::shared_ptr session) {
+ m_roomsManager.hostForwardToPlayer(session->getId(), request.getSession(),
+ const_cast(request));
+ }
+ );
+
// Items respawning
Common::Network::Session::addCallback(260, [&](const Common::Network::UnecryptedPacket& request,
@@ -226,28 +271,64 @@ namespace Cast
std::shared_ptr session) { Cast::Handlers::handleZombieAbility(request, session, m_roomsManager); });
// Reminder: do not broadcast the following packets to the whole room, otherwise "next round" elimination bug happens
- // Boss battle - main npcs movement/position
+ // Boss battle - main npcs movement/position, including boss position & small npcs positions
Common::Network::Session::addCallback(282, [&](const Common::Network::UnecryptedPacket& request,
- std::shared_ptr session) { m_roomsManager.broadcastToMatch(session->getId(), const_cast(request)); });
+ std::shared_ptr session)
+ {
+ m_roomsManager.broadcastToMatchExceptSelf(session->getId(), const_cast(request));
+ });
+
// Boss battle - npcs projectiles
Common::Network::Session::addCallback(326, [&](const Common::Network::UnecryptedPacket& request,
- std::shared_ptr session) { m_roomsManager.hostForwardToPlayer(request.getSession(), session->getId(),
- const_cast(request)); });
+ std::shared_ptr session) {
+ if (m_roomsManager.getModeOf(session->getId()) == Common::Enums::BossBattle)
+ {
+ m_roomsManager.broadcastToMatch(session->getId(), const_cast(request));
+ }
+ else
+ {
+ m_roomsManager.hostForwardToPlayer(request.getSession(), session->getId(), const_cast(request));
+ }
+ });
// Boss battle - npcs respawn
Common::Network::Session::addCallback(328, [&](const Common::Network::UnecryptedPacket& request,
- std::shared_ptr session) {m_roomsManager.hostForwardToPlayer(request.getSession(), session->getId(),
- const_cast(request)); });
+ std::shared_ptr session) {
+ if (m_roomsManager.getModeOf(session->getId()) == Common::Enums::BossBattle)
+ {
+ m_roomsManager.broadcastToMatch(session->getId(), const_cast(request));
+ }
+ else
+ {
+ m_roomsManager.hostForwardToPlayer(request.getSession(), session->getId(), const_cast(request));
+ }
+ });
// Boss battle - npc boss attack -- this is already sent to all clients
Common::Network::Session::addCallback(331, [&](const Common::Network::UnecryptedPacket& request,
- std::shared_ptr session) {m_roomsManager.hostForwardToPlayer(request.getSession(), session->getId(),
- const_cast(request)); });
+ std::shared_ptr session) {
+ if (m_roomsManager.getModeOf(session->getId()) == Common::Enums::BossBattle)
+ {
+ m_roomsManager.broadcastToMatch(session->getId(), const_cast(request));
+ }
+ else
+ {
+ m_roomsManager.hostForwardToPlayer(request.getSession(), session->getId(), const_cast(request));
+ }
+ });
Common::Network::Session::addCallback(304, [&](const Common::Network::UnecryptedPacket& request,
- std::shared_ptr session) {m_roomsManager.hostForwardToPlayer(request.getSession(), session->getId(),
- const_cast(request)); });
+ std::shared_ptr session) {
+ if (m_roomsManager.getModeOf(session->getId()) == Common::Enums::BossBattle)
+ {
+ m_roomsManager.broadcastToMatch(session->getId(), const_cast(request));
+ }
+ else
+ {
+ m_roomsManager.hostForwardToPlayer(request.getSession(), session->getId(), const_cast(request));
+ }
+ });
// Shotgun / Mg damage
@@ -267,7 +348,7 @@ namespace Cast
Cast::Handlers::handleNormalWeaponDamage(request, session, m_roomsManager, m_sessionsManager, m_acManager);
});
}
-
+
// Explosives damage
Common::Network::Session::addCallback(264, [&](const Common::Network::UnecryptedPacket& request,
std::shared_ptr session) {
@@ -280,8 +361,6 @@ namespace Cast
m_socket.emplace(m_io_context);
m_acceptor.async_accept(*m_socket, [&](asio::error_code error)
{
- m_sessionsManager.setRoomsManager(&m_roomsManager);
-
auto client = std::make_shared(std::move(*CastServer::m_socket),
std::bind(&Cast::Network::SessionsManager::removeSession, &m_sessionsManager, std::placeholders::_1));
client->m_checkValidSession = true;
diff --git a/CastServer/src/CastServerMain.cpp b/CastServer/src/CastServerMain.cpp
index 9f1f964e..1c83348b 100644
--- a/CastServer/src/CastServerMain.cpp
+++ b/CastServer/src/CastServerMain.cpp
@@ -25,7 +25,7 @@ void printInitialInformation()
int main()
{
- SetConsoleTitleW(L"Microvolts Cast Server");
+ Common::Utils::setConsoleTitle(L"Microvolts Cast Server");
printInitialInformation();
asio::io_context io_context;
@@ -36,6 +36,23 @@ int main()
parsedServerInfo.ipcPort, parsedServerInfo.serverNumber),
Utils::LogType::Normal);
+ const std::string banner = R"(
+
+ _____ __ __ ____ _ ______ _ _
+ / ____| \ \ / / | _ \ (_) | ____| | | | |
+ | (___ __\ \ /\ / /__| |_) | ___ __ _ _ _ __ | |__ _ __ ___ _ _| | __ _| |_ ___ _ __
+ \___ \ / _ \ \/ \/ / _ \ _ < / _ \/ _` | | '_ \ | __| | '_ ` _ \| | | | |/ _` | __/ _ \| '__|
+ ____) | (_) \ /\ / __/ |_) | __/ (_| | | | | | | |____| | | | | | |_| | | (_| | || (_) | |
+ |_____/ \___/ \/ \/ \___|____/ \___|\__, |_|_| |_| |______|_| |_| |_|\__,_|_|\__,_|\__\___/|_|
+ __/ |
+ |___/
+
+ GitHub: https://github.com/SoWeBegin/MicrovoltsEmulator
+
+)";
+
+ Utils::Logger::log(banner, Utils::LogType::Info);
+
Cast::CastServer srv(io_context, parsedServerInfo.ip, parsedServerInfo.port, parsedServerInfo.ipcPort, parsedServerInfo.serverNumber);
srv.asyncAccept();
diff --git a/CastServer/src/Classes/Room.cpp b/CastServer/src/Classes/Room.cpp
index d909a6ff..7f8c7de6 100644
--- a/CastServer/src/Classes/Room.cpp
+++ b/CastServer/src/Classes/Room.cpp
@@ -8,6 +8,8 @@
#include
#include
#include
+#include
+#include
namespace Cast
{
@@ -169,6 +171,22 @@ namespace Cast
}
}
+ void Room::broadcastToMatchExceptSelf(Common::Network::UnecryptedPacket& packet, std::uint32_t selfId)
+ {
+ for (auto& currentPlayer : m_playersVec)
+ {
+ if (auto player = currentPlayer.lock())
+ {
+ if (!player->m_isInMatch) continue;
+ if (player->getId() == selfId) continue;
+
+ packet.setTcpHeader(player->getId());
+ player->asyncWrite(packet);
+ }
+ }
+ }
+
+
bool Room::isInMatch(std::uint64_t playerSessionId) const
{
auto it = std::find_if(m_playersVec.begin(), m_playersVec.end(),
@@ -369,7 +387,41 @@ namespace Cast
broadcastToMatch(response);
}
}
+ }
+ void Room::enqueuePosition(Common::Network::UnecryptedPacket&& pkt)
+ {
+ m_pendingPositions.push_back(std::move(pkt));
}
+
+ void Room::flushPendingPositions()
+ {
+ if (m_pendingPositions.empty()) return;
+
+ static std::array batchBuffer;
+ std::size_t totalSize = 0;
+ std::size_t count = 0;
+
+ for (auto& pkt : m_pendingPositions)
+ {
+ const auto size = pkt.getDataSize();
+ if (totalSize + size > 2036) break; // 8 bytes header + 4 bytes roomtick
+ std::memcpy(batchBuffer.data() + totalSize, pkt.getData(), size);
+ totalSize += size;
+ ++count;
+ }
+
+ //const std::uint32_t serverTick = m_roomTick - (((Common::Utils::getCurrentTimestampMs() - timeSinceLastRestart) / 10) - m_roomTick);
+ std::memmove(batchBuffer.data() + sizeof(m_roomTick), batchBuffer.data(), totalSize);
+ std::memcpy(batchBuffer.data(), &m_roomTick, sizeof(m_roomTick));
+ totalSize += sizeof(m_roomTick);
+ static Common::Network::UnecryptedPacket batch(2048, 322, static_cast(count));
+ batch.setOption(static_cast(count));
+ batch.setData(batchBuffer.data(), static_cast(totalSize));
+
+ broadcastToRoom(batch);
+ m_pendingPositions.clear();
+ }
+
};
}
diff --git a/CastServer/src/Classes/RoomsManager.cpp b/CastServer/src/Classes/RoomsManager.cpp
index f6422a30..dacb3c01 100644
--- a/CastServer/src/Classes/RoomsManager.cpp
+++ b/CastServer/src/Classes/RoomsManager.cpp
@@ -13,6 +13,7 @@ namespace Cast
if (playerId < m_playerSessionIdToRoom.size())
{
m_playerSessionIdToRoom[playerId] = room;
+ m_rooms.push_back(std::move(room));
}
}
@@ -82,6 +83,19 @@ namespace Cast
playerRoom->broadcastToMatch(packet);
}
+ void RoomsManager::broadcastToMatchExceptSelf(std::uint64_t sessionId, Common::Network::UnecryptedPacket& packet)
+ {
+ if (sessionId >= m_playerSessionIdToRoom.size())
+ return;
+
+ auto& playerRoom = m_playerSessionIdToRoom[sessionId];
+
+ if (!playerRoom)
+ return;
+
+ playerRoom->broadcastToMatchExceptSelf(packet, sessionId);
+ }
+
void RoomsManager::broadcastToRoomExceptSelfAndHost(std::uint64_t sessionId, std::uint64_t hostSessionId, Common::Network::UnecryptedPacket& packet)
{
if (sessionId >= m_playerSessionIdToRoom.size())
@@ -217,6 +231,7 @@ namespace Cast
{
return room->m_redAssassinPos;
}
+ return std::nullopt;
}
void RoomsManager::setModeFor(std::uint64_t playerId, std::uint32_t mode)
@@ -233,17 +248,18 @@ namespace Cast
}
- void RoomsManager::setRoomNumberFor(std::uint64_t playerId, std::uint32_t roomNum)
+ bool RoomsManager::setRoomNumberFor(std::uint64_t playerId, std::uint32_t roomNum)
{
if (playerId >= m_playerSessionIdToRoom.size())
- return;
+ return false;
auto& room = m_playerSessionIdToRoom[playerId];
if (!room)
- return;
+ return false;
room->setRoomNumber(roomNum);
+ return true;
}
bool RoomsManager::exists(std::uint64_t playerId)
@@ -293,6 +309,8 @@ namespace Cast
if (mustRoomBeRemoved)
{
+ m_rooms.erase(std::remove(m_rooms.begin(), m_rooms.end(), roomToRemove), m_rooms.end());
+
for (auto& roomSlot : m_playerSessionIdToRoom)
{
if (roomSlot == roomToRemove)
diff --git a/CastServer/src/Network/SessionsManager.cpp b/CastServer/src/Network/SessionsManager.cpp
index 8cfae775..64792b04 100644
--- a/CastServer/src/Network/SessionsManager.cpp
+++ b/CastServer/src/Network/SessionsManager.cpp
@@ -28,10 +28,6 @@ namespace Cast
void SessionsManager::removeSession(std::size_t sessionId)
{
// The player is inside a room
- if (m_sessionsBySessionId.contains(sessionId) && m_sessionsBySessionId[sessionId] && m_sessionsBySessionId[sessionId]->getRoomNumber())
- {
- m_sessionsBySessionId[sessionId]->setIsInMatch(false);
- }
if (m_sessionsBySessionId.contains(sessionId))
{
m_sessionsBySessionId[sessionId]->setIsInMatch(false);
diff --git a/Client/CgdPasswordUpdater.cpp b/Client/CgdPasswordUpdater.cpp
index 8247b4c5..3366b0fc 100644
--- a/Client/CgdPasswordUpdater.cpp
+++ b/Client/CgdPasswordUpdater.cpp
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
const std::string GREEN = "\033[32m";
const std::string ORANGE = "\033[33m";
diff --git a/Common/CMakeLists.txt b/Common/CMakeLists.txt
new file mode 100644
index 00000000..e5250829
--- /dev/null
+++ b/Common/CMakeLists.txt
@@ -0,0 +1,47 @@
+project(Common LANGUAGES CXX)
+
+file(GLOB_RECURSE COMMON_SOURCES CONFIGURE_DEPENDS
+ ${CMAKE_CURRENT_LIST_DIR}/*.cpp
+)
+
+add_library(Common STATIC
+ ${COMMON_SOURCES}
+)
+
+set_target_properties(Common PROPERTIES
+ ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/ExternalLibraries/CommonLib
+ ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/ExternalLibraries/CommonLib
+ ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/ExternalLibraries/CommonLib
+ ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_SOURCE_DIR}/ExternalLibraries/CommonLib
+ ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_SOURCE_DIR}/ExternalLibraries/CommonLib
+
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/ExternalLibraries/CommonLib
+ LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/ExternalLibraries/CommonLib
+ LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/ExternalLibraries/CommonLib
+ LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_SOURCE_DIR}/ExternalLibraries/CommonLib
+ LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_SOURCE_DIR}/ExternalLibraries/CommonLib
+
+ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/ExternalLibraries/CommonLib
+ RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/ExternalLibraries/CommonLib
+ RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/ExternalLibraries/CommonLib
+ RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_SOURCE_DIR}/ExternalLibraries/CommonLib
+ RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_SOURCE_DIR}/ExternalLibraries/CommonLib
+)
+
+target_include_directories(Common
+ PUBLIC
+ ${CMAKE_CURRENT_LIST_DIR}
+ ${CMAKE_CURRENT_LIST_DIR}/include
+ ${CMAKE_SOURCE_DIR}/ExternalLibraries
+ ${CMAKE_SOURCE_DIR}/Common/include/Utils
+)
+
+target_link_libraries(Common
+ PUBLIC
+ cryptopp::cryptopp
+ unofficial::mariadb-connector-cpp::mariadbcpp
+)
+
+if (WIN32)
+ target_link_libraries(Common PUBLIC wsock32 ws2_32)
+endif()
diff --git a/Common/Common.cpp b/Common/Common.cpp
deleted file mode 100644
index e69de29b..00000000
diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj
deleted file mode 100644
index 4e0be2bb..00000000
--- a/Common/Common.vcxproj
+++ /dev/null
@@ -1,226 +0,0 @@
-
-
-
-
- Debug
- Win32
-
-
- Release
- Win32
-
-
- Debug
- x64
-
-
- Release
- x64
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 16.0
- Win32Proj
- {b17b4c2b-a318-43ab-bd0b-2a0bb9b4470d}
- Common
- 10.0
-
-
-
- StaticLibrary
- true
- v143
- Unicode
-
-
- StaticLibrary
- false
- v143
- true
- Unicode
-
-
- StaticLibrary
- true
- v143
- Unicode
- false
-
-
- StaticLibrary
- false
- ClangCL
- false
- Unicode
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ..\ExternalLibraries\CommonLib\
-
-
- ..\ExternalLibraries\CommonLib\
-
-
- ..\ExternalLibraries\CommonLib\
-
-
- ..\ExternalLibraries\vcpkg\vcpkg_installed
-
-
- ..\ExternalLibraries\vcpkg\vcpkg_installed
-
-
- ..\ExternalLibraries\vcpkg\vcpkg_installed
-
-
-
- Level3
- true
- WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
- true
- ..\Common; ..\ExternalLibraries\visit_struct; ..\ExternalLibraries\asio-1.24.0\include; ..\ExternalLibraries
- stdcpp20
-
-
- Console
- true
-
-
-
-
- Level3
- true
- true
- true
- WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
- true
- stdcpplatest
- ..\Common; ..\ExternalLibraries\visit_struct; ..\ExternalLibraries\asio-1.24.0\include; ..\ExternalLibraries
-
-
- Console
- true
- true
- true
-
-
-
-
- Level3
- true
- NDEBUG;_CONSOLE;ENABLE_DEBUG_MESSAGES;_CRT_SECURE_NO_WARNINGS
- true
- stdcpplatest
- ..\Common; ..\ExternalLibraries\visit_struct; ..\ExternalLibraries\asio-1.24.0\include; ..\ExternalLibraries
- ProgramDatabase
- MaxSpeed
-
-
- Console
- true
-
-
-
-
- Level3
- true
- true
- true
- NDEBUG;_CONSOLE;ENABLE_DEBUG_MESSAGES;_CRT_SECURE_NO_WARNINGS
- true
- stdcpplatest
- ..\Common; ..\ExternalLibraries\visit_struct; ..\ExternalLibraries\asio-1.24.0\include; ..\ExternalLibraries; ..\ExternalLibraries\vcpkg\vcpkg_installed\x64-windows\include
- Speed
- MaxSpeed
- AnySuitable
- false
- false
- EditAndContinue
- EnableFastChecks
- stdc11
-
-
- Console
- true
- true
- true
-
-
- ..\ExternalLibraries\CommonLib\Common.lib
-
-
- ..\ExternalLibraries\vcpkg\vcpkg_installed\x64-windows\lib
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters
deleted file mode 100644
index 8aeca79e..00000000
--- a/Common/Common.vcxproj.filters
+++ /dev/null
@@ -1,162 +0,0 @@
-
-
-
-
- {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
- cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
-
-
- {93995380-89BD-4b04-88EB-625FBE52EBFB}
- h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
-
-
- {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
- rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
-
-
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
- File di intestazione
-
-
-
-
- File di origine
-
-
- File di origine
-
-
- File di origine
-
-
- File di origine
-
-
- File di origine
-
-
- File di origine
-
-
- File di origine
-
-
- File di origine
-
-
-
\ No newline at end of file
diff --git a/Common/include/AntiCheat/AntiCheat.h b/Common/include/AntiCheat/AntiCheat.h
index 1c7c32d3..ac524644 100644
--- a/Common/include/AntiCheat/AntiCheat.h
+++ b/Common/include/AntiCheat/AntiCheat.h
@@ -95,7 +95,7 @@ namespace Ac
}
public:
- AntiCheatManager()
+ AntiCheatManager()
{
registerChecker();
registerChecker();
@@ -104,6 +104,7 @@ namespace Ac
m_thread = std::thread(&AntiCheatManager::worker, this);
}
+
~AntiCheatManager()
{
m_isRunning = false;
diff --git a/Common/include/AntiCheat/Checks/PacketFloodingCheck.h b/Common/include/AntiCheat/Checks/PacketFloodingCheck.h
index 74b8bc95..c5b6134c 100644
--- a/Common/include/AntiCheat/Checks/PacketFloodingCheck.h
+++ b/Common/include/AntiCheat/Checks/PacketFloodingCheck.h
@@ -31,12 +31,11 @@ namespace Ac
public:
std::optional processEvent(const PacketFloodingEvent& event) override
{
- const std::uint64_t serverTime = Common::Utils::getCurrentTimestampMs();
auto& packetRecords = playerData[event.session->getId()][event.packetId];
- packetRecords.push_back({ serverTime, event });
+ packetRecords.push_back({ event.eventTime, event });
while (!packetRecords.empty() &&
- (serverTime - packetRecords.front().serverTime) > event.analysisWindowMs)
+ (event.eventTime - packetRecords.front().serverTime) > event.analysisWindowMs)
{
packetRecords.pop_front();
}
@@ -52,13 +51,14 @@ namespace Ac
"s (max " + std::to_string(event.maxPacketsPerSecond) + ")"
};
packetRecords.clear();
- event.session->closeSocket();
+ //event.session->closeSocket();
return flag;
}
return std::nullopt;
}
+
};
}
diff --git a/Common/include/AntiCheat/Checks/PacketReplicaCheck.h b/Common/include/AntiCheat/Checks/PacketReplicaCheck.h
index 7929604c..f19c3dc7 100644
--- a/Common/include/AntiCheat/Checks/PacketReplicaCheck.h
+++ b/Common/include/AntiCheat/Checks/PacketReplicaCheck.h
@@ -32,7 +32,6 @@ namespace Ac
public:
std::optional processEvent(const PacketReplicationEvent& event) override
{
- const std::uint64_t serverTime = Common::Utils::getCurrentTimestampMs();
const size_t packetHash = calculatePacketHash(event.data);
auto& playerPackets = playerData[event.session->getId()];
@@ -40,14 +39,14 @@ namespace Ac
{
timestamps.erase(
std::remove_if(timestamps.begin(), timestamps.end(), [&](std::uint64_t ts) {
- return (serverTime - ts) > analysisWindowMs;
+ return (event.eventTime - ts) > analysisWindowMs;
}),
timestamps.end()
);
}
auto& timestamps = playerPackets[packetHash];
- timestamps.push_back(serverTime);
+ timestamps.push_back(event.eventTime);
if (timestamps.size() >= 4)
{
@@ -59,7 +58,7 @@ namespace Ac
floatToString(analysisWindowMs / 1000.0f) + "s window"
};
- playerData[event.session->getId()].clear();
+ playerData[event.session->getId()].clear();
event.session->closeSocket();
return flag;
diff --git a/Common/include/AntiCheat/Event.h b/Common/include/AntiCheat/Event.h
index 5b168c2d..be72a350 100644
--- a/Common/include/AntiCheat/Event.h
+++ b/Common/include/AntiCheat/Event.h
@@ -1,21 +1,24 @@
#ifndef EVENT_AC_H
#define EVENT_AC_H
-#include "DirectXPackedVector.h"
#include
#include
+#include "../Utils/Utils.h"
+#include "../Network/Session.h"
namespace Ac
{
struct ACEvent
{
virtual ~ACEvent() = default;
+
enum class Type
{
PlayerPosition,
PlayerKill,
PacketFlooding,
- PacketReplication
+ PacketReplication,
+ ObserverCheck,
} type;
};
@@ -26,11 +29,13 @@ namespace Ac
std::uint64_t analysisWindowMs;
std::string floodingType;
std::uint32_t packetId;
+ std::uint64_t eventTime;
PacketFloodingEvent(std::shared_ptr session_, std::size_t maxPacketsPerS_,
std::uint64_t analysisWindowMs_, const std::string& type_, std::uint32_t packetId_)
: session(session_), maxPacketsPerSecond(maxPacketsPerS_), analysisWindowMs(analysisWindowMs_),
- floodingType(type_), packetId(packetId_)
+ floodingType(type_), packetId(packetId_),
+ eventTime(Common::Utils::getCurrentTimestampMs())
{
type = Type::PacketFlooding;
}
@@ -38,15 +43,33 @@ namespace Ac
static constexpr Type typeValue = Type::PacketFlooding;
};
+ template
+ struct OutsideMatchActionEvent : ACEvent
+ {
+ std::shared_ptr session;
+ std::string message;
+
+ OutsideMatchActionEvent(std::shared_ptr session_, const std::string& mss)
+ : session(session_), message(mss)
+ {
+ type = Type::ObserverCheck;
+ }
+
+ static constexpr Type typeValue = Type::ObserverCheck;
+ };
+
+
struct PacketReplicationEvent : ACEvent
{
std::shared_ptr session;
std::uint16_t packetId;
std::vector data;
+ std::uint64_t eventTime;
- PacketReplicationEvent(std::shared_ptr session_, std::uint16_t packetId_,
+ PacketReplicationEvent(std::shared_ptr session_, std::uint16_t packetId_,
const std::vector& data_)
- : session(session_), packetId(packetId_), data(data_)
+ : session(session_), packetId(packetId_), data(data_),
+ eventTime(Common::Utils::getCurrentTimestampMs())
{
type = Type::PacketReplication;
}
diff --git a/Common/include/ConstantDatabase/Cdb.h b/Common/include/ConstantDatabase/Cdb.h
index 09f4ca66..4e4a9498 100644
--- a/Common/include/ConstantDatabase/Cdb.h
+++ b/Common/include/ConstantDatabase/Cdb.h
@@ -9,6 +9,7 @@
#include
#include
#include "../Utils/Logger.h"
+#include
namespace Common
{
diff --git a/Common/include/ConstantDatabase/CdbSingleton.h b/Common/include/ConstantDatabase/CdbSingleton.h
index 1521a14f..80ec36b9 100644
--- a/Common/include/ConstantDatabase/CdbSingleton.h
+++ b/Common/include/ConstantDatabase/CdbSingleton.h
@@ -41,7 +41,7 @@ namespace Common
return m_itemByType[itemId];
}
- static bool itemExistsInShop(std::uint32_t itemId) requires std::same_as
+ static bool itemExistsInShop(std::uint32_t itemId) requires (std::same_as)
{
return m_shopItemIds.contains(itemId);
}
@@ -125,8 +125,8 @@ namespace Common
}
static void initialize(const std::string& filePath, const std::string& fileName)
- requires std::same_as or std::same_as
- or std::same_as
+ requires (std::same_as or std::same_as
+ or std::same_as)
{
m_cdb.parse_non_unique_key(filePath, fileName);
}
@@ -152,6 +152,21 @@ namespace Common
}
}
+ static void filterGambleItemsByRareCapsules(const std::vector& rareCapsuleItems)
+ {
+ std::unordered_set rareIds;
+ rareIds.reserve(rareCapsuleItems.size());
+ for (const auto& capsule : rareCapsuleItems)
+ rareIds.insert(capsule.gi_itemid);
+
+ for (auto& [type, itemList] : m_gambleItems)
+ {
+ itemList.erase(std::remove_if(itemList.begin(), itemList.end(),
+ [&](std::uint32_t id) { return !rareIds.contains(id); }),
+ itemList.end());
+ }
+ }
+
CdbSingleton(CdbSingleton const&) = delete;
void operator=(CdbSingleton const&) = delete;
@@ -162,4 +177,4 @@ namespace Common
};
}
}
-#endif
\ No newline at end of file
+#endif
diff --git a/Common/include/ConstantDatabase/Structures/CdbCapsuleInfo.h b/Common/include/ConstantDatabase/Structures/CdbCapsuleInfo.h
index abb1488f..909ab2da 100644
--- a/Common/include/ConstantDatabase/Structures/CdbCapsuleInfo.h
+++ b/Common/include/ConstantDatabase/Structures/CdbCapsuleInfo.h
@@ -2,13 +2,13 @@
#define CGD_CAPSULE_INFO_H
#include "visit_struct/visit_struct.hpp"
+#include "Macros.h"
namespace Common
{
-
namespace ConstantDatabase
{
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct CdbCapsuleInfo
{
std::uint32_t gi_id = static_cast(-1);
@@ -26,7 +26,7 @@ namespace Common
constexpr std::uint32_t getId() const noexcept { return gi_id; }
constexpr bool isValid() const noexcept { return gi_id != static_cast(-1); }
};
-#pragma pack(pop)
+PACK_POP()
}
}
diff --git a/Common/include/ConstantDatabase/Structures/CdbCapsulePackageInfo.h b/Common/include/ConstantDatabase/Structures/CdbCapsulePackageInfo.h
index 8983fd15..c6a31d95 100644
--- a/Common/include/ConstantDatabase/Structures/CdbCapsulePackageInfo.h
+++ b/Common/include/ConstantDatabase/Structures/CdbCapsulePackageInfo.h
@@ -2,12 +2,13 @@
#define CGD_CAPSULE_PACKAGE_INFO_H
#include "visit_struct/visit_struct.hpp"
+#include "Macros.h"
namespace Common
{
namespace ConstantDatabase
{
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct CdbCapsulePackageInfo
{
int gi_id{};
@@ -22,7 +23,7 @@ namespace Common
constexpr std::uint32_t getId() const noexcept { return gi_infoid; }
constexpr bool isValid() const noexcept { return gi_infoid != static_cast(-1); }
};
-#pragma pack(pop)
+PACK_POP()
}
}
diff --git a/Common/include/ConstantDatabase/Structures/CdbCollectionInfo.h b/Common/include/ConstantDatabase/Structures/CdbCollectionInfo.h
index c1edf70a..462652d4 100644
--- a/Common/include/ConstantDatabase/Structures/CdbCollectionInfo.h
+++ b/Common/include/ConstantDatabase/Structures/CdbCollectionInfo.h
@@ -2,12 +2,13 @@
#define CGD_COLLECTION_INFO_H
#include "visit_struct/visit_struct.hpp"
+#include "Macros.h"
namespace Common
{
namespace ConstantDatabase
{
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct CdbCollectionInfo
{
std::uint32_t ci_id = static_cast(-1);
@@ -38,7 +39,7 @@ namespace Common
constexpr std::uint32_t getId() const noexcept { return ci_id; }
constexpr bool isValid() const noexcept { return ci_id != static_cast(-1); }
};
-#pragma pack(pop)
+PACK_POP()
}
}
diff --git a/Common/include/ConstantDatabase/Structures/CdbEffectInfo.h b/Common/include/ConstantDatabase/Structures/CdbEffectInfo.h
index b4ac4376..0eb8c800 100644
--- a/Common/include/ConstantDatabase/Structures/CdbEffectInfo.h
+++ b/Common/include/ConstantDatabase/Structures/CdbEffectInfo.h
@@ -3,12 +3,14 @@
#include "visit_struct/visit_struct.hpp"
#include
+#include "Macros.h"
namespace Common
{
namespace ConstantDatabase
{
-#pragma pack(push, 1)
+
+PACK_PUSH(1)
struct CdbEffectInfo
{
std::uint32_t ei_id;
@@ -28,7 +30,7 @@ namespace Common
constexpr std::uint32_t getId() const noexcept { return ei_id; }
constexpr bool isValid() const noexcept { return ei_id != static_cast(-1); }
};
-#pragma pack(pop)
+PACK_POP()
}
}
diff --git a/Common/include/ConstantDatabase/Structures/CdbGradeInfo.h b/Common/include/ConstantDatabase/Structures/CdbGradeInfo.h
index edc6b453..6568d05b 100644
--- a/Common/include/ConstantDatabase/Structures/CdbGradeInfo.h
+++ b/Common/include/ConstantDatabase/Structures/CdbGradeInfo.h
@@ -4,12 +4,13 @@
#include "visit_struct/visit_struct.hpp"
#include
+#include "Macros.h"
namespace Common
{
namespace ConstantDatabase
{
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct CdbGradeInfo
{
std::uint32_t gi_grade = static_cast(-1);
@@ -23,7 +24,7 @@ namespace Common
constexpr std::uint32_t getId() const noexcept { return gi_grade; }
constexpr bool isValid() const noexcept { return gi_grade != static_cast(-1); }
};
-#pragma pack(pop)
+PACK_POP()
}
}
diff --git a/Common/include/ConstantDatabase/Structures/CdbItemInfo.h b/Common/include/ConstantDatabase/Structures/CdbItemInfo.h
index 9978e3c6..cd111859 100644
--- a/Common/include/ConstantDatabase/Structures/CdbItemInfo.h
+++ b/Common/include/ConstantDatabase/Structures/CdbItemInfo.h
@@ -3,13 +3,14 @@
#include "visit_struct/visit_struct.hpp"
#include
+#include "Macros.h"
// This is used for MVSurge, refer to "CdbItemsInfo" for CMV
namespace Common
{
namespace ConstantDatabase
{
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct CdbItemInfo
{
std::uint32_t ii_id = static_cast(-1);
@@ -86,7 +87,7 @@ namespace Common
constexpr bool isValid() const noexcept { return ii_id != static_cast(-1); }
};
-#pragma pack(pop)
+PACK_POP()
}
}
diff --git a/Common/include/ConstantDatabase/Structures/CdbItemWeapon.h b/Common/include/ConstantDatabase/Structures/CdbItemWeapon.h
index df52a5ef..51ae9928 100644
--- a/Common/include/ConstantDatabase/Structures/CdbItemWeapon.h
+++ b/Common/include/ConstantDatabase/Structures/CdbItemWeapon.h
@@ -4,13 +4,14 @@
#include "visit_struct/visit_struct.hpp"
#include "CdbWeaponsInfo.h"
#include "CdbItemInfo.h"
+#include "Macros.h"
namespace Common
{
namespace ConstantDatabase
{
// Common stuff between CdbItem and CdbWeapons to reduce map lookups in Cdb.h and CdbUtils.h
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct CdbItemWeapon
{
std::uint32_t ii_id = static_cast(-1);
@@ -54,7 +55,7 @@ namespace Common
constexpr std::uint32_t getId() const noexcept { return ii_id; }
};
-#pragma pack(pop)
+PACK_POP()
}
}
diff --git a/Common/include/ConstantDatabase/Structures/CdbMapInfo.h b/Common/include/ConstantDatabase/Structures/CdbMapInfo.h
index 7a5f3a35..1d89b0e7 100644
--- a/Common/include/ConstantDatabase/Structures/CdbMapInfo.h
+++ b/Common/include/ConstantDatabase/Structures/CdbMapInfo.h
@@ -3,12 +3,14 @@
#include "visit_struct/visit_struct.hpp"
#include
+#include "Macros.h"
namespace Common
{
namespace ConstantDatabase
{
-#pragma pack(push, 1)
+PACK_PUSH(1)
+
struct CdbMapInfo
{
std::uint32_t mi_id = static_cast(-1);
@@ -58,7 +60,7 @@ namespace Common
constexpr std::uint32_t getId() const noexcept { return mi_id; }
constexpr bool isValid() const noexcept { return mi_id != static_cast(-1); }
};
-#pragma pack(pop)
+PACK_POP()
}
}
diff --git a/Common/include/ConstantDatabase/Structures/CdbMissionEventInfo.h b/Common/include/ConstantDatabase/Structures/CdbMissionEventInfo.h
index 85892a0a..d40f0120 100644
--- a/Common/include/ConstantDatabase/Structures/CdbMissionEventInfo.h
+++ b/Common/include/ConstantDatabase/Structures/CdbMissionEventInfo.h
@@ -2,12 +2,13 @@
#define CGD_EVENTMISSIONINFO_H
#include "visit_struct/visit_struct.hpp"
+#include "Macros.h"
namespace Common
{
namespace ConstantDatabase
{
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct CdbEventMissionInfo
{
std::uint32_t em_id = static_cast(-1);
@@ -20,7 +21,7 @@ namespace Common
constexpr std::uint32_t getId() const noexcept { return em_id; }
constexpr bool isValid() const noexcept { return em_id != static_cast(-1); }
};
-#pragma pack(pop)
+PACK_POP()
}
}
diff --git a/Common/include/ConstantDatabase/Structures/CdbPackageInfos.h b/Common/include/ConstantDatabase/Structures/CdbPackageInfos.h
index 447f691d..ee5eb02c 100644
--- a/Common/include/ConstantDatabase/Structures/CdbPackageInfos.h
+++ b/Common/include/ConstantDatabase/Structures/CdbPackageInfos.h
@@ -2,12 +2,13 @@
#define CDB_PACKAGE_INFOS_H
#include "visit_struct/visit_struct.hpp"
+#include "Macros.h"
namespace Common
{
namespace ConstantDatabase
{
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct CdbItemPackageInfo
{
std::uint32_t ip_id;
@@ -21,10 +22,9 @@ namespace Common
constexpr std::uint32_t getId() const noexcept { return ip_infoid; } // this is what the client sends when buying a weapon/item package
constexpr bool isValid() const noexcept { return ip_infoid != static_cast(-1); }
};
-#pragma pack(pop)
+PACK_POP()
-
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct CdbWeaponPackageInfo
{
std::uint32_t pi_id;
@@ -39,7 +39,7 @@ namespace Common
constexpr std::uint32_t getId() const noexcept { return pi_itemid; } // this is what the client sends when buying a weapon/item package
constexpr bool isValid() const noexcept { return pi_itemid != static_cast(-1); }
};
-#pragma pack(pop)
+PACK_POP()
}
}
diff --git a/Common/include/ConstantDatabase/Structures/CdbRewardInfo.h b/Common/include/ConstantDatabase/Structures/CdbRewardInfo.h
index 5c881db8..447d6057 100644
--- a/Common/include/ConstantDatabase/Structures/CdbRewardInfo.h
+++ b/Common/include/ConstantDatabase/Structures/CdbRewardInfo.h
@@ -3,12 +3,13 @@
#include
#include "visit_struct/visit_struct.hpp"
+#include "Macros.h"
namespace Common
{
namespace ConstantDatabase
{
-#pragma pack(push,1)
+PACK_PUSH(1)
struct CdbRewardInfo
{
std::uint32_t ri_mod = static_cast(-1);
@@ -47,8 +48,7 @@ namespace Common
constexpr std::uint32_t getId() const noexcept { return ri_mod; }
constexpr bool isValid() const noexcept { return ri_mod != static_cast(-1); }
};
-#pragma pack(pop)
-
+PACK_POP()
}
}
diff --git a/Common/include/ConstantDatabase/Structures/CdbUpgradeInfo.h b/Common/include/ConstantDatabase/Structures/CdbUpgradeInfo.h
index 2d3403f6..c77a5db7 100644
--- a/Common/include/ConstantDatabase/Structures/CdbUpgradeInfo.h
+++ b/Common/include/ConstantDatabase/Structures/CdbUpgradeInfo.h
@@ -3,12 +3,13 @@
#include "visit_struct/visit_struct.hpp"
#include
+#include "Macros.h"
namespace Common
{
namespace ConstantDatabase
{
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct CdbUpgradeInfo
{
std::uint32_t ui_id;
@@ -29,7 +30,7 @@ namespace Common
constexpr std::uint32_t getId() const noexcept { return ui_itemid; }
constexpr bool isValid() const noexcept { return ui_itemid != static_cast(-1); }
};
-#pragma pack(pop)
+PACK_POP()
}
}
diff --git a/Common/include/ConstantDatabase/Structures/CdbVendor.h b/Common/include/ConstantDatabase/Structures/CdbVendor.h
index 588ef4ab..a039ba49 100644
--- a/Common/include/ConstantDatabase/Structures/CdbVendor.h
+++ b/Common/include/ConstantDatabase/Structures/CdbVendor.h
@@ -3,12 +3,13 @@
#include "visit_struct/visit_struct.hpp"
#include
+#include "Macros.h"
namespace Common
{
namespace ConstantDatabase
{
-#pragma pack(push,1)
+PACK_PUSH(1)
struct CdbVendorInfo
{
std::uint32_t vi_id = static_cast(-1);
@@ -44,8 +45,8 @@ namespace Common
constexpr std::uint32_t getId() const noexcept { return vi_id; }
constexpr bool isValid() const noexcept { return vi_id != static_cast(-1); }
};
-#pragma pack(pop)
- }
+PACK_POP()
+ }
}
VISITABLE_STRUCT(Common::ConstantDatabase::CdbVendorInfo,
diff --git a/Common/include/ConstantDatabase/Structures/CdbWeaponsInfo.h b/Common/include/ConstantDatabase/Structures/CdbWeaponsInfo.h
index 4150134b..1a95d4d1 100644
--- a/Common/include/ConstantDatabase/Structures/CdbWeaponsInfo.h
+++ b/Common/include/ConstantDatabase/Structures/CdbWeaponsInfo.h
@@ -3,12 +3,13 @@
#include "visit_struct/visit_struct.hpp"
#include
+#include "Macros.h"
namespace Common
{
namespace ConstantDatabase
{
-#pragma pack(push, 1)
+PACK_PUSH(1)
struct CdbWeaponInfo
{
std::uint32_t ii_id = static_cast(-1);
@@ -84,8 +85,7 @@ namespace Common
constexpr std::uint32_t getId() const noexcept { return ii_id; }
constexpr bool isValid() const noexcept { return ii_id != static_cast(-1); }
};
-
-#pragma pack(pop)
+PACK_POP()
}
}
diff --git a/Common/include/ConstantDatabase/Structures/SetItemInfo.h b/Common/include/ConstantDatabase/Structures/SetItemInfo.h
index 0e72664f..aa3eb2da 100644
--- a/Common/include/ConstantDatabase/Structures/SetItemInfo.h
+++ b/Common/include/ConstantDatabase/Structures/SetItemInfo.h
@@ -2,13 +2,14 @@
#define CGD_SET_ITEM_INFO_H
#include "visit_struct/visit_struct.hpp"
-
+#include "Macros.h"
+#include
namespace Common
{
namespace ConstantDatabase
{
-#pragma pack(push,1)
+PACK_PUSH(1)
struct SetItemInfo
{
std::uint32_t si_id = static_cast(-1);
@@ -26,11 +27,11 @@ namespace Common
constexpr std::uint32_t getId() const noexcept { return si_id; }
constexpr bool isValid() const noexcept { return si_id != static_cast(-1); }
};
-#pragma pack(pop)
+PACK_POP()
}
}
VISITABLE_STRUCT(Common::ConstantDatabase::SetItemInfo, si_id, si_hair, si_face, si_top, si_under, si_pants, si_arms, si_boots, si_acce_A, si_acce_B, si_acce_C);
-#endif
\ No newline at end of file
+#endif
diff --git a/Common/include/Enums/GameEnums.h b/Common/include/Enums/GameEnums.h
index 1c4d81fb..81e70aaa 100644
--- a/Common/include/Enums/GameEnums.h
+++ b/Common/include/Enums/GameEnums.h
@@ -1,4 +1,4 @@
- #ifndef COMMON_GAME_ENUMS_H
+#ifndef COMMON_GAME_ENUMS_H
#define COMMON_GAME_ENUMS_H
#include
@@ -50,11 +50,15 @@ namespace Common
MG = 14,
BAZOOKA = 15,
GRENADE = 16,
-
SET = 17,
MAX_ITEMTYPE = 18
};
+ inline bool isWeapon(ItemType itemType)
+ {
+ return itemType >= ItemType::MELEE && itemType <= ItemType::GRENADE;
+ }
+
enum PlayerState : std::uint32_t
{
STATE_EXIT = 0,
@@ -125,4 +129,4 @@ namespace Common
}
}
-#endif
\ No newline at end of file
+#endif
diff --git a/Common/include/Network/Packet.h b/Common/include/Network/Packet.h
index 212d2d06..791cdb3b 100644
--- a/Common/include/Network/Packet.h
+++ b/Common/include/Network/Packet.h
@@ -11,7 +11,7 @@
#include "../../include/Network/Packet.h"
#include "../../include/Enums/MiscellaneousEnums.h"
#include "../../include/Utils/Parser.h"
-
+#include
#include
diff --git a/Common/include/Network/Session.h b/Common/include/Network/Session.h
index 2c2466a2..606d3441 100644
--- a/Common/include/Network/Session.h
+++ b/Common/include/Network/Session.h
@@ -16,6 +16,7 @@
#include "Packet.h"
#include "SessionIdManager.h"
#include
+#include "../Enums/GameEnums.h"
#ifdef ENABLE_BENCHMARKING
#include
diff --git a/Common/include/Protocol/CommandHeader.h b/Common/include/Protocol/CommandHeader.h
index 3242cee6..55c5c015 100644
--- a/Common/include/Protocol/CommandHeader.h
+++ b/Common/include/Protocol/CommandHeader.h
@@ -3,12 +3,13 @@
#include
#include
+#include "Macros.h"
namespace Common
{
namespace Protocol
{
-#pragma pack(push, 1)
+PACK_PUSH(1)
class CommandHeader
{
private:
@@ -50,7 +51,7 @@ namespace Common
std::uint32_t getOption() const;
};
-#pragma pack(pop)
+PACK_POP()
}
}
diff --git a/Common/include/Protocol/TcpHeader.h b/Common/include/Protocol/TcpHeader.h
index f70282f3..865850d5 100644
--- a/Common/include/Protocol/TcpHeader.h
+++ b/Common/include/Protocol/TcpHeader.h
@@ -3,12 +3,13 @@
#include
#include
+#include "Macros.h"
namespace Common
{
namespace Protocol
{
-#pragma pack(push, 1)
+PACK_PUSH(1)
class TcpHeader
{
private:
@@ -42,8 +43,7 @@ namespace Common
std::uint32_t getCrypt() const;
};
-#pragma pack(pop)
-
+PACK_POP()
}
}
diff --git a/Common/include/Utils/Constants.h b/Common/include/Utils/Constants.h
index 411f0261..0655778b 100644
--- a/Common/include/Utils/Constants.h
+++ b/Common/include/Utils/Constants.h
@@ -43,9 +43,9 @@ namespace Common
constexpr inline std::uint16_t maxClanRooms = 30;
constexpr inline std::uint16_t maxPartiesPerClan = 4;
constexpr inline std::uint32_t clanRoomNumberStart = 151;
- constexpr inline std::uint16_t matchBaseExp = 120;
+ constexpr inline std::uint16_t matchBaseExp = 80;
constexpr inline std::uint16_t matchBaseMp = 150;
- constexpr inline std::uint16_t maxExpAndMpPerMatch = 1500;
+ constexpr inline std::uint16_t maxExpAndMpPerMatch = 2000;
constexpr inline std::uint16_t clanBaseContribution = 100;
constexpr inline std::uint32_t goldLevelBox = 5336571;
constexpr inline std::uint32_t silverLevelBox = 5336570;
diff --git a/Common/include/Utils/Macros.h b/Common/include/Utils/Macros.h
new file mode 100644
index 00000000..762fc855
--- /dev/null
+++ b/Common/include/Utils/Macros.h
@@ -0,0 +1,18 @@
+#ifndef MACROS_UTILS_CUSTOM_H
+#define MACROS_UTILS_CUSTOM_H
+
+
+#if defined(_MSC_VER)
+#define PACK_PUSH(n) __pragma(pack(push, n))
+#define PACK_POP() __pragma(pack(pop))
+#elif defined(__GNUC__) || defined(__clang__)
+#define STRINGIFY(x) #x
+#define PACK_PUSH(n) _Pragma(STRINGIFY(pack(push, n)))
+#define PACK_POP() _Pragma("pack(pop)")
+#else
+#define PACK_PUSH(n)
+#define PACK_POP()
+#endif
+
+
+#endif
\ No newline at end of file
diff --git a/Common/include/Utils/Utils.h b/Common/include/Utils/Utils.h
index 2ec0eeac..ce2b5a9f 100644
--- a/Common/include/Utils/Utils.h
+++ b/Common/include/Utils/Utils.h
@@ -22,6 +22,13 @@
#define SEND_DEBUG_MESSAGE(msg, session) (void)0
#endif
+#ifdef _WIN32
+#include
+#else
+#include
+#endif
+
+
namespace Common
{
namespace Utils
@@ -101,7 +108,18 @@ namespace Common
duration_cast(system_clock::now().time_since_epoch()).count()
);
}
+
+
+ inline void setConsoleTitle(const std::wstring& title)
+ {
+ #ifdef _WIN32
+ SetConsoleTitleW(title.c_str());
+ #else
+ std::string utf8title(title.begin(), title.end());
+ std::cout << "\033]0;" << utf8title << "\007";
+ #endif
+ }
}
}
-#endif
\ No newline at end of file
+#endif
diff --git a/Common/src/Network/Session.cpp b/Common/src/Network/Session.cpp
index c2e38e8a..90e47307 100644
--- a/Common/src/Network/Session.cpp
+++ b/Common/src/Network/Session.cpp
@@ -4,7 +4,9 @@
#include