Skip to content

Commit 1342238

Browse files
authored
Merge c2841ed into 895dafb
2 parents 895dafb + c2841ed commit 1342238

20 files changed

Lines changed: 1562 additions & 89 deletions

.github/workflows/core_windows_build.yml

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ name: Windows Build (MSVC)
33
permissions:
44
contents: read
55

6+
env:
7+
OPENSSL_VERSION: 3.6.3
8+
OPENSSL_SHA512: 120A2E9A3E8B961484CB94D52F85D48DC2C8AF777B5B3B9E26BF49B4408797281F7C0FB2D543FD7796B3C3232ADFAA0F675E7122C0E5C4225B3B02E767197AC6
9+
610
on:
711
push:
812
branches: [master, devel]
@@ -34,20 +38,50 @@ jobs:
3438
id: cache-openssl
3539
uses: actions/cache@v4
3640
with:
37-
path: |
38-
C:\Program Files\OpenSSL
39-
C:\Program Files\OpenSSL-Win64
40-
key: ${{ runner.os }}-openssl-v1
41+
path: C:\Program Files\OpenSSL-Win64
42+
key: ${{ runner.os }}-openssl-${{ env.OPENSSL_VERSION }}-v1
4143

4244

4345
- name: Install full OpenSSL (developer)
4446
if: steps.cache-openssl.outputs.cache-hit != 'true'
4547
shell: powershell
4648
run: |
47-
Write-Host "Installing latest full OpenSSL for development..."
48-
choco upgrade openssl -y --no-progress
49-
$ver = & openssl version
50-
Write-Host "Installed OpenSSL version: $ver"
49+
$versionSlug = $env:OPENSSL_VERSION.Replace('.', '_')
50+
$installer = Join-Path $env:RUNNER_TEMP "Win64OpenSSL-$versionSlug.exe"
51+
$url = "https://slproweb.com/download/Win64OpenSSL-$versionSlug.exe"
52+
53+
Write-Host "Downloading OpenSSL $env:OPENSSL_VERSION for development..."
54+
curl.exe --fail --location --retry 3 --output $installer $url
55+
if ($LASTEXITCODE -ne 0) {
56+
throw "OpenSSL download failed with exit code $LASTEXITCODE"
57+
}
58+
59+
$actualHash = (Get-FileHash -Algorithm SHA512 $installer).Hash
60+
if ($actualHash -ne $env:OPENSSL_SHA512) {
61+
throw "OpenSSL installer checksum mismatch: $actualHash"
62+
}
63+
64+
$installArgs = '/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- /DIR="C:\Program Files\OpenSSL-Win64"'
65+
$process = Start-Process -FilePath $installer -ArgumentList $installArgs -Wait -PassThru
66+
if ($process.ExitCode -ne 0) {
67+
throw "OpenSSL installer failed with exit code $($process.ExitCode)"
68+
}
69+
70+
71+
- name: Verify OpenSSL major version
72+
shell: powershell
73+
run: |
74+
$openssl = "C:\Program Files\OpenSSL-Win64\bin\openssl.exe"
75+
76+
if (-not (Test-Path $openssl)) {
77+
throw "OpenSSL executable not found at $openssl"
78+
}
79+
80+
$version = & $openssl version
81+
Write-Host "Installed OpenSSL version: $version"
82+
if ($version -notmatch '^OpenSSL 3\.') {
83+
throw "Windows CI requires OpenSSL 3.x, found: $version"
84+
}
5185
5286
5387
- name: Setup Windows 10 SDK
@@ -59,18 +93,13 @@ jobs:
5993
- name: Configure OpenSSL environment
6094
shell: bash
6195
run: |
62-
if [ -d "C:/Program Files/OpenSSL/lib/VC" ]; then
63-
echo "OPENSSL_ROOT_DIR=C:/Program Files/OpenSSL" >> $GITHUB_ENV
64-
echo "OPENSSL_INCLUDE_DIR=C:/Program Files/OpenSSL/include" >> $GITHUB_ENV
65-
echo "OPENSSL_CRYPTO_LIBRARY=C:/Program Files/OpenSSL/lib/VC/libcrypto64MT.lib" >> $GITHUB_ENV
66-
echo "OPENSSL_SSL_LIBRARY=C:/Program Files/OpenSSL/lib/VC/libssl64MT.lib" >> $GITHUB_ENV
67-
elif [ -d "C:/Program Files/OpenSSL-Win64/lib/VC" ]; then
96+
if [ -d "C:/Program Files/OpenSSL-Win64/lib/VC" ]; then
6897
echo "OPENSSL_ROOT_DIR=C:/Program Files/OpenSSL-Win64" >> $GITHUB_ENV
6998
echo "OPENSSL_INCLUDE_DIR=C:/Program Files/OpenSSL-Win64/include" >> $GITHUB_ENV
7099
echo "OPENSSL_CRYPTO_LIBRARY=C:/Program Files/OpenSSL-Win64/lib/VC/libcrypto64MT.lib" >> $GITHUB_ENV
71100
echo "OPENSSL_SSL_LIBRARY=C:/Program Files/OpenSSL-Win64/lib/VC/libssl64MT.lib" >> $GITHUB_ENV
72101
else
73-
echo "::error::OpenSSL not found in either expected location"
102+
echo "::error::OpenSSL developer libraries not found"
74103
exit 1
75104
fi
76105

CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ option(PCH "Enable precompiled headers" ON)
6464
option(DEBUG "Enable debug build (only on non IDEs)" OFF)
6565
option(WITHOUT_GIT "Disable Git revision detection" OFF)
6666
option(BUILD_AH_SERVICE "Build the out-of-process auction-house service" ON)
67+
option(BUILD_TESTING "Build focused regression tests" OFF)
6768
#==================================================================================
6869
message("")
6970
message(
@@ -146,6 +147,11 @@ endif()
146147

147148
find_package(Threads REQUIRED)
148149
find_package(OpenSSL 3.0 REQUIRED)
150+
# OpenSSL 4.x support is intentionally deferred until the OpenSSL 4.2 LTS migration.
151+
if(OPENSSL_VERSION VERSION_GREATER_EQUAL "4.0.0")
152+
message(FATAL_ERROR
153+
"Unsupported OpenSSL ${OPENSSL_VERSION}: MaNGOS currently requires >=3.0.0 and <4.0.0")
154+
endif()
149155
find_package(MySQL REQUIRED)
150156

151157
# =============================================================================
@@ -218,6 +224,11 @@ else()
218224
message(WARNING "Source directory 'src' not found. Nothing to build.")
219225
endif()
220226

227+
if(BUILD_TESTING)
228+
enable_testing()
229+
add_subdirectory(tests)
230+
endif()
231+
221232
# =============================================================================
222233
# Final info and summary
223234
# =============================================================================

src/game/Server/WorldSession.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ bool WorldSessionFilter::Process(WorldPacket* packet)
147147
/// WorldSession constructor
148148
WorldSession::WorldSession(uint32 id, std::shared_ptr<WorldSocket> sock, AccountTypes sec, time_t mute_time, LocaleConstant locale)
149149
: m_muteTime(mute_time),
150-
_player(NULL), m_Socket(std::move(sock)), _security(sec), _accountId(id), _warden(NULL), _build(0), _logoutTime(0),
150+
_player(NULL), m_OwningSocket(sock), m_Socket(std::move(sock)), _security(sec), _accountId(id), _warden(NULL), _build(0), _logoutTime(0),
151151
m_inQueue(false), m_playerLoading(false), m_playerLogout(false), m_playerRecentlyLogout(false), m_playerSave(false),
152152
m_sessionDbcLocale(sWorld.GetAvailableDbcLocale(locale)), m_sessionDbLocaleIndex(sObjectMgr.GetIndexForLocale(locale)),
153153
m_latency(0), m_clientTimeDelay(0), m_tutorialState(TUTORIALDATA_UNCHANGED), m_npcWatchLastGuid()
@@ -161,6 +161,11 @@ WorldSession::WorldSession(uint32 id, std::shared_ptr<WorldSocket> sock, Account
161161
/// WorldSession destructor
162162
WorldSession::~WorldSession()
163163
{
164+
if (std::shared_ptr<WorldSocket> socket = m_OwningSocket.lock())
165+
{
166+
socket->DetachSessionAndWait();
167+
}
168+
164169
///- unload player if not unloaded
165170
if (_player)
166171
{

src/game/Server/WorldSession.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,7 @@ class WorldSession
893893
void LogUnprocessedTail(WorldPacket* packet);
894894

895895
Player* _player;
896+
std::weak_ptr<WorldSocket> m_OwningSocket;
896897
std::shared_ptr<WorldSocket> m_Socket;
897898
std::string m_Address;
898899

src/game/Server/WorldSocket.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ std::atomic<uint32> WorldSocket::s_openConnections{0};
7575
#endif
7676

7777
WorldSocket::WorldSocket()
78-
: m_Session(0),
79-
m_closed(false),
78+
: m_closed(false),
8079
m_recvBuf(),
8180
m_headerPending(false),
8281
m_recvOpcode(0),
@@ -98,16 +97,19 @@ WorldSocket::~WorldSocket()
9897
#endif
9998
}
10099

101-
WorldSession* WorldSocket::GetSession()
100+
WorldSocket::SessionLease WorldSocket::GetSession()
102101
{
103-
std::lock_guard<std::mutex> guard(m_SessionLock);
104-
return m_Session;
102+
return m_session.acquire();
105103
}
106104

107105
void WorldSocket::SetSession(WorldSession* session)
108106
{
109-
std::lock_guard<std::mutex> guard(m_SessionLock);
110-
m_Session = session;
107+
m_session.publish(session);
108+
}
109+
110+
void WorldSocket::DetachSessionAndWait()
111+
{
112+
m_session.detachAndWait();
111113
}
112114

113115
void WorldSocket::CloseSocket()
@@ -117,7 +119,7 @@ void WorldSocket::CloseSocket()
117119
return;
118120
}
119121

120-
SetSession(NULL);
122+
m_session.detach();
121123

122124
if (m_closer)
123125
{
@@ -185,7 +187,7 @@ std::vector<uint8_t> WorldSocket::onConnect()
185187
void WorldSocket::onClose()
186188
{
187189
m_closed.store(true);
188-
SetSession(NULL);
190+
m_session.detach();
189191
}
190192

191193
std::vector<uint8_t> WorldSocket::onData(const uint8_t* data, size_t len)
@@ -287,7 +289,9 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
287289
sLog.outWorldPacketDump(0, new_pct->GetOpcode(), new_pct->GetOpcodeName(), new_pct, true);
288290
}
289291

290-
WorldSession* session = GetSession();
292+
// HandlePing acquires its own narrow leases. In particular, do not keep a
293+
// ProcessIncoming lease alive across its close-capable paths.
294+
SessionLease session = opcode == CMSG_PING ? SessionLease{} : GetSession();
291295

292296
try
293297
{
@@ -304,7 +308,7 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
304308
#ifdef ENABLE_ELUNA
305309
if (Eluna* e = sWorld.GetEluna())
306310
{
307-
if (!e->OnPacketReceive(session, *new_pct))
311+
if (!e->OnPacketReceive(session.get(), *new_pct))
308312
{
309313
return 0;
310314
}
@@ -316,12 +320,12 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
316320
#ifdef ENABLE_ELUNA
317321
if (Eluna* e = sWorld.GetEluna())
318322
{
319-
e->OnPacketReceive(session, *new_pct);
323+
e->OnPacketReceive(session.get(), *new_pct);
320324
}
321325
#endif /* ENABLE_ELUNA */
322326
return 0;
323327
default:
324-
if (session != NULL)
328+
if (session)
325329
{
326330
aptr.release();
327331
session->QueuePacket(new_pct);
@@ -591,7 +595,7 @@ int WorldSocket::HandlePing(WorldPacket& recvPacket)
591595

592596
if (max_count && m_OverSpeedPings > max_count)
593597
{
594-
WorldSession* session = GetSession();
598+
SessionLease session = GetSession();
595599
if (session && session->GetSecurity() == SEC_PLAYER)
596600
{
597601
sLog.outError("WorldSocket::HandlePing: Player kicked for overspeeded pings address = %s",
@@ -606,7 +610,7 @@ int WorldSocket::HandlePing(WorldPacket& recvPacket)
606610
}
607611
}
608612

609-
WorldSession* session = GetSession();
613+
SessionLease session = GetSession();
610614
if (session)
611615
{
612616
session->SetLatency(latency);

src/game/Server/WorldSocket.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "Common.h"
3535
#include "Auth/AuthCrypt.h"
3636
#include "Auth/Sha1.h"
37+
#include "Threading/LeasedPtr.h"
3738

3839
#include "net/ISession.hpp"
3940

@@ -92,21 +93,24 @@ class WorldSocket : public net::ISession
9293

9394
private:
9495

96+
friend class WorldSession;
97+
using SessionLease = LeasedPtr<WorldSession>::Lease;
98+
9599
std::vector<uint8_t> EncodePacket(const WorldPacket& pct);
96100
int ProcessIncoming(WorldPacket* new_pct);
97101
int HandleAuthSession(WorldPacket& recvPacket);
98102
int HandlePing(WorldPacket& recvPacket);
99103

100-
WorldSession* GetSession();
101-
void SetSession(WorldSession* session);
104+
SessionLease GetSession();
105+
void SetSession(WorldSession* session);
106+
void DetachSessionAndWait();
102107

103108
std::string m_Address;
104109

105110
AuthCrypt m_Crypt;
106111
std::mutex m_CryptSendLock; ///< serialises header encryption on send
107112

108-
std::mutex m_SessionLock;
109-
WorldSession* m_Session;
113+
LeasedPtr<WorldSession> m_session;
110114

111115
std::atomic<bool> m_closed;
112116

src/mangosd/mangosd.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ int main(int argc, char** argv)
328328
if (!providerManager.IsInitialized())
329329
{
330330
Log::WaitBeforeContinueIfNeed();
331-
return 0;
331+
return 1;
332332
}
333333

334334
///- Set progress bars show mode

src/realmd

Submodule realmd updated 1 file

0 commit comments

Comments
 (0)