diff --git a/Info.plist b/Info.plist index f82ec6a6a..14c1b198d 100644 --- a/Info.plist +++ b/Info.plist @@ -49,6 +49,10 @@ NSAllowsArbitraryLoads + UIBackgroundModes + + audio + UIDeviceFamily 1 diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index cf8efef1a..20b19af97 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -177,9 +177,7 @@ if(WIN32) target_compile_definitions(vcmiclient PRIVATE WINDOWS_IGNORE_PACKING_MISMATCH) elseif(APPLE_IOS) target_link_libraries(vcmiclient PRIVATE - vcmiserver - # SDL2_image: - "-framework Foundation -framework UIKit -framework QuartzCore -framework CoreGraphics -framework CoreServices -framework ImageIO" + "-framework Foundation -framework UIKit -framework QuartzCore -framework CoreGraphics -framework CoreServices -framework ImageIO" # SDL2_image ) target_sources(vcmiclient PRIVATE ${CMAKE_SOURCE_DIR}/client/LaunchScreen.storyboard) diff --git a/client/CServerHandler.cpp b/client/CServerHandler.cpp index 39024dc1b..93d44cefa 100644 --- a/client/CServerHandler.cpp +++ b/client/CServerHandler.cpp @@ -24,8 +24,7 @@ #ifdef VCMI_ANDROID #include "../lib/CAndroidVMHelper.h" #elif defined(VCMI_IOS) -#include "../server/CVCMIServer.h" -// todo ios +//TODO #else #include "../lib/Interprocess.h" #endif @@ -185,18 +184,7 @@ void CServerHandler::startLocalServerAndConnect() envHelper.callStaticVoidMethod(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS, "startServer", true); } #elif defined(VCMI_IOS) - // todo ios: hide keyboard - logNetwork->info("[ios] create server thread"); - boost::condition_variable cond; - threadRunLocalServer = std::make_shared([&cond, this] { - setThreadName("CVCMIServer"); - CVCMIServer::create(&cond); - // todo ios copypaste - threadRunLocalServer.reset(); - CSH->campaignServerRestartLock.setn(false); - }); -// threadRunLocalServer->detach(); - logNetwork->info("[ios] detach server thread"); + // TODO #else threadRunLocalServer = std::make_shared(&CServerHandler::threadRunServer, this); //runs server executable; #endif @@ -214,14 +202,7 @@ void CServerHandler::startLocalServerAndConnect() logNetwork->info("waiting for server finished..."); androidTestServerReadyFlag = false; #elif defined(VCMI_IOS) - // todo ios - { - boost::mutex m; - boost::unique_lock lock{m}; - logNetwork->info("[ios] wait for server"); - cond.wait(lock); - logNetwork->info("[ios] server ready"); - } + //TODO #else if(shm) shm->sr->waitTillReady(); diff --git a/lib/VCMIDirs.cpp b/lib/VCMIDirs.cpp index c8c523fb8..5a59ff03e 100644 --- a/lib/VCMIDirs.cpp +++ b/lib/VCMIDirs.cpp @@ -391,7 +391,6 @@ class VCMIDirsIOS final : public VCMIDirsApple 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 serverPath() const override; bool developmentMode() const override; }; @@ -431,7 +430,6 @@ boost::filesystem::path VCMIDirsIOS::fullLibraryPath(const std::string & desired #endif } bfs::path VCMIDirsIOS::binaryPath() const { return {ios_bundlePath()}; } -bfs::path VCMIDirsIOS::serverPath() const { return clientPath(); } bool VCMIDirsIOS::developmentMode() const { return false; } #elif defined(VCMI_MAC) diff --git a/package_ios.sh b/package_ios.sh index 849d4dc3a..5240b74a1 100755 --- a/package_ios.sh +++ b/package_ios.sh @@ -2,18 +2,20 @@ pushd bin/Debug mkdir -p vcmiclient.app/Frameworks -cp *.dylib AI/*.dylib vcmiclient.app -badInstallNamePrefix=$(pwd) -cd vcmiclient.app +productsDir=$(pwd) sdl2Path=~/dev/ios/vcmi-ios-deps/SDL2-lib/lib -cp "$sdl2Path/libSDL2.dylib" . -install_name_tool -rpath "$sdl2Path" '@executable_path/Frameworks' vcmiclient +for app in vcmiclient vcmiserver; do + install_name_tool -rpath "$sdl2Path" '@executable_path/Frameworks' "$productsDir/$app.app/$app" +done + +cp *.dylib AI/*.dylib "$sdl2Path/libSDL2.dylib" vcmiclient.app +cd vcmiclient.app for b in vcmiclient *.dylib; do for l in minizip vcmi; do libName="lib${l}.dylib" - install_name_tool -change "$badInstallNamePrefix/$libName" "@rpath/$libName" "$b" + install_name_tool -change "$productsDir/$libName" "@rpath/$libName" "$b" done if [ "$b" != vcmiclient ]; then install_name_tool -id "@rpath/$b" "$b" @@ -23,5 +25,15 @@ done mv -f *.dylib Frameworks popd -cp -f ../vcmi/Info.plist "$badInstallNamePrefix/vcmiclient.app" -cp -R bin/Debug-iphoneos/* "$badInstallNamePrefix/vcmiclient.app" +for app in vcmiclient vcmiserver; do + cp -f ../vcmi/Info.plist "$productsDir/$app.app" +done +sed -i '' -e 's/client/server/g' -e 's/>VCMIVCMI server()), 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 { logNetwork->info("We got a new connection! :)"); - auto c = std::make_shared(upcomingConnection, SERVER_NAME, uuid); + auto c = std::make_shared(upcomingConnection, NAME, uuid); upcomingConnection.reset(); connections.insert(c); c->handler = std::make_shared(&CVCMIServer::threadHandleClient, this, c); @@ -920,14 +920,9 @@ int main(int argc, char * argv[]) console = new CConsoleHandler(); CBasicLogConfigurator logConfig(VCMIDirs::get().userLogsPath() / "VCMI_Server_log.txt", console); logConfig.configureDefault(); - logGlobal->info(SERVER_NAME); + logGlobal->info(NAME); - boost::program_options::variables_map opts; -#ifdef VCMI_IOS - argc = 1; - boost::condition_variable * cond = reinterpret_cast(argv[1]); - cond->notify_one(); -#else + boost::program_options::variables_map opts; handleCommandOptions(argc, argv, opts); preinitDLL(console); settings.init(); @@ -935,7 +930,6 @@ int main(int argc, char * argv[]) loadDLLClasses(); srand((ui32)time(nullptr)); -#endif try { boost::asio::io_service io_service; @@ -975,17 +969,10 @@ int main(int argc, char * argv[]) return 0; } -#ifdef VCMI_ANDROID +#if defined(VCMI_ANDROID) || defined(VCMI_IOS) void CVCMIServer::create() { const char * foo[1] = {"android-server"}; main(1, const_cast(foo)); } -#elif defined(VCMI_IOS) -void CVCMIServer::create(boost::condition_variable * cond) -{ - const auto executablePath = VCMIDirs::get().serverPath(); - void *argv[] = {const_cast(executablePath.c_str()), cond}; - main(2, reinterpret_cast(argv)); -} #endif diff --git a/server/CVCMIServer.h b/server/CVCMIServer.h index 5e68c62eb..7cd84eb46 100644 --- a/server/CVCMIServer.h +++ b/server/CVCMIServer.h @@ -101,9 +101,7 @@ public: ui8 getIdOfFirstUnallocatedPlayer() const; -#ifdef VCMI_ANDROID +#if defined(VCMI_ANDROID) || defined(VCMI_IOS) static void create(); -#elif defined(VCMI_IOS) - static void create(boost::condition_variable * cond); #endif }; diff --git a/server/main_ios.mm b/server/main_ios.mm new file mode 100644 index 000000000..ec28d8c64 --- /dev/null +++ b/server/main_ios.mm @@ -0,0 +1,63 @@ +/* + * main_ios.mm, 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 + * + */ +#import +#import + +//#include "StdInc.h" +#include "../Global.h" +#include "CVCMIServer.h" + +@interface ViewController : UIViewController +@end + +@implementation ViewController +@end + + +@interface AppDelegate : UIResponder +@property (nonatomic, strong) UIWindow *window; +@property (nonatomic, strong) AVPlayerLooper *looper; +@end + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds]; + self.window.rootViewController = [ViewController new]; + [self.window makeKeyAndVisible]; + + [AVAudioSession.sharedInstance setCategory:AVAudioSessionCategoryPlayback mode:AVAudioSessionModeDefault options:AVAudioSessionCategoryOptionMixWithOthers error:nullptr]; + + auto item = [AVPlayerItem playerItemWithURL:[NSBundle.mainBundle URLForResource:@"silence" withExtension:@"wav"]]; + auto player = [AVQueuePlayer new]; + player.allowsExternalPlayback = NO; + [player play]; + self.looper = [AVPlayerLooper playerLooperWithPlayer:player templateItem:item]; + + [NSThread detachNewThreadWithBlock:^ + { + NSThread.currentThread.name = @"CVCMIServer"; + NSLog(@"starting server from thread %@", NSThread.currentThread); + CVCMIServer::create(); + }]; + return YES; +} + +@end + + +int main(int argc, char * argv[]) +{ + @autoreleasepool + { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +}