mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
- Moved place bonus hero before normal random hero and starting hero placement -> same behaviour as in OH3
- Moved placing campaign heroes before random object generation -> same behaviour as in OH3 - Refactored pickHero into pickNextHeroType (hero generation sequence) and pickUnusedHeroTypeRandomly - Added a SIGSEV violation handler to vcmiserver executable for logging stacktrace (for convenience only) - Fixed Fuzzy.cpp and VCAI.h compilation on Clang - Added a handleException function in addition to our macros (no use of macros, enables debugging support, does not re-throw, catches ...-case too)
This commit is contained in:
parent
9ec299931d
commit
b8eddcd9a8
@ -311,7 +311,7 @@ Goals::TSubgoal FuzzyHelper::chooseSolution (Goals::TGoalVec vec)
|
|||||||
setPriority(g);
|
setPriority(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto compareGoals = [&](Goals::TSubgoal & lhs, const Goals::TSubgoal & rhs) -> bool
|
auto compareGoals = [](const Goals::TSubgoal & lhs, const Goals::TSubgoal & rhs) -> bool
|
||||||
{
|
{
|
||||||
return lhs->priority < rhs->priority;
|
return lhs->priority < rhs->priority;
|
||||||
};
|
};
|
||||||
@ -467,4 +467,4 @@ float FuzzyHelper::evaluate (Goals::AbstractGoal & g)
|
|||||||
void FuzzyHelper::setPriority (Goals::TSubgoal & g)
|
void FuzzyHelper::setPriority (Goals::TSubgoal & g)
|
||||||
{
|
{
|
||||||
g->setpriority(g->accept(this)); //this enforces returned value is set
|
g->setpriority(g->accept(this)); //this enforces returned value is set
|
||||||
}
|
}
|
||||||
|
@ -295,7 +295,7 @@ public:
|
|||||||
const CGTownInstance *findTownWithTavern() const;
|
const CGTownInstance *findTownWithTavern() const;
|
||||||
bool canRecruitAnyHero(const CGTownInstance * t = NULL) const;
|
bool canRecruitAnyHero(const CGTownInstance * t = NULL) const;
|
||||||
|
|
||||||
bool VCAI::canAct (HeroPtr h) const;
|
bool canAct(HeroPtr h) const;
|
||||||
std::vector<HeroPtr> getUnblockedHeroes() const;
|
std::vector<HeroPtr> getUnblockedHeroes() const;
|
||||||
HeroPtr primaryHero() const;
|
HeroPtr primaryHero() const;
|
||||||
TResources freeResources() const; //owned resources minus gold reserve
|
TResources freeResources() const; //owned resources minus gold reserve
|
||||||
|
27
Global.h
27
Global.h
@ -225,6 +225,28 @@ template<typename T, size_t N> char (&_ArrayCountObj(const T (&)[N]))[N];
|
|||||||
/* ---------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------- */
|
||||||
/* VCMI standard library */
|
/* VCMI standard library */
|
||||||
/* ---------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------- */
|
||||||
|
#include "lib/logging/CLogger.h"
|
||||||
|
|
||||||
|
void inline handleException()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch(const std::exception & ex)
|
||||||
|
{
|
||||||
|
logGlobal->errorStream() << ex.what();
|
||||||
|
}
|
||||||
|
catch(const std::string & ex)
|
||||||
|
{
|
||||||
|
logGlobal->errorStream() << ex;
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
logGlobal->errorStream() << "Sorry, caught unknown exception type. No more info available.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::ostream & operator<<(std::ostream & out, const boost::optional<T> & opt)
|
std::ostream & operator<<(std::ostream & out, const boost::optional<T> & opt)
|
||||||
{
|
{
|
||||||
@ -601,8 +623,3 @@ namespace vstd
|
|||||||
}
|
}
|
||||||
using vstd::operator-=;
|
using vstd::operator-=;
|
||||||
using vstd::make_unique;
|
using vstd::make_unique;
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------- */
|
|
||||||
/* VCMI headers */
|
|
||||||
/* ---------------------------------------------------------------------------- */
|
|
||||||
#include "lib/logging/CLogger.h"
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "GameConstants.h"
|
#include "GameConstants.h"
|
||||||
#include "rmg/CMapGenerator.h"
|
#include "rmg/CMapGenerator.h"
|
||||||
#include "CStopWatch.h"
|
#include "CStopWatch.h"
|
||||||
|
#include "mapping/CMapEditManager.h"
|
||||||
|
|
||||||
DLL_LINKAGE std::minstd_rand ran;
|
DLL_LINKAGE std::minstd_rand ran;
|
||||||
class CGObjectInstance;
|
class CGObjectInstance;
|
||||||
@ -444,28 +445,23 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor pl
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CGameState::pickHero(PlayerColor owner)
|
int CGameState::pickNextHeroType(PlayerColor owner) const
|
||||||
{
|
{
|
||||||
const PlayerSettings &ps = scenarioOps->getIthPlayersSettings(owner);
|
const PlayerSettings &ps = scenarioOps->getIthPlayersSettings(owner);
|
||||||
if(!isUsedHero(HeroTypeID(ps.hero)) && ps.hero >= 0) //we haven't used selected hero
|
if(ps.hero >= 0 && !isUsedHero(HeroTypeID(ps.hero))) //we haven't used selected hero
|
||||||
return ps.hero;
|
|
||||||
|
|
||||||
if(scenarioOps->mode == StartInfo::CAMPAIGN)
|
|
||||||
{
|
{
|
||||||
auto bonus = scenarioOps->campState->getBonusForCurrentMap();
|
return ps.hero;
|
||||||
if(bonus && bonus->type == CScenarioTravel::STravelBonus::HERO && owner == PlayerColor(bonus->info1))
|
|
||||||
{
|
|
||||||
//TODO what if hero chosen as bonus is placed in the prison on map
|
|
||||||
if(bonus->info2 != 0xffff && !isUsedHero(HeroTypeID(bonus->info2))) //not random and not taken
|
|
||||||
{
|
|
||||||
return bonus->info2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return pickUnusedHeroTypeRandomly(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CGameState::pickUnusedHeroTypeRandomly(PlayerColor owner) const
|
||||||
|
{
|
||||||
//list of available heroes for this faction and others
|
//list of available heroes for this faction and others
|
||||||
std::vector<HeroTypeID> factionHeroes, otherHeroes;
|
std::vector<HeroTypeID> factionHeroes, otherHeroes;
|
||||||
|
|
||||||
|
const PlayerSettings &ps = scenarioOps->getIthPlayersSettings(owner);
|
||||||
for(HeroTypeID hid : getUnusedAllowedHeroes())
|
for(HeroTypeID hid : getUnusedAllowedHeroes())
|
||||||
{
|
{
|
||||||
if(VLC->heroh->heroes[hid.getNum()]->heroClass->faction == ps.castle)
|
if(VLC->heroh->heroes[hid.getNum()]->heroClass->faction == ps.castle)
|
||||||
@ -507,7 +503,7 @@ std::pair<Obj,int> CGameState::pickObject (CGObjectInstance *obj)
|
|||||||
case Obj::RANDOM_RELIC_ART:
|
case Obj::RANDOM_RELIC_ART:
|
||||||
return std::make_pair(Obj::ARTIFACT, VLC->arth->getRandomArt (CArtifact::ART_RELIC));
|
return std::make_pair(Obj::ARTIFACT, VLC->arth->getRandomArt (CArtifact::ART_RELIC));
|
||||||
case Obj::RANDOM_HERO:
|
case Obj::RANDOM_HERO:
|
||||||
return std::make_pair(Obj::HERO, pickHero(obj->tempOwner));
|
return std::make_pair(Obj::HERO, pickNextHeroType(obj->tempOwner));
|
||||||
case Obj::RANDOM_MONSTER:
|
case Obj::RANDOM_MONSTER:
|
||||||
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(std::ref(ran)));
|
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(std::ref(ran)));
|
||||||
case Obj::RANDOM_MONSTER_L1:
|
case Obj::RANDOM_MONSTER_L1:
|
||||||
@ -794,11 +790,11 @@ void CGameState::init(StartInfo * si)
|
|||||||
|
|
||||||
logGlobal->debugStream() << "Initialization:";
|
logGlobal->debugStream() << "Initialization:";
|
||||||
|
|
||||||
|
initPlayerStates();
|
||||||
|
placeCampaignHeroes();
|
||||||
initGrailPosition();
|
initGrailPosition();
|
||||||
initRandomFactionsForPlayers();
|
initRandomFactionsForPlayers();
|
||||||
randomizeMapObjects();
|
randomizeMapObjects();
|
||||||
initPlayerStates();
|
|
||||||
initHeroPlaceholders();
|
|
||||||
placeStartingHeroes();
|
placeStartingHeroes();
|
||||||
initStartingResources();
|
initStartingResources();
|
||||||
initHeroes();
|
initHeroes();
|
||||||
@ -1095,10 +1091,31 @@ void CGameState::initPlayerStates()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameState::initHeroPlaceholders()
|
void CGameState::placeCampaignHeroes()
|
||||||
{
|
{
|
||||||
if (scenarioOps->campState)
|
if (scenarioOps->campState)
|
||||||
{
|
{
|
||||||
|
// place bonus hero
|
||||||
|
auto campaignBonus = scenarioOps->campState->getBonusForCurrentMap();
|
||||||
|
bool campaignGiveHero = campaignBonus && campaignBonus.get().type == CScenarioTravel::STravelBonus::HERO;
|
||||||
|
|
||||||
|
if(campaignGiveHero)
|
||||||
|
{
|
||||||
|
auto playerColor = PlayerColor(campaignBonus->info1);
|
||||||
|
auto it = scenarioOps->playerInfos.find(playerColor);
|
||||||
|
if(it != scenarioOps->playerInfos.end())
|
||||||
|
{
|
||||||
|
auto heroTypeId = campaignBonus->info2;
|
||||||
|
if(heroTypeId == 0xffff) // random bonus hero
|
||||||
|
{
|
||||||
|
heroTypeId = pickUnusedHeroTypeRandomly(playerColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
placeStartingHero(playerColor, HeroTypeID(heroTypeId), map->players[playerColor.getNum()].posOfMainTown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// replace heroes placeholders
|
||||||
auto campaignScenario = getCampaignScenarioForCrossoverHeroes();
|
auto campaignScenario = getCampaignScenarioForCrossoverHeroes();
|
||||||
|
|
||||||
if(campaignScenario)
|
if(campaignScenario)
|
||||||
@ -1107,14 +1124,29 @@ void CGameState::initHeroPlaceholders()
|
|||||||
auto crossoverHeroes = prepareCrossoverHeroes(campaignScenario);
|
auto crossoverHeroes = prepareCrossoverHeroes(campaignScenario);
|
||||||
|
|
||||||
logGlobal->debugStream() << "\tGenerate list of hero placeholders";
|
logGlobal->debugStream() << "\tGenerate list of hero placeholders";
|
||||||
auto campaignHeroReplacements = generateCampaignHeroesToReplace(crossoverHeroes);
|
const auto campaignHeroReplacements = generateCampaignHeroesToReplace(crossoverHeroes);
|
||||||
|
|
||||||
|
// remove same heroes on the map which will be added through crossover heroes
|
||||||
|
/*for(auto & campaignHeroReplacement : campaignHeroReplacement)
|
||||||
|
{
|
||||||
|
campaignHeroReplacement.first->subID
|
||||||
|
}*/
|
||||||
|
|
||||||
logGlobal->debugStream() << "\tReplace placeholders with heroes";
|
logGlobal->debugStream() << "\tReplace placeholders with heroes";
|
||||||
placeCampaignHeroes(campaignHeroReplacements);
|
replaceHeroesPlaceholders(campaignHeroReplacements);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGameState::placeStartingHero(PlayerColor playerColor, HeroTypeID heroTypeId, int3 townPos)
|
||||||
|
{
|
||||||
|
townPos.x += 1;
|
||||||
|
|
||||||
|
CGHeroInstance * hero = static_cast<CGHeroInstance*>(createObject(Obj::HERO, heroTypeId.getNum(), townPos, playerColor));
|
||||||
|
hero->initHero();
|
||||||
|
map->getEditManager()->insertObject(hero, townPos);
|
||||||
|
}
|
||||||
|
|
||||||
const CCampaignScenario * CGameState::getCampaignScenarioForCrossoverHeroes() const
|
const CCampaignScenario * CGameState::getCampaignScenarioForCrossoverHeroes() const
|
||||||
{
|
{
|
||||||
const CCampaignScenario * campaignScenario = nullptr;
|
const CCampaignScenario * campaignScenario = nullptr;
|
||||||
@ -1223,36 +1255,26 @@ std::vector<CGHeroInstance *> CGameState::prepareCrossoverHeroes(const CCampaign
|
|||||||
void CGameState::placeStartingHeroes()
|
void CGameState::placeStartingHeroes()
|
||||||
{
|
{
|
||||||
logGlobal->debugStream() << "\tGiving starting hero";
|
logGlobal->debugStream() << "\tGiving starting hero";
|
||||||
bool campaignGiveHero = false;
|
|
||||||
if(scenarioOps->campState)
|
for(auto & playerSettingPair : scenarioOps->playerInfos)
|
||||||
{
|
{
|
||||||
if(auto bonus = scenarioOps->campState->getBonusForCurrentMap())
|
auto playerColor = playerSettingPair.first;
|
||||||
|
auto & playerInfo = map->players[playerColor.getNum()];
|
||||||
|
if(playerInfo.generateHeroAtMainTown && playerInfo.hasMainTown)
|
||||||
{
|
{
|
||||||
campaignGiveHero = scenarioOps->mode == StartInfo::CAMPAIGN &&
|
// Do not place a starting hero if the hero was already placed due to a campaign bonus
|
||||||
bonus.get().type == CScenarioTravel::STravelBonus::HERO;
|
if(scenarioOps->campState)
|
||||||
}
|
{
|
||||||
}
|
if(auto campaignBonus = scenarioOps->campState->getBonusForCurrentMap())
|
||||||
|
{
|
||||||
|
if(campaignBonus->type == CScenarioTravel::STravelBonus::HERO && playerColor == PlayerColor(campaignBonus->info1)) continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(auto it = scenarioOps->playerInfos.begin(); it != scenarioOps->playerInfos.end(); ++it)
|
int heroTypeId = pickNextHeroType(playerColor);
|
||||||
{
|
if(playerSettingPair.second.hero == -1) playerSettingPair.second.hero = heroTypeId;
|
||||||
const PlayerInfo &p = map->players[it->first.getNum()];
|
|
||||||
bool generateHero = (p.generateHeroAtMainTown ||
|
|
||||||
(it->second.playerID != PlayerSettings::PLAYER_AI && campaignGiveHero)) && p.hasMainTown;
|
|
||||||
if(generateHero && vstd::contains(scenarioOps->playerInfos, it->first))
|
|
||||||
{
|
|
||||||
int3 hpos = p.posOfMainTown;
|
|
||||||
hpos.x+=1;
|
|
||||||
|
|
||||||
int h = pickHero(it->first);
|
placeStartingHero(playerColor, HeroTypeID(heroTypeId), playerInfo.posOfMainTown);
|
||||||
if(it->second.hero == -1)
|
|
||||||
it->second.hero = h;
|
|
||||||
|
|
||||||
CGHeroInstance * nnn = static_cast<CGHeroInstance*>(createObject(Obj::HERO,h,hpos,it->first));
|
|
||||||
nnn->id = ObjectInstanceID(map->objects.size());
|
|
||||||
nnn->initHero();
|
|
||||||
map->heroesOnMap.push_back(nnn);
|
|
||||||
map->objects.push_back(nnn);
|
|
||||||
map->addBlockVisTiles(nnn);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2781,7 +2803,7 @@ std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > CGameState::generateC
|
|||||||
return campaignHeroReplacements;
|
return campaignHeroReplacements;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameState::placeCampaignHeroes(const std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > &campHeroReplacements)
|
void CGameState::replaceHeroesPlaceholders(const std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > &campHeroReplacements)
|
||||||
{
|
{
|
||||||
for(auto obj : campHeroReplacements)
|
for(auto obj : campHeroReplacements)
|
||||||
{
|
{
|
||||||
|
@ -457,15 +457,16 @@ private:
|
|||||||
void randomizeMapObjects();
|
void randomizeMapObjects();
|
||||||
void randomizeObject(CGObjectInstance *cur);
|
void randomizeObject(CGObjectInstance *cur);
|
||||||
void initPlayerStates();
|
void initPlayerStates();
|
||||||
void initHeroPlaceholders();
|
void placeCampaignHeroes();
|
||||||
const CCampaignScenario * getCampaignScenarioForCrossoverHeroes() const;
|
const CCampaignScenario * getCampaignScenarioForCrossoverHeroes() const;
|
||||||
std::vector<CGHeroInstance *> prepareCrossoverHeroes(const CCampaignScenario * campaignScenario);
|
std::vector<CGHeroInstance *> prepareCrossoverHeroes(const CCampaignScenario * campaignScenario);
|
||||||
|
|
||||||
// returns heroes and placeholders in where heroes will be put
|
// returns heroes and placeholders in where heroes will be put
|
||||||
std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > generateCampaignHeroesToReplace(std::vector<CGHeroInstance *> & crossoverHeroes);
|
std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > generateCampaignHeroesToReplace(std::vector<CGHeroInstance *> & crossoverHeroes);
|
||||||
|
|
||||||
void placeCampaignHeroes(const std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > &campHeroReplacements);
|
void replaceHeroesPlaceholders(const std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > &campHeroReplacements);
|
||||||
void placeStartingHeroes();
|
void placeStartingHeroes();
|
||||||
|
void placeStartingHero(PlayerColor playerColor, HeroTypeID heroTypeId, int3 townPos);
|
||||||
void initStartingResources();
|
void initStartingResources();
|
||||||
void initHeroes();
|
void initHeroes();
|
||||||
void giveCampaignBonusToHero(CGHeroInstance * hero);
|
void giveCampaignBonusToHero(CGHeroInstance * hero);
|
||||||
@ -494,7 +495,8 @@ private:
|
|||||||
bool isUsedHero(HeroTypeID hid) const; //looks in heroes and prisons
|
bool isUsedHero(HeroTypeID hid) const; //looks in heroes and prisons
|
||||||
std::set<HeroTypeID> getUnusedAllowedHeroes(bool alsoIncludeNotAllowed = false) const;
|
std::set<HeroTypeID> getUnusedAllowedHeroes(bool alsoIncludeNotAllowed = false) const;
|
||||||
std::pair<Obj,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
|
std::pair<Obj,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
|
||||||
int pickHero(PlayerColor owner);
|
int pickUnusedHeroTypeRandomly(PlayerColor owner) const; // picks a unused hero type randomly
|
||||||
|
int pickNextHeroType(PlayerColor owner) const; // picks next free hero type of the H3 hero init sequence -> chosen starting hero, then unused hero type randomly
|
||||||
|
|
||||||
friend class CCallback;
|
friend class CCallback;
|
||||||
friend class CClient;
|
friend class CClient;
|
||||||
|
@ -32,6 +32,10 @@
|
|||||||
|
|
||||||
#include "../lib/UnlockGuard.h"
|
#include "../lib/UnlockGuard.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#include <execinfo.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
std::string NAME_AFFIX = "server";
|
std::string NAME_AFFIX = "server";
|
||||||
std::string NAME = GameConstants::VCMI_VERSION + std::string(" (") + NAME_AFFIX + ')'; //application name
|
std::string NAME = GameConstants::VCMI_VERSION + std::string(" (") + NAME_AFFIX + ')'; //application name
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
@ -531,8 +535,41 @@ static void handleCommandOptions(int argc, char *argv[])
|
|||||||
po::notify(cmdLineOptions);
|
po::notify(cmdLineOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
void handleLinuxSignal(int sig)
|
||||||
|
{
|
||||||
|
const int STACKTRACE_SIZE = 100;
|
||||||
|
void * buffer[STACKTRACE_SIZE];
|
||||||
|
int ptrCount = backtrace(buffer, STACKTRACE_SIZE);
|
||||||
|
char ** strings;
|
||||||
|
|
||||||
|
logGlobal->errorStream() << "Error: signal " << sig << ":";
|
||||||
|
strings = backtrace_symbols(buffer, ptrCount);
|
||||||
|
if(strings == nullptr)
|
||||||
|
{
|
||||||
|
logGlobal->errorStream() << "There are no symbols.";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0; i < ptrCount; ++i)
|
||||||
|
{
|
||||||
|
logGlobal->errorStream() << strings[i];
|
||||||
|
}
|
||||||
|
free(strings);
|
||||||
|
}
|
||||||
|
|
||||||
|
_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
// Installs a sig sev segmentation violation handler
|
||||||
|
// to log stacktrace
|
||||||
|
#ifdef __GNUC__
|
||||||
|
signal(SIGSEGV, handleLinuxSignal);
|
||||||
|
#endif
|
||||||
|
|
||||||
console = new CConsoleHandler;
|
console = new CConsoleHandler;
|
||||||
CBasicLogConfigurator logConfig(VCMIDirs::get().userCachePath() + "/VCMI_Server_log.txt", console);
|
CBasicLogConfigurator logConfig(VCMIDirs::get().userCachePath() + "/VCMI_Server_log.txt", console);
|
||||||
logConfig.configureDefault();
|
logConfig.configureDefault();
|
||||||
@ -564,7 +601,11 @@ int main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
logNetwork->errorStream() << e.what();
|
logNetwork->errorStream() << e.what();
|
||||||
end2 = true;
|
end2 = true;
|
||||||
}HANDLE_EXCEPTION
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
handleException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(boost::system::system_error &e)
|
catch(boost::system::system_error &e)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user