2018-01-05 20:21:07 +03:00
/*
* NetPacksLobbyServer.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
2023-02-12 09:23:39 +02:00
#include "LobbyNetPackVisitors.h"
2018-01-05 20:21:07 +03:00
#include "CVCMIServer.h"
#include "CGameHandler.h"
#include "../lib/StartInfo.h"
2024-01-31 00:17:40 +02:00
#include "../lib/CRandomGenerator.h"
2023-06-25 22:28:24 +03:00
#include "../lib/campaign/CampaignState.h"
2024-07-21 10:49:40 +00:00
#include "../lib/entities/faction/CTownHandler.h"
#include "../lib/entities/faction/CFaction.h"
2023-11-18 16:34:18 +02:00
#include "../lib/serializer/Connection.h"
2024-04-30 01:52:49 +02:00
#include "../lib/mapping/CMapInfo.h"
#include "../lib/mapping/CMapHeader.h"
2024-10-31 21:57:20 +01:00
#include "../lib/filesystem/Filesystem.h"
2018-01-05 20:21:07 +03:00
2023-02-12 09:23:39 +02:00
void ClientPermissionsCheckerNetPackVisitor :: visitForLobby ( CPackForLobby & pack )
2018-01-05 20:21:07 +03:00
{
2023-02-12 09:23:39 +02:00
if ( pack . isForServer ())
{
2025-03-01 17:50:52 +00:00
result = srv . isClientHost ( connection -> connectionID );
2023-02-12 09:23:39 +02:00
}
2018-01-05 20:21:07 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyOnServerAfterAnnounceNetPackVisitor :: visitForLobby ( CPackForLobby & pack )
2018-01-05 20:21:07 +03:00
{
2024-06-24 03:23:26 +02:00
// Propagate options after every CLobbyPackToServer
2023-02-12 09:23:39 +02:00
if ( pack . isForServer ())
{
srv . updateAndPropagateLobbyState ();
}
2018-01-05 20:21:07 +03:00
}
2023-02-12 09:23:39 +02:00
void ClientPermissionsCheckerNetPackVisitor :: visitLobbyClientConnected ( LobbyClientConnected & pack )
2018-01-05 20:21:07 +03:00
{
2024-02-03 19:08:45 +02:00
result = srv . getState () == EServerState :: LOBBY ;
2018-01-05 20:21:07 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyOnServerNetPackVisitor :: visitLobbyClientConnected ( LobbyClientConnected & pack )
2018-01-05 20:21:07 +03:00
{
2024-05-29 20:08:32 +00:00
auto compatibleVersion = std :: min ( pack . version , ESerializationVersion :: CURRENT );
2025-03-01 17:50:52 +00:00
connection -> setSerializationVersion ( compatibleVersion );
2024-05-29 20:08:32 +00:00
2025-03-01 17:50:52 +00:00
srv . clientConnected ( connection , pack . names , pack . uuid , pack . mode );
2024-05-29 20:08:32 +00:00
2018-01-05 20:21:07 +03:00
// Server need to pass some data to newly connected client
2025-03-01 17:50:52 +00:00
pack . clientId = connection -> connectionID ;
2023-02-12 09:23:39 +02:00
pack . mode = srv . si -> mode ;
pack . hostClientId = srv . hostClientId ;
2024-05-29 20:08:32 +00:00
pack . version = compatibleVersion ;
2023-02-12 09:23:39 +02:00
result = true ;
2018-01-05 20:21:07 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyOnServerAfterAnnounceNetPackVisitor :: visitLobbyClientConnected ( LobbyClientConnected & pack )
2018-01-05 20:21:07 +03:00
{
2023-02-12 09:23:39 +02:00
srv . updateAndPropagateLobbyState ();
2023-12-26 18:29:13 +02:00
// FIXME: what is this??? We do NOT support reconnection into ongoing game - at the very least queries and battles are NOT serialized
// if(srv.getState() == EServerState::GAMEPLAY)
// {
// //immediately start game
// std::unique_ptr<LobbyStartGame> startGameForReconnectedPlayer(new LobbyStartGame);
// startGameForReconnectedPlayer->initializedStartInfo = srv.si;
// startGameForReconnectedPlayer->initializedGameState = srv.gh->gameState();
// startGameForReconnectedPlayer->clientId = pack.c->connectionID;
// srv.announcePack(std::move(startGameForReconnectedPlayer));
// }
2018-01-05 20:21:07 +03:00
}
2023-02-12 09:23:39 +02:00
void ClientPermissionsCheckerNetPackVisitor :: visitLobbyClientDisconnected ( LobbyClientDisconnected & pack )
2018-01-05 20:21:07 +03:00
{
2025-03-01 17:50:52 +00:00
if ( pack . clientId != connection -> connectionID )
2018-01-05 20:21:07 +03:00
{
2023-02-12 09:23:39 +02:00
result = false ;
2018-01-05 20:21:07 +03:00
return ;
}
2023-02-12 09:23:39 +02:00
if ( pack . shutdownServer )
{
2024-02-10 23:56:02 +02:00
if ( ! srv . wasStartedByClient ())
2023-02-12 09:23:39 +02:00
{
result = false ;
return ;
}
2025-03-01 17:50:52 +00:00
if ( connection -> connectionID != srv . hostClientId )
2023-02-12 09:23:39 +02:00
{
result = false ;
return ;
}
}
result = true ;
}
void ApplyOnServerNetPackVisitor :: visitLobbyClientDisconnected ( LobbyClientDisconnected & pack )
{
2025-03-01 17:50:52 +00:00
connection -> getConnection () -> close ();
srv . clientDisconnected ( connection );
2023-02-12 09:23:39 +02:00
result = true ;
}
void ApplyOnServerAfterAnnounceNetPackVisitor :: visitLobbyClientDisconnected ( LobbyClientDisconnected & pack )
{
srv . updateAndPropagateLobbyState ();
2018-01-05 20:21:07 +03:00
}
2023-02-12 09:23:39 +02:00
void ClientPermissionsCheckerNetPackVisitor :: visitLobbyChatMessage ( LobbyChatMessage & pack )
2018-01-05 20:21:07 +03:00
{
2023-02-12 09:23:39 +02:00
result = true ;
2018-01-05 20:21:07 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyOnServerNetPackVisitor :: visitLobbySetMap ( LobbySetMap & pack )
2018-01-05 20:21:07 +03:00
{
2023-08-22 18:45:13 +03:00
if ( srv . getState () != EServerState :: LOBBY )
2018-01-05 20:21:07 +03:00
{
2023-02-12 09:23:39 +02:00
result = false ;
return ;
}
srv . updateStartInfoOnMapChange ( pack . mapInfo , pack . mapGenOpts );
result = true ;
}
void ApplyOnServerNetPackVisitor :: visitLobbySetCampaign ( LobbySetCampaign & pack )
{
2023-06-26 01:07:55 +03:00
srv . si -> mapname = pack . ourCampaign -> getFilename ();
2024-01-21 16:48:36 +02:00
srv . si -> mode = EStartMode :: CAMPAIGN ;
2023-02-12 09:23:39 +02:00
srv . si -> campState = pack . ourCampaign ;
2023-08-14 02:16:25 +04:00
srv . si -> turnTimerInfo = TurnTimerInfo {};
2023-06-25 21:16:03 +03:00
2023-06-26 00:01:25 +03:00
bool isCurrentMapConquerable = pack . ourCampaign -> currentScenario () && pack . ourCampaign -> isAvailable ( * pack . ourCampaign -> currentScenario ());
2024-12-27 17:59:54 +01:00
auto scenarios = pack . ourCampaign -> allScenarios ();
for ( std :: set < CampaignScenarioID >:: reverse_iterator itr = scenarios . rbegin (); itr != scenarios . rend (); itr ++ ) // reverse -> on multiple scenario selection set lowest id at the end
2023-06-26 00:01:25 +03:00
{
2024-12-27 17:59:54 +01:00
auto scenarioID = * itr ;
2023-06-26 00:01:25 +03:00
if ( pack . ourCampaign -> isAvailable ( scenarioID ))
2018-01-05 20:21:07 +03:00
{
2023-06-26 00:01:25 +03:00
if ( ! isCurrentMapConquerable || ( isCurrentMapConquerable && scenarioID == * pack . ourCampaign -> currentScenario ()))
2018-01-05 20:21:07 +03:00
{
2023-06-25 21:16:03 +03:00
srv . setCampaignMap ( scenarioID );
2018-01-05 20:21:07 +03:00
}
}
}
2023-02-12 09:23:39 +02:00
result = true ;
2018-01-05 20:21:07 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyOnServerNetPackVisitor :: visitLobbySetCampaignMap ( LobbySetCampaignMap & pack )
2018-01-05 20:21:07 +03:00
{
2023-02-12 09:23:39 +02:00
srv . setCampaignMap ( pack . mapId );
result = true ;
2018-01-05 20:21:07 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyOnServerNetPackVisitor :: visitLobbySetCampaignBonus ( LobbySetCampaignBonus & pack )
2018-01-05 20:21:07 +03:00
{
2023-02-12 09:23:39 +02:00
srv . setCampaignBonus ( pack . bonusId );
result = true ;
2018-01-05 20:21:07 +03:00
}
2023-02-12 09:23:39 +02:00
void ClientPermissionsCheckerNetPackVisitor :: visitLobbyGuiAction ( LobbyGuiAction & pack )
2018-01-05 20:21:07 +03:00
{
2025-03-01 17:50:52 +00:00
result = srv . isClientHost ( connection -> connectionID );
2018-01-05 20:21:07 +03:00
}
2024-02-03 19:08:45 +02:00
void ClientPermissionsCheckerNetPackVisitor :: visitLobbyRestartGame ( LobbyRestartGame & pack )
2022-09-29 21:08:05 +04:00
{
2025-03-01 17:50:52 +00:00
result = srv . isClientHost ( connection -> connectionID );
2022-09-29 21:08:05 +04:00
}
2024-02-03 19:08:45 +02:00
void ApplyOnServerNetPackVisitor :: visitLobbyRestartGame ( LobbyRestartGame & pack )
2022-09-29 21:08:05 +04:00
{
2023-02-12 09:23:39 +02:00
srv . prepareToRestart ();
result = true ;
2022-09-29 21:08:05 +04:00
}
2024-02-03 19:08:45 +02:00
void ApplyOnServerAfterAnnounceNetPackVisitor :: visitLobbyRestartGame ( LobbyRestartGame & pack )
2022-09-29 21:08:05 +04:00
{
2024-02-12 18:57:20 +02:00
for ( const auto & connection : srv . activeConnections )
connection -> enterLobbyConnectionMode ();
2022-09-29 21:08:05 +04:00
}
2024-02-03 19:57:23 +02:00
void ClientPermissionsCheckerNetPackVisitor :: visitLobbyPrepareStartGame ( LobbyPrepareStartGame & pack )
{
2025-03-01 17:50:52 +00:00
result = srv . isClientHost ( connection -> connectionID );
2024-02-03 19:57:23 +02:00
}
2023-02-12 09:23:39 +02:00
void ClientPermissionsCheckerNetPackVisitor :: visitLobbyStartGame ( LobbyStartGame & pack )
2018-01-05 20:21:07 +03:00
{
2025-03-01 17:50:52 +00:00
result = srv . isClientHost ( connection -> connectionID );
2018-01-05 20:21:07 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyOnServerNetPackVisitor :: visitLobbyStartGame ( LobbyStartGame & pack )
2018-01-05 20:21:07 +03:00
{
try
{
2023-02-12 09:23:39 +02:00
srv . verifyStateBeforeStart ( true );
2018-01-05 20:21:07 +03:00
}
catch (...)
{
2023-02-12 09:23:39 +02:00
result = false ;
return ;
2018-01-05 20:21:07 +03:00
}
2023-08-21 05:06:58 +04:00
2018-01-05 20:21:07 +03:00
// Server will prepare gamestate and we announce StartInfo to clients
2023-02-12 09:23:39 +02:00
if ( ! srv . prepareToStartGame ())
{
result = false ;
return ;
}
2022-09-23 15:02:19 +04:00
2025-03-03 14:46:15 +00:00
pack . initializedStartInfo = std :: make_shared < StartInfo > ( * srv . gh -> getInitialStartInfo ());
2023-02-12 09:23:39 +02:00
pack . initializedGameState = srv . gh -> gameState ();
result = true ;
2018-01-05 20:21:07 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyOnServerAfterAnnounceNetPackVisitor :: visitLobbyStartGame ( LobbyStartGame & pack )
2018-01-05 20:21:07 +03:00
{
2023-02-12 09:23:39 +02:00
if ( pack . clientId == - 1 ) //do not restart game for single client only
2023-11-18 16:34:18 +02:00
srv . startGameImmediately ();
2022-10-01 18:28:45 +04:00
else
{
2024-02-12 18:57:20 +02:00
for ( const auto & connection : srv . activeConnections )
2022-10-01 18:28:45 +04:00
{
2024-02-12 18:57:20 +02:00
if ( connection -> connectionID == pack . clientId )
2022-10-01 18:28:45 +04:00
{
2024-02-12 18:57:20 +02:00
connection -> enterGameplayConnectionMode ( srv . gh -> gameState ());
2023-02-12 09:23:39 +02:00
srv . reconnectPlayer ( pack . clientId );
2022-10-01 18:28:45 +04:00
}
}
}
2018-01-05 20:21:07 +03:00
}
2023-02-12 09:23:39 +02:00
void ClientPermissionsCheckerNetPackVisitor :: visitLobbyChangeHost ( LobbyChangeHost & pack )
2018-01-05 20:21:07 +03:00
{
2025-03-01 17:50:52 +00:00
result = srv . isClientHost ( connection -> connectionID );
2018-01-05 20:21:07 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyOnServerNetPackVisitor :: visitLobbyChangeHost ( LobbyChangeHost & pack )
2018-01-05 20:21:07 +03:00
{
2023-02-12 09:23:39 +02:00
result = true ;
2018-01-05 20:21:07 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyOnServerAfterAnnounceNetPackVisitor :: visitLobbyChangeHost ( LobbyChangeHost & pack )
2018-01-05 20:21:07 +03:00
{
2023-02-12 09:23:39 +02:00
auto result = srv . passHost ( pack . newHostConnectionId );
if ( ! result )
2018-01-05 20:21:07 +03:00
{
2023-02-12 09:23:39 +02:00
logGlobal -> error ( "passHost returned false. What does it mean?" );
}
}
void ClientPermissionsCheckerNetPackVisitor :: visitLobbyChangePlayerOption ( LobbyChangePlayerOption & pack )
{
2025-03-01 17:50:52 +00:00
if ( srv . isClientHost ( connection -> connectionID ))
2023-02-12 09:23:39 +02:00
{
result = true ;
return ;
}
2025-03-01 17:50:52 +00:00
if ( vstd :: contains ( srv . getAllClientPlayers ( connection -> connectionID ), pack . color ))
2023-02-12 09:23:39 +02:00
{
result = true ;
return ;
}
result = false ;
}
void ApplyOnServerNetPackVisitor :: visitLobbyChangePlayerOption ( LobbyChangePlayerOption & pack )
{
switch ( pack . what )
{
2023-08-14 00:08:48 +02:00
case LobbyChangePlayerOption :: TOWN_ID :
2023-09-28 19:43:04 +03:00
srv . optionSetCastle ( pack . color , FactionID ( pack . value ));
2023-08-14 00:08:48 +02:00
break ;
2023-02-12 09:23:39 +02:00
case LobbyChangePlayerOption :: TOWN :
2023-08-14 00:08:48 +02:00
srv . optionNextCastle ( pack . color , pack . value );
break ;
case LobbyChangePlayerOption :: HERO_ID :
2023-09-28 19:43:04 +03:00
srv . optionSetHero ( pack . color , HeroTypeID ( pack . value ));
2018-01-05 20:21:07 +03:00
break ;
2023-02-12 09:23:39 +02:00
case LobbyChangePlayerOption :: HERO :
2023-08-14 00:08:48 +02:00
srv . optionNextHero ( pack . color , pack . value );
break ;
case LobbyChangePlayerOption :: BONUS_ID :
2023-09-28 19:43:04 +03:00
srv . optionSetBonus ( pack . color , PlayerStartingBonus ( pack . value ));
2018-01-05 20:21:07 +03:00
break ;
2023-02-12 09:23:39 +02:00
case LobbyChangePlayerOption :: BONUS :
2023-08-14 00:08:48 +02:00
srv . optionNextBonus ( pack . color , pack . value );
2018-01-05 20:21:07 +03:00
break ;
}
2023-02-12 09:23:39 +02:00
result = true ;
2018-01-05 20:21:07 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyOnServerNetPackVisitor :: visitLobbySetPlayer ( LobbySetPlayer & pack )
2018-01-05 20:21:07 +03:00
{
2023-02-12 09:23:39 +02:00
srv . setPlayer ( pack . clickedColor );
result = true ;
2018-01-05 20:21:07 +03:00
}
2023-10-13 23:04:35 +02:00
void ApplyOnServerNetPackVisitor :: visitLobbySetPlayerName ( LobbySetPlayerName & pack )
{
srv . setPlayerName ( pack . color , pack . name );
result = true ;
}
2024-07-16 00:40:39 +02:00
void ApplyOnServerNetPackVisitor :: visitLobbySetPlayerHandicap ( LobbySetPlayerHandicap & pack )
{
srv . setPlayerHandicap ( pack . color , pack . handicap );
result = true ;
}
2023-09-22 19:57:43 +03:00
void ApplyOnServerNetPackVisitor :: visitLobbySetSimturns ( LobbySetSimturns & pack )
{
srv . si -> simturnsInfo = pack . simturnsInfo ;
result = true ;
}
2023-02-12 09:23:39 +02:00
void ApplyOnServerNetPackVisitor :: visitLobbySetTurnTime ( LobbySetTurnTime & pack )
2018-01-05 20:21:07 +03:00
{
2023-08-14 02:16:25 +04:00
srv . si -> turnTimerInfo = pack . turnTimerInfo ;
2023-02-12 09:23:39 +02:00
result = true ;
2018-01-05 20:21:07 +03:00
}
2023-12-28 20:48:19 +01:00
void ApplyOnServerNetPackVisitor :: visitLobbySetExtraOptions ( LobbySetExtraOptions & pack )
2023-12-27 14:39:35 +01:00
{
2023-12-28 20:48:19 +01:00
srv . si -> extraOptionsInfo = pack . extraOptionsInfo ;
2023-12-27 14:39:35 +01:00
result = true ;
}
2023-02-12 09:23:39 +02:00
void ApplyOnServerNetPackVisitor :: visitLobbySetDifficulty ( LobbySetDifficulty & pack )
2018-01-05 20:21:07 +03:00
{
2023-04-11 01:00:46 +03:00
srv . si -> difficulty = std :: clamp < uint8_t > ( pack . difficulty , 0 , 4 );
2023-02-12 09:23:39 +02:00
result = true ;
2018-01-05 20:21:07 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyOnServerNetPackVisitor :: visitLobbyForceSetPlayer ( LobbyForceSetPlayer & pack )
2018-01-05 20:21:07 +03:00
{
2023-02-12 09:23:39 +02:00
srv . si -> playerInfos [ pack . targetPlayerColor ]. connectedPlayerIDs . insert ( pack . targetConnectedPlayer );
result = true ;
2018-01-05 20:21:07 +03:00
}
2024-04-30 01:52:49 +02:00
2024-05-01 15:58:22 +02:00
void ClientPermissionsCheckerNetPackVisitor :: visitLobbyPvPAction ( LobbyPvPAction & pack )
{
result = true ;
}
2024-04-30 01:52:49 +02:00
void ApplyOnServerNetPackVisitor :: visitLobbyPvPAction ( LobbyPvPAction & pack )
{
2024-05-01 01:26:51 +02:00
std :: vector < FactionID > allowedTowns ;
2024-04-30 01:52:49 +02:00
2025-02-14 16:23:37 +00:00
for ( auto const & factionID : LIBRARY -> townh -> getDefaultAllowed ())
2024-05-02 20:15:34 +02:00
if ( std :: find ( pack . bannedTowns . begin (), pack . bannedTowns . end (), factionID ) == pack . bannedTowns . end ())
allowedTowns . push_back ( factionID );
2024-05-01 00:49:33 +02:00
std :: vector < FactionID > randomFaction1 ;
2024-05-01 01:26:51 +02:00
std :: sample ( allowedTowns . begin (), allowedTowns . end (), std :: back_inserter ( randomFaction1 ), 1 , std :: mt19937 { std :: random_device {}()});
2024-05-01 00:49:33 +02:00
std :: vector < FactionID > randomFaction2 ;
2024-05-01 01:26:51 +02:00
std :: sample ( allowedTowns . begin (), allowedTowns . end (), std :: back_inserter ( randomFaction2 ), 1 , std :: mt19937 { std :: random_device {}()});
2024-04-30 01:52:49 +02:00
2024-05-02 21:03:23 +02:00
MetaString txt ;
2024-04-30 01:52:49 +02:00
switch ( pack . action ) {
case LobbyPvPAction :: COIN :
2024-05-02 21:03:23 +02:00
txt . appendTextID ( "vcmi.lobby.pvp.coin.hover" );
txt . appendRawString ( " - " + std :: to_string ( std :: rand () % 2 ));
srv . announceTxt ( txt );
2024-04-30 01:52:49 +02:00
break ;
case LobbyPvPAction :: RANDOM_TOWN :
2024-05-02 21:03:23 +02:00
if ( ! allowedTowns . size ())
break ;
txt . appendTextID ( "core.overview.3" );
txt . appendRawString ( " - " );
2025-02-14 16:23:37 +00:00
txt . appendTextID ( LIBRARY -> townh -> getById ( randomFaction1 [ 0 ]) -> getNameTextID ());
2024-05-02 21:03:23 +02:00
srv . announceTxt ( txt );
2024-04-30 01:52:49 +02:00
break ;
case LobbyPvPAction :: RANDOM_TOWN_VS :
2024-05-02 21:03:23 +02:00
if ( ! allowedTowns . size ())
break ;
txt . appendTextID ( "core.overview.3" );
txt . appendRawString ( " - " );
2025-02-14 16:23:37 +00:00
txt . appendTextID ( LIBRARY -> townh -> getById ( randomFaction1 [ 0 ]) -> getNameTextID ());
2024-05-02 21:03:23 +02:00
txt . appendRawString ( " " );
txt . appendTextID ( "vcmi.lobby.pvp.versus" );
txt . appendRawString ( " " );
2025-02-14 16:23:37 +00:00
txt . appendTextID ( LIBRARY -> townh -> getById ( randomFaction2 [ 0 ]) -> getNameTextID ());
2024-05-02 21:03:23 +02:00
srv . announceTxt ( txt );
2024-04-30 01:52:49 +02:00
break ;
}
result = true ;
}
2024-10-31 21:57:20 +01:00
void ClientPermissionsCheckerNetPackVisitor :: visitLobbyDelete ( LobbyDelete & pack )
{
2025-03-01 17:50:52 +00:00
result = srv . isClientHost ( connection -> connectionID );
2024-10-31 21:57:20 +01:00
}
void ApplyOnServerNetPackVisitor :: visitLobbyDelete ( LobbyDelete & pack )
{
2024-11-15 18:38:44 +01:00
if ( pack . type == LobbyDelete :: EType :: SAVEGAME || pack . type == LobbyDelete :: EType :: RANDOMMAP )
2024-10-31 21:57:20 +01:00
{
2024-11-15 18:38:44 +01:00
auto res = ResourcePath ( pack . name , pack . type == LobbyDelete :: EType :: SAVEGAME ? EResType :: SAVEGAME : EResType :: MAP );
2024-12-23 18:00:35 +00:00
auto name = CResourceHandler :: get () -> getResourceName ( res );
if ( ! name )
{
logGlobal -> error ( "Failed to find resource with name '%s'" , res . getOriginalName ());
return ;
}
2025-01-01 20:57:43 +00:00
boost :: system :: error_code ec ;
auto file = boost :: filesystem :: canonical ( * name , ec );
if ( ec )
{
logGlobal -> error ( "Failed to delete file '%s'. Reason: %s" , res . getOriginalName (), ec . message ());
}
else
{
boost :: filesystem :: remove ( file );
if ( boost :: filesystem :: is_empty ( file . parent_path ()))
boost :: filesystem :: remove ( file . parent_path ());
}
2024-11-01 01:16:01 +01:00
}
2024-11-15 18:38:44 +01:00
else if ( pack . type == LobbyDelete :: EType :: SAVEGAME_FOLDER )
2024-11-01 01:16:01 +01:00
{
auto res = ResourcePath ( "Saves/" + pack . name , EResType :: DIRECTORY );
2024-12-23 18:00:35 +00:00
auto name = CResourceHandler :: get () -> getResourceName ( res );
if ( ! name )
{
logGlobal -> error ( "Failed to find folder with name '%s'" , res . getOriginalName ());
return ;
}
2025-01-01 20:57:43 +00:00
boost :: system :: error_code ec ;
2024-12-23 18:00:35 +00:00
auto folder = boost :: filesystem :: canonical ( * name );
2025-01-01 20:57:43 +00:00
if ( ec )
{
logGlobal -> error ( "Failed to delete folder '%s'. Reason: %s" , res . getOriginalName (), ec . message ());
}
else
{
boost :: filesystem :: remove_all ( folder );
}
2024-10-31 21:57:20 +01:00
}
2024-11-01 00:52:19 +01:00
LobbyUpdateState lus ;
lus . state = srv ;
lus . refreshList = true ;
srv . announcePack ( lus );
2024-10-31 21:57:20 +01:00
}