1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

make server a static lib, run it in a separate thread

issues to solve:
- dynamic_cast error 2: One or more of the following type_info's has hidden visibility or is defined in more than one translation unit. They should all have public visibility. 13CPackForLobby, 20LobbyClientConnected, 20LobbyClientConnected.
- error setting socket option: set_option: No buffer space available
This commit is contained in:
Andrey Filipenkov 2021-03-05 19:26:35 +03:00
parent d6f8e4328c
commit 2e18299897
12 changed files with 88 additions and 20 deletions

View File

@ -433,6 +433,7 @@ int main(int argc, char * argv[])
#ifndef VCMI_NO_THREADED_LOAD #ifndef VCMI_NO_THREADED_LOAD
// todo ios
#ifdef VCMI_ANDROID // android loads the data quite slowly so we display native progressbar to prevent having only black screen for few seconds #ifdef VCMI_ANDROID // android loads the data quite slowly so we display native progressbar to prevent having only black screen for few seconds
{ {
CAndroidVMHelper vmHelper; CAndroidVMHelper vmHelper;
@ -1136,9 +1137,9 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
logGlobal->warn("Metal unavailable, using OpenGL ES"); logGlobal->warn("Metal unavailable, using OpenGL ES");
createWindow(); createWindow();
} }
SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight"); // TODO: isn't setting in Info.plist not enough? // SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight"); // TODO: isn't setting in Info.plist not enough?
SDL_SetHint(SDL_HINT_IOS_HIDE_HOME_INDICATOR, "1"); SDL_SetHint(SDL_HINT_IOS_HIDE_HOME_INDICATOR, "1");
//SDL_HINT_RETURN_KEY_HIDES_IME SDL_SetHint(SDL_HINT_RETURN_KEY_HIDES_IME, "1");
logGlobal->info("before SDL_GetWindowSize %dx%d", w, h); logGlobal->info("before SDL_GetWindowSize %dx%d", w, h);
SDL_GetWindowSize(mainWindow, &w, &h); SDL_GetWindowSize(mainWindow, &w, &h);
@ -1315,6 +1316,7 @@ static void handleEvent(SDL_Event & ev)
{ {
if((ev.type==SDL_QUIT) ||(ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4 && (ev.key.keysym.mod & KMOD_ALT))) if((ev.type==SDL_QUIT) ||(ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4 && (ev.key.keysym.mod & KMOD_ALT)))
{ {
// todo ios
#ifdef VCMI_ANDROID #ifdef VCMI_ANDROID
handleQuit(false); handleQuit(false);
#else #else

View File

@ -177,7 +177,9 @@ if(WIN32)
target_compile_definitions(vcmiclient PRIVATE WINDOWS_IGNORE_PACKING_MISMATCH) target_compile_definitions(vcmiclient PRIVATE WINDOWS_IGNORE_PACKING_MISMATCH)
elseif(APPLE_IOS) elseif(APPLE_IOS)
target_link_libraries(vcmiclient PRIVATE target_link_libraries(vcmiclient PRIVATE
"-framework Foundation -framework UIKit -framework QuartzCore -framework CoreGraphics -framework CoreServices -framework ImageIO" # SDL2_image vcmiserver
# SDL2_image:
"-framework Foundation -framework UIKit -framework QuartzCore -framework CoreGraphics -framework CoreServices -framework ImageIO"
) )
target_sources(vcmiclient PRIVATE ${CMAKE_SOURCE_DIR}/client/LaunchScreen.storyboard) target_sources(vcmiclient PRIVATE ${CMAKE_SOURCE_DIR}/client/LaunchScreen.storyboard)

View File

@ -364,6 +364,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
for(int i = 1; i < 32; i += 2 * speed) for(int i = 1; i < 32; i += 2 * speed)
{ {
movementPxStep(details, i, hp, hero); movementPxStep(details, i, hp, hero);
// todo ios
#ifndef VCMI_ANDROID #ifndef VCMI_ANDROID
// currently android doesn't seem to be able to handle all these full redraws here, so let's disable it so at least it looks less choppy; // currently android doesn't seem to be able to handle all these full redraws here, so let's disable it so at least it looks less choppy;
// most likely this is connected with the way that this manual animation+framerate handling is solved // most likely this is connected with the way that this manual animation+framerate handling is solved

View File

@ -24,7 +24,8 @@
#ifdef VCMI_ANDROID #ifdef VCMI_ANDROID
#include "../lib/CAndroidVMHelper.h" #include "../lib/CAndroidVMHelper.h"
#elif defined(VCMI_IOS) #elif defined(VCMI_IOS)
//TODO #include "../server/CVCMIServer.h"
// todo ios
#else #else
#include "../lib/Interprocess.h" #include "../lib/Interprocess.h"
#endif #endif
@ -184,7 +185,18 @@ void CServerHandler::startLocalServerAndConnect()
envHelper.callStaticVoidMethod(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS, "startServer", true); envHelper.callStaticVoidMethod(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS, "startServer", true);
} }
#elif defined(VCMI_IOS) #elif defined(VCMI_IOS)
// TODO // todo ios: hide keyboard
logNetwork->info("[ios] create server thread");
boost::condition_variable cond;
threadRunLocalServer = std::make_shared<boost::thread>([&cond, this] {
setThreadName("CVCMIServer");
CVCMIServer::create(&cond);
// todo ios copypaste
threadRunLocalServer.reset();
CSH->campaignServerRestartLock.setn(false);
});
// threadRunLocalServer->detach();
logNetwork->info("[ios] detach server thread");
#else #else
threadRunLocalServer = std::make_shared<boost::thread>(&CServerHandler::threadRunServer, this); //runs server executable; threadRunLocalServer = std::make_shared<boost::thread>(&CServerHandler::threadRunServer, this); //runs server executable;
#endif #endif
@ -202,7 +214,14 @@ void CServerHandler::startLocalServerAndConnect()
logNetwork->info("waiting for server finished..."); logNetwork->info("waiting for server finished...");
androidTestServerReadyFlag = false; androidTestServerReadyFlag = false;
#elif defined(VCMI_IOS) #elif defined(VCMI_IOS)
//TODO // todo ios
{
boost::mutex m;
boost::unique_lock<boost::mutex> lock{m};
logNetwork->info("[ios] wait for server");
cond.wait(lock);
logNetwork->info("[ios] server ready");
}
#else #else
if(shm) if(shm)
shm->sr->waitTillReady(); shm->sr->waitTillReady();

View File

@ -126,6 +126,7 @@ void CTerrainRect::clickLeft(tribool down, bool previousState)
return; return;
#ifdef VCMI_ANDROID #ifdef VCMI_ANDROID
// todo ios
if(adventureInt->swipeEnabled) if(adventureInt->swipeEnabled)
{ {
if(handleSwipeStateChange((bool)down == true)) if(handleSwipeStateChange((bool)down == true))
@ -151,6 +152,7 @@ void CTerrainRect::clickLeft(tribool down, bool previousState)
void CTerrainRect::clickRight(tribool down, bool previousState) void CTerrainRect::clickRight(tribool down, bool previousState)
{ {
#ifdef VCMI_ANDROID #ifdef VCMI_ANDROID
// todo ios
if(adventureInt->swipeEnabled && isSwiping) if(adventureInt->swipeEnabled && isSwiping)
return; return;
#endif #endif
@ -180,6 +182,7 @@ void CTerrainRect::mouseMoved(const SDL_MouseMotionEvent & sEvent)
void CTerrainRect::handleSwipeMove(const SDL_MouseMotionEvent & sEvent) void CTerrainRect::handleSwipeMove(const SDL_MouseMotionEvent & sEvent)
{ {
#ifdef VCMI_ANDROID #ifdef VCMI_ANDROID
// todo ios
if(sEvent.state == 0) // any "button" is enough on android if(sEvent.state == 0) // any "button" is enough on android
#else //!VCMI_ANDROID #else //!VCMI_ANDROID
if((sEvent.state & SDL_BUTTON_MMASK) == 0) // swipe only works with middle mouse on other platforms if((sEvent.state & SDL_BUTTON_MMASK) == 0) // swipe only works with middle mouse on other platforms
@ -1050,6 +1053,7 @@ void CAdvMapInt::show(SDL_Surface * to)
handleSwipeUpdate(); handleSwipeUpdate();
} }
#ifdef VCMI_ANDROID // on android, map-moving mode is exclusive (TODO technically it might work with both enabled; to be checked) #ifdef VCMI_ANDROID // on android, map-moving mode is exclusive (TODO technically it might work with both enabled; to be checked)
// todo ios
else else
#endif // VCMI_ANDROID #endif // VCMI_ANDROID
{ {
@ -1452,6 +1456,7 @@ void CAdvMapInt::select(const CArmedInstance *sel, bool centerView)
void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent ) void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
{ {
#ifdef VCMI_ANDROID #ifdef VCMI_ANDROID
// todo ios
if(swipeEnabled) if(swipeEnabled)
return; return;
#endif #endif

View File

@ -5,11 +5,12 @@ ffmpegDir=~/dev/ios/vcmi-ios-deps/mobile-ffmpeg-min-universal
sdlLibsDir=~/dev/ios/vcmi-ios-deps/SDL2-lib sdlLibsDir=~/dev/ios/vcmi-ios-deps/SDL2-lib
srcDir="../vcmi" srcDir="../vcmi"
"${2:-cmake}" "$srcDir" -G "$1" \ /Users/Shared/xbmc-depends/x86_64-darwin19.6.0-native/bin/cmake "$srcDir" -G Xcode \
-DENABLE_LAUNCHER=0 \ -DENABLE_LAUNCHER=0 \
-Wno-dev \ -Wno-dev \
-DCMAKE_TOOLCHAIN_FILE="$srcDir/ios.toolchain.cmake" \ -DCMAKE_TOOLCHAIN_FILE="$srcDir/ios.toolchain.cmake" \
-DPLATFORM=OS64 \ -DPLATFORM=${1:-OS64} \
-DDEPLOYMENT_TARGET=9.0 \
-DENABLE_BITCODE=0 \ -DENABLE_BITCODE=0 \
-DCMAKE_BINARY_DIR=$(pwd) \ -DCMAKE_BINARY_DIR=$(pwd) \
-DCMAKE_PREFIX_PATH="$boostPrefix;$ffmpegDir;$sdlLibsDir" \ -DCMAKE_PREFIX_PATH="$boostPrefix;$ffmpegDir;$sdlLibsDir" \

View File

@ -389,7 +389,9 @@ class VCMIDirsIOS final : public VCMIDirsApple
std::vector<bfs::path> dataPaths() const override; std::vector<bfs::path> dataPaths() const override;
bfs::path libraryPath() const override; bfs::path libraryPath() const override;
boost::filesystem::path fullLibraryPath(const std::string & desiredFolder, const std::string & baseLibName) const override;
bfs::path binaryPath() const override; bfs::path binaryPath() const override;
bfs::path serverPath() const override;
bool developmentMode() const override; bool developmentMode() const override;
}; };
@ -398,10 +400,13 @@ bfs::path VCMIDirsIOS::userDataPath() const { return {ios_documentsPath()}; }
bfs::path VCMIDirsIOS::userCachePath() const { return {ios_cachesPath()}; } bfs::path VCMIDirsIOS::userCachePath() const { return {ios_cachesPath()}; }
bfs::path VCMIDirsIOS::userLogsPath() const { return {ios_documentsPath()}; } bfs::path VCMIDirsIOS::userLogsPath() const { return {ios_documentsPath()}; }
std::vector<bfs::path> VCMIDirsIOS::dataPaths() const { return {userDataPath()}; } std::vector<bfs::path> VCMIDirsIOS::dataPaths() const { return {binaryPath(), userDataPath()}; }
bfs::path VCMIDirsIOS::libraryPath() const { return {ios_frameworksPath()}; } bfs::path VCMIDirsIOS::libraryPath() const { return {ios_frameworksPath()}; }
// todo ios: place AI libs in subdir?
boost::filesystem::path VCMIDirsIOS::fullLibraryPath(const std::string & desiredFolder, const std::string & baseLibName) const { return libraryPath() / libraryName(baseLibName); }
bfs::path VCMIDirsIOS::binaryPath() const { return {ios_bundlePath()}; } bfs::path VCMIDirsIOS::binaryPath() const { return {ios_bundlePath()}; }
bfs::path VCMIDirsIOS::serverPath() const { return clientPath(); }
bool VCMIDirsIOS::developmentMode() const { return false; } bool VCMIDirsIOS::developmentMode() const { return false; }
#elif defined(VCMI_MAC) #elif defined(VCMI_MAC)

View File

@ -154,7 +154,9 @@ std::vector<const ISimpleResourceLoader *> CFilesystemList::getResourcesWithName
std::vector<const ISimpleResourceLoader *> ret; std::vector<const ISimpleResourceLoader *> ret;
for (auto & loader : loaders) for (auto & loader : loaders)
boost::range::copy(loader->getResourcesWithName(resourceName), std::back_inserter(ret)); // todo ios
if (loader)
boost::range::copy(loader->getResourcesWithName(resourceName), std::back_inserter(ret));
return ret; return ret;
} }

View File

@ -33,8 +33,15 @@ using namespace boost::asio::ip;
void CConnection::init() void CConnection::init()
{ {
socket->set_option(boost::asio::ip::tcp::no_delay(true)); socket->set_option(boost::asio::ip::tcp::no_delay(true));
socket->set_option(boost::asio::socket_base::send_buffer_size(4194304)); try
socket->set_option(boost::asio::socket_base::receive_buffer_size(4194304)); {
socket->set_option(boost::asio::socket_base::send_buffer_size(4194304));
socket->set_option(boost::asio::socket_base::receive_buffer_size(4194304));
}
catch (const boost::system::system_error & e)
{
logNetwork->error("error setting socket option: %s", e.what());
}
enableSmartPointerSerialization(); enableSmartPointerSerialization();
disableStackSendingByID(); disableStackSendingByID();

View File

@ -22,7 +22,11 @@ if(ANDROID) # android needs client/server to be libraries, not executables, so w
return() return()
endif() endif()
add_executable(vcmiserver ${server_SRCS} ${server_HEADERS}) if(APPLE_IOS)
add_library(vcmiserver STATIC ${server_SRCS} ${server_HEADERS})
else()
add_executable(vcmiserver ${server_SRCS} ${server_HEADERS})
endif()
set(server_LIBS vcmi) set(server_LIBS vcmi)
if(CMAKE_SYSTEM_NAME MATCHES FreeBSD) if(CMAKE_SYSTEM_NAME MATCHES FreeBSD)

View File

@ -30,7 +30,7 @@
#ifdef VCMI_ANDROID #ifdef VCMI_ANDROID
#include "lib/CAndroidVMHelper.h" #include "lib/CAndroidVMHelper.h"
#elif defined(VCMI_IOS) #elif defined(VCMI_IOS)
//TODO // todo ios
#else #else
#include "../lib/Interprocess.h" #include "../lib/Interprocess.h"
#endif #endif
@ -114,8 +114,8 @@ public:
} }
}; };
std::string NAME_AFFIX = "server"; std::string SERVER_NAME_AFFIX = "server";
std::string NAME = GameConstants::VCMI_VERSION + std::string(" (") + NAME_AFFIX + ')'; std::string SERVER_NAME = GameConstants::VCMI_VERSION + std::string(" (") + SERVER_NAME_AFFIX + ')';
CVCMIServer::CVCMIServer(boost::program_options::variables_map & opts) CVCMIServer::CVCMIServer(boost::program_options::variables_map & opts)
: port(3030), io(std::make_shared<boost::asio::io_service>()), state(EServerState::LOBBY), cmdLineOptions(opts), currentClientId(1), currentPlayerId(1), restartGameplay(false) : port(3030), io(std::make_shared<boost::asio::io_service>()), state(EServerState::LOBBY), cmdLineOptions(opts), currentClientId(1), currentPlayerId(1), restartGameplay(false)
@ -293,7 +293,7 @@ void CVCMIServer::connectionAccepted(const boost::system::error_code & ec)
try try
{ {
logNetwork->info("We got a new connection! :)"); logNetwork->info("We got a new connection! :)");
auto c = std::make_shared<CConnection>(upcomingConnection, NAME, uuid); auto c = std::make_shared<CConnection>(upcomingConnection, SERVER_NAME, uuid);
upcomingConnection.reset(); upcomingConnection.reset();
connections.insert(c); connections.insert(c);
c->handler = std::make_shared<boost::thread>(&CVCMIServer::threadHandleClient, this, c); c->handler = std::make_shared<boost::thread>(&CVCMIServer::threadHandleClient, this, c);
@ -901,6 +901,9 @@ static void handleCommandOptions(int argc, char * argv[], boost::program_options
} }
} }
#ifdef VCMI_IOS
#define main server_main
#endif
int main(int argc, char * argv[]) int main(int argc, char * argv[])
{ {
#if !defined(VCMI_ANDROID) && !defined(VCMI_IOS) #if !defined(VCMI_ANDROID) && !defined(VCMI_IOS)
@ -913,12 +916,19 @@ int main(int argc, char * argv[])
signal(SIGSEGV, handleLinuxSignal); signal(SIGSEGV, handleLinuxSignal);
#endif #endif
// todo ios: double console log
console = new CConsoleHandler(); console = new CConsoleHandler();
CBasicLogConfigurator logConfig(VCMIDirs::get().userLogsPath() / "VCMI_Server_log.txt", console); CBasicLogConfigurator logConfig(VCMIDirs::get().userLogsPath() / "VCMI_Server_log.txt", console);
logConfig.configureDefault(); logConfig.configureDefault();
logGlobal->info(NAME); logGlobal->info(SERVER_NAME);
boost::program_options::variables_map opts; boost::program_options::variables_map opts;
#ifdef VCMI_IOS
argc = 1;
boost::condition_variable * cond = reinterpret_cast<boost::condition_variable *>(argv[1]);
cond->notify_one();
//#endif
#else
handleCommandOptions(argc, argv, opts); handleCommandOptions(argc, argv, opts);
preinitDLL(console); preinitDLL(console);
settings.init(); settings.init();
@ -926,6 +936,8 @@ int main(int argc, char * argv[])
loadDLLClasses(); loadDLLClasses();
srand((ui32)time(nullptr)); srand((ui32)time(nullptr));
//#ifdef VCMI_IOS
#endif
try try
{ {
boost::asio::io_service io_service; boost::asio::io_service io_service;
@ -965,11 +977,17 @@ int main(int argc, char * argv[])
return 0; return 0;
} }
// TODO iOS
#ifdef VCMI_ANDROID #ifdef VCMI_ANDROID
void CVCMIServer::create() void CVCMIServer::create()
{ {
const char * foo[1] = {"android-server"}; const char * foo[1] = {"android-server"};
main(1, const_cast<char **>(foo)); main(1, const_cast<char **>(foo));
} }
#elif defined(VCMI_IOS)
void CVCMIServer::create(boost::condition_variable * cond)
{
const auto executablePath = VCMIDirs::get().serverPath();
void *argv[] = {const_cast<char *>(executablePath.c_str()), cond};
main(2, reinterpret_cast<char **>(argv));
}
#endif #endif

View File

@ -103,5 +103,7 @@ public:
#ifdef VCMI_ANDROID #ifdef VCMI_ANDROID
static void create(); static void create();
#elif defined(VCMI_IOS)
static void create(boost::condition_variable * cond);
#endif #endif
}; };