Skip to content

Commit 493a124

Browse files
Merge branch 'master' into sidequest/frontier-distance-static-blockers
2 parents e59dcfb + 9d51240 commit 493a124

10 files changed

Lines changed: 114 additions & 4 deletions

File tree

Jenkinsfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pipeline {
4949
options {
5050
buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '14', daysToKeepStr: '14', numToKeepStr: '180'))
5151
disableConcurrentBuilds()
52+
disableResume()
5253
skipDefaultCheckout(true)
5354
}
5455

data/RTTR/texte/keyboardlayout.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ F9:................... Readme
3131
F10:.................. Settings (UI, ...)
3232
F11:.................. Musicplayer
3333
F12:.................. Options window
34+
Print:................ Take screenshot
3435

3536
Post office:
3637

doc/lua/functions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ Closes a spot kicking any player or AI there.
238238

239239
**SetAI(level)**
240240
Add an AI or change its difficulty.
241+
Switching a slot to an AI assigns the AI's default name. If a custom name should be kept, call `SetName(name)` after `SetAI(level)`.
241242

242243
**SetName(name)**
243244
Change the player's name.

external/libutil

libs/s25main/Replay.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,15 @@ bool Replay::StopRecording()
7272
isRecording_ = false;
7373
file_.Close();
7474

75+
// Remove empty replay recordings. They are mostly produced when a game is aborted
76+
// during startup, for example after an early script error.
77+
if(lastGF_ == 0)
78+
{
79+
boost::system::error_code ec;
80+
boost::filesystem::remove(filepath_, ec);
81+
return !ec;
82+
}
83+
7584
BinaryFile file;
7685
if(!file.Open(filepath_, OpenFileMode::Read))
7786
return false;

libs/s25main/network/GameClient.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,10 @@ bool GameClient::OnGameMessage(const GameMessage_Map_Info& msg)
928928
OnError(ClientError::InvalidMap);
929929
return true;
930930
}
931-
mapinfo.filepath = RTTRCONFIG.ExpandPath(s25::folders::mapsPlayed) / portFilename;
931+
const auto targetPath =
932+
RTTRCONFIG.ExpandPath((msg.mt == MapType::Savegame) ? s25::folders::save : s25::folders::mapsPlayed);
933+
bfs::create_directories(targetPath);
934+
mapinfo.filepath = targetPath / portFilename;
932935
mapinfo.type = msg.mt;
933936

934937
// lua script file path

libs/s25main/network/GameServer.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -938,10 +938,12 @@ bool GameServer::OnGameMessage(const GameMessage_Server_Password& msg)
938938
} else
939939
playerInfos[msg.senderPlayerID].isHost = false;
940940

941-
player->sendMsgAsync(new GameMessage_Server_Password(passwordok));
942-
943941
if(passwordok == "false")
942+
{
943+
player->sendMsg(GameMessage_Server_Password(passwordok));
944944
KickPlayer(msg.senderPlayerID, KickReason::WrongPassword, __LINE__);
945+
} else
946+
player->sendMsgAsync(new GameMessage_Server_Password(passwordok));
945947
return true;
946948
}
947949

tests/mockupDrivers/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,18 @@ add_library(audioMockup STATIC MockupAudioDriver.h MockupAudioDriver.cpp)
1111
target_link_libraries(audioMockup PUBLIC audiodrv turtle::turtle)
1212
target_include_directories(audioMockup INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/..)
1313
enable_warnings(audioMockup)
14+
15+
# Turtle does not support override for mocked methods, so let's disable the warning
16+
include(CheckAndAddWarnings)
17+
18+
check_warning(CXX "-Wno-suggest-override" CXX_WARNING__Wno_suggest_override_SUPPORTED)
19+
20+
if (CXX_WARNING__Wno_suggest_override_SUPPORTED)
21+
add_library(no_suggest_override INTERFACE)
22+
target_compile_options(no_suggest_override INTERFACE
23+
$<$<COMPILE_LANGUAGE:CXX>:-Wno-suggest-override>
24+
)
25+
26+
target_link_libraries(videoMockup PRIVATE no_suggest_override)
27+
target_link_libraries(audioMockup PRIVATE no_suggest_override)
28+
endif()

tests/s25Main/integration/testSerialization.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,26 @@ struct ReplayMapFixture
398398
}
399399
};
400400

401+
BOOST_FIXTURE_TEST_CASE(EmptyReplayRecordingIsRemoved, ReplayMapFixture)
402+
{
403+
Replay replay;
404+
for(const BasePlayerInfo& player : players)
405+
replay.AddPlayer(player);
406+
replay.ggs.speed = GameSpeed::VeryFast;
407+
408+
TmpFile tmpFile(".rpl");
409+
BOOST_TEST_REQUIRE(tmpFile.isValid());
410+
tmpFile.close();
411+
bfs::remove(tmpFile.filePath);
412+
413+
BOOST_TEST_REQUIRE(replay.StartRecording(tmpFile.filePath, map, 42));
414+
BOOST_TEST_REQUIRE(replay.IsRecording());
415+
BOOST_TEST(replay.GetLastGF() == 0u);
416+
417+
BOOST_TEST_REQUIRE(replay.StopRecording());
418+
BOOST_TEST_REQUIRE(!replay.IsRecording());
419+
BOOST_TEST(!bfs::exists(tmpFile.filePath));
420+
}
401421
BOOST_FIXTURE_TEST_CASE(ReplayWithMap, ReplayMapFixture)
402422
{
403423
Replay replay;

tests/s25Main/network/testGameClient.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,36 @@ BOOST_DATA_TEST_CASE(ClientFollowsConnectProtocol, usesLuaScriptValues, usesLuaS
244244
}
245245
}
246246

247+
BOOST_AUTO_TEST_CASE(ClientStoresReceivedSavegamesInSaveFolder)
248+
{
249+
rttr::test::TmpFolder testUserData;
250+
rttr::test::ConfigOverride userDataOverride("USERDATA", testUserData);
251+
252+
GameClient client;
253+
GameMessageInterface& clientMsgInterface = client;
254+
TestServer server;
255+
const auto serverPort = server.tryListen();
256+
BOOST_TEST_REQUIRE(serverPort >= 0);
257+
258+
BOOST_TEST_REQUIRE(client.Connect("localhost", rttr::test::randString(10), rttr::test::randomEnum<ServerType>(),
259+
serverPort, false, false));
260+
clientMsgInterface.OnGameMessage(GameMessage_Player_Id(1));
261+
client.GetMainPlayer().sendQueue.clear();
262+
clientMsgInterface.OnGameMessage(GameMessage_Server_TypeOK(GameMessage_Server_TypeOK::StatusCode::Ok, ""));
263+
client.GetMainPlayer().sendQueue.clear();
264+
clientMsgInterface.OnGameMessage(GameMessage_Server_Password("true"));
265+
client.GetMainPlayer().sendQueue.clear();
266+
267+
const auto expectedSavePath = RTTRCONFIG.ExpandPath(s25::folders::save) / "received.sav";
268+
269+
clientMsgInterface.OnGameMessage(GameMessage_Map_Info("received.sav", MapType::Savegame, 1, 1, 0, 0));
270+
const auto msg = boost::dynamic_pointer_cast<GameMessage_MapRequest>(client.GetMainPlayer().sendQueue.pop());
271+
BOOST_TEST_REQUIRE(msg);
272+
BOOST_TEST(!msg->requestInfo);
273+
BOOST_TEST(client.GetMapType() == MapType::Savegame);
274+
BOOST_TEST(client.GetMapPath() == expectedSavePath);
275+
}
276+
247277
BOOST_AUTO_TEST_CASE(ClientDetectsMapBufferOverflow)
248278
{
249279
rttr::test::LogAccessor _suppressLogOutput;
@@ -287,6 +317,34 @@ BOOST_AUTO_TEST_CASE(ClientDetectsMapBufferOverflow)
287317
BOOST_TEST(client.GetState() == ClientState::Stopped);
288318
}
289319

320+
BOOST_AUTO_TEST_CASE(ClientReportsWrongPasswordResponse)
321+
{
322+
GameClient client;
323+
GameMessageInterface& clientMsgInterface = client;
324+
MockClientInterface callbacks;
325+
client.SetInterface(&callbacks);
326+
TestServer server;
327+
const auto serverPort = server.tryListen();
328+
BOOST_TEST_REQUIRE(serverPort >= 0);
329+
const auto serverType = rttr::test::randomEnum<ServerType>();
330+
mock::sequence s;
331+
MOCK_EXPECT(callbacks.CI_NextConnectState).in(s).with(ConnectState::Initiated).once();
332+
MOCK_EXPECT(callbacks.CI_NextConnectState).in(s).with(ConnectState::VerifyServer).once();
333+
MOCK_EXPECT(callbacks.CI_NextConnectState).in(s).with(ConnectState::QueryPw).once();
334+
MOCK_EXPECT(callbacks.CI_Error).in(s).with(ClientError::WrongPassword).once();
335+
336+
BOOST_TEST_REQUIRE(client.Connect("localhost", rttr::test::randString(10), serverType, serverPort, false, false));
337+
clientMsgInterface.OnGameMessage(GameMessage_Player_Id(1));
338+
clientMsgInterface.OnGameMessage(GameMessage_Server_TypeOK(GameMessage_Server_TypeOK::StatusCode::Ok, ""));
339+
BOOST_TEST_REQUIRE(boost::dynamic_pointer_cast<GameMessage_Server_Type>(client.GetMainPlayer().sendQueue.pop()));
340+
BOOST_TEST_REQUIRE(
341+
boost::dynamic_pointer_cast<GameMessage_Server_Password>(client.GetMainPlayer().sendQueue.pop()));
342+
343+
clientMsgInterface.OnGameMessage(GameMessage_Server_Password("false"));
344+
345+
BOOST_TEST(client.GetState() == ClientState::Stopped);
346+
}
347+
290348
using namespace std::chrono_literals;
291349

292350
BOOST_AUTO_TEST_CASE(CanSetNewSpeed)

0 commit comments

Comments
 (0)