//--------------------------------------------------------------------------- #include "KPL_Start.h" #include "KPLTypes.h" #include "KPLFillModSpecific.h" #include "WriteScript.h" #include "GenerateScript.h" #ifndef __WIN32__ #include #include #endif #ifdef __WIN32__ #include "process.h"// For spawnlp #include #pragma package(smart_init) static DWORD processID=0; #else #include #include #include #include #define P_NOWAIT 0 static pid_t processID=0; static int spawnl(int flg, const char* file, const char* name, const char* arg1, const char* arg2) { int pid = fork(); if (pid == 0) { // We are in the son execlp(file, name, arg1, arg2, NULL); perror("execlp"); exit(1); } return pid; } #endif /* * Wait()s without blocking to cleanup exited children processes. * Returns: * -1 for error * 0 for no running children * 1 for running children */ static int cleanupWait() { if (!processID) return 0; #ifdef __WIN32__ HANDLE ProcessHandle; ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION,false,processID); if(ProcessHandle!=NULL) { // Spring is already running return 1; } #else pid_t termedProc = waitpid(processID, NULL, WNOHANG); if (termedProc == -1) { perror("waitpid"); return -1; } if (termedProc == 0) { // Spring is already running return 1; } processID = 0; #endif return 0; } int StartSpectator(void*) { return LaunchSpringExecutable(0); } int StartEasy(void*) { return LaunchSpringExecutable(1); } int StartMedium(void*) { return LaunchSpringExecutable(2); } int StartHard(void*) { return LaunchSpringExecutable(3); } int StartVeryHard(void*) { return LaunchSpringExecutable(4); } int StartMultiPlayer(void*) { if (cleanupWait() != 0) return 1; processID=spawnl(P_NOWAIT,cKPgame::ClientExecutableFileName,cKPgame::ClientExecutableFileName,"",NULL); return 0; } int StartSettings(void*) { if (cleanupWait() != 0) return 1; processID=spawnl(P_NOWAIT,cKPgame::SettingsExecutableFileName,cKPgame::SettingsExecutableFileName,"",NULL); return 0; } int LaunchSpringExecutable(int Difficulty) { // Check that Spring isn't already running if (cleanupWait() != 0) return 2; KPLFillModSpecific(); // Create and allocate "game" and its "players" and its "modoptions" cKPgame* game=(cKPgame*)malloc(sizeof(cKPgame)); game->players=(cKPplayer**)malloc(32*sizeof(cKPplayer*)); for(int p=0;p<32;++p) game->players[p]=(cKPplayer*)malloc(sizeof(cKPplayer)); game->ModOptions=(cKPmodoptions*)malloc(sizeof(cKPmodoptions)); // Generate a random script according to difficulty GenerateScript(game,Difficulty); // Writing that script on the disk WriteScript(game); #ifdef __WIN32__ Sleep(500); #endif free(game->ModOptions); for(int p=0;p<32;++p) free(game->players[p]); free(game->players); free(game); const char *scriptName = game->ScriptFileName; #ifndef __WIN32__ char fullName[256]; if (getcwd(fullName, sizeof(fullName) - strlen(game->ExecutableFileName) - 1) == NULL) { fprintf(stderr, "Current working directory too large\n"); return 1; } strcat(fullName, "/"); strcat(fullName, game->ScriptFileName); scriptName = fullName; #endif // Running Spring //ShellExecute(NULL,"open",game->ExecutableFileName,game->ScriptFileName,NULL,SW_SHOWNORMAL); processID=spawnl(P_NOWAIT,cKPgame::ExecutableFileName,game->ExecutableFileName,scriptName,NULL); // Check that Spring has run if (processID == -1) { perror("spawnl"); processID = 0; return 1; } //Application->Terminate(); return 0; }