Name") !== false) { $line_found = true; continue; } if($line_found) { $name = str_replace("", "", $line); $name = str_replace("", "", $name); $name = trim(preg_replace('/\t+/', '', $name)); $name = str_replace("\n", "", $name); break; } } fclose($handle); echo "Extracted provisioning profile name: $name\n"; return $name; } function xcode_archive_path() { global $GAME_ROOT; $GAME_PROJECT_NAME = taskman_prop("GAME_PROJECT_NAME"); return "$GAME_ROOT/build/xcode_archives/" . game_version() . "/{$GAME_PROJECT_NAME}"; } function xcode_ipa_path() { global $GAME_ROOT; $GAME_PROJECT_NAME = taskman_prop("GAME_PROJECT_NAME"); return "$GAME_ROOT/build/ipa/" . game_version() . "/{$GAME_PROJECT_NAME}.ipa"; } function xcode_ipa_adhoc_path() { global $GAME_ROOT; $GAME_PROJECT_NAME = taskman_prop("GAME_PROJECT_NAME"); return "$GAME_ROOT/build/ipa/" . game_version() . "/{$GAME_PROJECT_NAME}.ipa"; } function xcode_proj_dir() { global $GAME_ROOT; return "$GAME_ROOT/build_xcode"; } function ipa_path($flavor) { global $GAME_ROOT; $GAME_PROJECT_NAME = taskman_prop("GAME_PROJECT_NAME"); $project_version = taskman_prop("GAME_VERSION"); return "$GAME_ROOT/{$GAME_PROJECT_NAME}_{$flavor}_{$project_version}.ipa"; } function task_xcode_archive_postprocess() { $xcode_dir = xcode_proj_dir(); //temporary hack for GoogleUtilities $pod_lines = file("$xcode_dir/Podfile"); if(trim($pod_lines[2]) == '') $pod_lines[2] = "pod 'GoogleUtilities', '7.3.0'\n"; ensure_write("$xcode_dir/Podfile", implode('', $pod_lines)); taskman_shell_ensure( "cd $xcode_dir && " . "rm -rf Podfile.lock && " . "rm -rf Pods && " . "pod cache clean --all && " . "pod install --repo-update" ); $plist_file = "$xcode_dir/Info.plist"; //TODO: allowing ALL arbitrary loads for now (set via Unity Player Settings) //TODO: removing AdColony's flag that breaks our DLC download taskman_shell("/usr/libexec/Plistbuddy -c 'Delete NSAppTransportSecurity:NSAllowsArbitraryLoadsInWebContent' '$plist_file'"); } function resolve_ios_app_names() { global $GAME_ROOT; $ios_langs = taskman_prop("SUPPORTED_LANGUAGES_LIST"); $ios_name_default = taskman_prop("IOS_APP_NAME_DEFAULT"); $ios_names = taskman_prop("IOS_APP_NAMES_LOCALIZED"); $csv = ""; foreach($ios_langs as $lang) { $name = isset($ios_names[$lang]) ? $ios_names[$lang] : $ios_name_default; $csv .= "$lang;$name\n"; } $csv_path = "$GAME_ROOT/unity/Assets/Editor/ios_app_names.csv"; ensure_write($csv_path, $csv); } function is_incremental_ios_build($args) { return arg_exists($args, "-i"); } function task_install_ipa_to_device($args) { $ipa_path = isset($args[0]) ? $args[0] : ipa_path("adhoc"); $cmd = "ideviceinstaller -i $ipa_path"; taskman_shell_ensure($cmd); } //END_IOS_BLOCK //UNITY_BLOCK function task_unity_defines() { gen_smcs_rsp(); } function gen_smcs_rsp() { global $GAME_ROOT; $rsp_file = "$GAME_ROOT/Assets/csc.rsp"; $cs_file = "$GAME_ROOT/Assets/smcs.cs"; $rsp_str = taskman_prop("SMCS_DEFAULT_ARGS"); $unity_defines = array(); if(is_dev()) $unity_defines["GAME_IS_DEV"] = true; else $unity_defines["STRIP_LOGS"] = true; //Mediation defines $mediation = taskman_propor("ADS_MEDIATION", "null"); if(!empty($mediation)) { $unity_defines["APP_HAS_ADS"] = true; switch($mediation) { case "MoPub": $unity_defines["RND_MOPUB"] = true; break; case "AppLovin": $unity_defines["RND_MAX"] = true; break; default: echo " ==== WARNING ==== Unknown mediation: $mediation ==== WARNING ====\n"; } } if(taskman_propor('UNITY_CONNECT_PURCHASING', 0) > 0) $unity_defines["PURCHASING_IS_CONNECT"] = true; //end //SDK defines if(!empty(taskman_prop("TENJIN_KEY"))) $unity_defines["RND_TENJIN"] = true; if(!empty(taskman_prop("FACEBOOK_APP_ID"))) $unity_defines["RND_FACEBOOK"] = true; if(!empty(taskman_prop("GA_SETTINGS_ASSET"))) $unity_defines["RND_GAME_ANALYTICS"] = true; //end if(taskman_propor("USE_PROFILER", 0) == 1) { $unity_defines["STRIP_LOGS"] = true; $unity_defines["STRIP_ASSERTS"] = true; } foreach(explode(',', taskman_prop("SMCS_DEFINES")) as $define) $unity_defines[$define] = true; foreach(array_keys($unity_defines) as $define) { if($define) $rsp_str .= ' -define:' . $define; } //fix error associated with the transition to .NET 4 $rsp_str .= " -r:System.Web.dll"; if(!is_file($rsp_file) || ensure_read($rsp_file) !== $rsp_str) ensure_write($rsp_file, $rsp_str); if(need_to_regen($cs_file, array($rsp_file))) { $cs_str = "//THIS FILE IS AUTOGENERATED\npublic static class SmcsDefines { public static string DEFINES = \"$rsp_str\"; }"; ensure_write($cs_file, $cs_str); } } function task_setup_unity_player_settings() { global $GAME_ROOT; $settings_template = "$GAME_ROOT/ProjectSettings/ProjectSettings.asset-template"; $settings = "$GAME_ROOT/ProjectSettings/ProjectSettings.asset"; ensure_write_if_differs($settings, ensure_read($settings_template)); } function task_unity_kill() { $proc_id = unity_find_proc_id(); if($proc_id) { echo "Found Unity process '$proc_id', killing it...\n"; system("kill -9 $proc_id"); sleep(5); } else { echo "No Unity process found to kill\n"; } } function unity_find_proc_id() { global $GAME_ROOT; exec("ps aux | grep 'Unity' | grep -i 'projectpath' | grep -v grep", $out); foreach($out as $line) if(preg_match('~.*?\s+(\d+).*-projectpath\s+(.*?)\s+-~i', $line, $ms)) if(strpos(realpath($ms[2]), realpath($GAME_ROOT)) === 0) return $ms[1]; return null; } function task_unity() { $cmd = guess_unity_app_dir()."'Unity.app/Contents/MacOS/Unity' -projectPath . > /dev/null 2>&1&"; system($cmd, $res); } function task_make_client_settings() { make_client_settings(); } function make_client_settings() { global $GAME_ROOT; make_cs_settings(); $has_applovin = taskman_prop("ADS_MEDIATION") == "AppLovin"; taskman_propset("APPLOVIN_SPECIFIC_STUFF_STARTS_HERE", xml_block_start($has_applovin)); taskman_propset("APPLOVIN_SPECIFIC_STUFF_ELSE_HERE",$has_applovin ? xml_block_start($has_applovin == false) : xml_block_end($has_applovin)); taskman_propset("APPLOVIN_SPECIFIC_STUFF_END_HERE", $has_applovin ? xml_block_end($has_applovin == false) : ""); $has_mopub = taskman_propor("MOPUB_ADMOD_APP_ID", "") != ""; taskman_propset("MOPUB_SPECIFIC_STUFF_STARTS_HERE", xml_block_start($has_mopub)); taskman_propset("MOPUB_SPECIFIC_STUFF_ENDS_HERE" , xml_block_end ($has_mopub)); $has_facebook = taskman_propor("FACEBOOK_APP_ID", "") != ""; taskman_propset("FACEBOOK_SPECIFIC_STUFF_STARTS_HERE", xml_block_start($has_facebook)); taskman_propset("FACEBOOK_SPECIFIC_STUFF_ENDS_HERE" , xml_block_end ($has_facebook)); gen_build_file("$GAME_ROOT/Assets/Configs/in/AndroidManifest.xml.in", "$GAME_ROOT/Assets/Plugins/Android/AndroidManifest.xml"); gen_build_file("$GAME_ROOT/Assets/Configs/in/baseProjectTemplate.gradle.in", "$GAME_ROOT/Assets/Plugins/Android/baseProjectTemplate.gradle"); if(taskman_propor("GA_SETTINGS_ASSET", "") != "") { ensure_copy("$GAME_ROOT/" . taskman_prop("GA_SETTINGS_ASSET"), "$GAME_ROOT/Assets/Resources/GameAnalytics/Settings.asset"); } if(taskman_propor("ADVERTY_SETTINGS_ASSET", "") != "") { ensure_copy("$GAME_ROOT/" . taskman_prop("ADVERTY_SETTINGS_ASSET"), "$GAME_ROOT/Assets/Adverty/Resources/Data/AdvertySettings.asset"); } } function xml_block_start($enabled) { return $enabled ? "" : ""; } function make_cs_settings($force = false) { $settings_path = get_cs_settings_path(); if($force) ensure_rm($settings_path); gen_build_file("$settings_path.in", $settings_path); } function get_cs_settings_path() { global $GAME_ROOT; return "$GAME_ROOT/Assets/Scripts/Settings.cs"; } function unity_batch_exec($func, $build_target = "", $notify = true) { global $GAME_ROOT; try { list($log_file, $pid) = unity_exec($func, $build_target, /*$quit = */ true, /*$batchmode = */ true); watch_running_process($pid, $log_file, array( 'Exiting batchmode successfully' ), array( 'UnityException:', 'Aborting batchmode due to failure', 'Launching bug reporter', ': error CS', 'Unrecognized assets cannot be included in AssetBundles:' ) ); } catch(Exception $e) { throw $e; } } function unity_exec($func, $build_target = "", $quit = true, $batchmode = true) { global $GAME_ROOT; $proj_path = normalize_path("$GAME_ROOT/"); $log_file = "$GAME_ROOT/build/unity.log"; ensure_rm($log_file); $pid_file = "$GAME_ROOT/build/unity.pid"; ensure_rm($pid_file); $app_dir = taskman_prop('UNITY_APP_DIR'); echo "App dir: $app_dir\n"; $username = taskman_propor('UNITY_ACCOUNT_USERNAME', null); $password = taskman_propor('UNITY_ACCOUNT_PASSWORD', null); $shared_cmd = "-projectPath $proj_path -logFile $log_file " . ($batchmode ? "-batchmode" : "") . " -accept-apiupdate" . ($quit ? " -quit" : "") . ($build_target ? " -buildTarget $build_target" : "") . ($func != "" ? " -executeMethod $func" : ""); if($username !== null && $password !== null) $shared_cmd .= " -username '$username' -password '$password'"; $cmd = "$app_dir/Unity.app/Contents/MacOS/Unity $shared_cmd > /dev/null & echo $! > $pid_file"; exec($cmd, $output, $ret); if($ret !== 0) throw new Exception("Error starting cmd: $cmd"); $pid = trim(file_get_contents($pid_file)); while(!is_file($log_file)) usleep(200000); return array($log_file, $pid); } function arg_exists($args, $needle) { $strict = true; return in_array($needle, $args, $strict); } function should_autorun_on_device($args) { return arg_exists($args, "-r"); } function guess_unity_app_dir() { global $GAME_ROOT; if(getenv("UNITY_APP_DIR")) return getenv("UNITY_APP_DIR"); $path = "/Applications/Unity/"; if(is_win()) $path = getenv("ProgramFiles")."/Unity/"; $proj_version_file = $GAME_ROOT.'/ProjectSettings/ProjectVersion.txt'; if(is_file($proj_version_file)) { list($_, $unity_version) = array_map('trim', explode(":", file($proj_version_file)[0])); $path .= "Hub/Editor/$unity_version/"; } return $path; } function get_unity_dir() { $app_dir = taskman_prop('UNITY_APP_DIR'); if(is_win()) return "$app_dir/Editor/Data"; else return "$app_dir/Unity.app/Contents/"; } function mono_mcs_bin() { $unity_dir = get_unity_dir(); if(!is_dir($unity_dir)) throw new Exception("Unity directory doesn't exist: $unity_dir"); $canidates = array( "$unity_dir/Mono/bin/gmcs", "$unity_dir/MonoBleedingEdge/bin/mcs", "$unity_dir/Frameworks/Mono/bin/gmcs", "$unity_dir/Mono/bin/gmcs", ); foreach($canidates as $mcs_bin) { if(is_file($mcs_bin)) { if(is_win()) return '"' . normalize_path($mcs_bin, false) . '"'; else return $mcs_bin; } } throw new Exception("Mono compiler binary not found"); } function build_mono_dll($src_spec, $out_file, $ref_dlls = array(), $mcs_opts = "") { build_mono($src_spec, $out_file, $ref_dlls, "$mcs_opts -target:library"); } function build_mono($src_spec, $out_file, $ref_dlls = array(), $mcs_opts = "") { global $GAME_ROOT; $unity_dir = get_unity_dir(); $mcs_bin = mono_mcs_bin(); if(is_array($src_spec)) $sources = $src_spec; else if(is_dir($src_spec)) $sources = scan_files_rec(array($src_spec), array('.cs')); else $sources = glob($src_spec); $sources_str = ''; foreach($sources as $src) { if(is_win()) $sources_str .= '"'.normalize_path($src, !is_win()).'" '; else $sources_str .= '\''.normalize_path($src, !is_win()).'\' '; } $deps = $sources; $refs_str = ""; foreach($ref_dlls as $ref_dll) { if($ref_dll === "UnityEngine.dll") { $ref_dll = "$unity_dir/Managed/UnityEngine.dll"; if(!is_file($ref_dll)) $ref_dll = "$unity_dir/Frameworks/Managed/UnityEngine.dll"; } $ref_dll = normalize_path($ref_dll, !is_win()); $refs_str .= "-r:\"$ref_dll\" "; $deps[] = $ref_dll; } $out_file = normalize_path($out_file, !is_win()); $cmd = "$mcs_bin $mcs_opts $refs_str -out:$out_file $sources_str"; if(is_string($src_spec) && is_dir($src_spec)) $cmd = "cd $src_spec && $cmd"; $cmd_hash = crc32($cmd); $cmd_hash_file = "$GAME_ROOT/build/" . crc32($out_file) . ".mhash"; if(!is_file($cmd_hash_file) || file_get_contents($cmd_hash_file) != "$cmd_hash") file_put_contents($cmd_hash_file, "$cmd_hash"); $deps[] = $cmd_hash_file; if(need_to_regen($out_file, $deps)) { ensure_mkdir(dirname($out_file)); taskman_shell_ensure($cmd); echo "> $out_file " . round(filesize($out_file)/1024, 2) . "kb\n"; } } function run_mono($exe_file) { $app_dir = taskman_prop('UNITY_APP_DIR'); if(is_win()) { $unity_dir = "$app_dir/Editor/Data"; $mono_bin = '"' . normalize_path("$unity_dir/Mono/bin/mono", !is_win()) . '"'; } else { $unity_dir = "$app_dir/Unity.app/Contents/"; if(is_dir("$unity_dir/Frameworks/Mono")) $mono_bin = "$unity_dir/Frameworks/Mono/bin/mono"; else $mono_bin = "$unity_dir/Mono/bin/mono"; } $exe_file = normalize_path($exe_file, !is_win()); $mono_path = realpath(dirname($mono_bin) . '/../lib/mono/unity'); var_dump($mono_path); putenv("MONO_PATH=$mono_path"); //To LOCATION_PATH? $cmd = "$mono_bin $exe_file"; taskman_shell_ensure($cmd); } function build_option_exists($option) { return strpos(taskman_propor("BUILD_CLIENT_OPTS", ""), $option) !== FALSE; } function build_option_add($option) { if(build_option_exists($option)) return; $propname = "BUILD_CLIENT_OPTS"; $opts = taskman_propor($propname, ""); if(strlen($opts) > 0) $opts .= ",$option"; else $opts = $option; taskman_propset($propname, $opts); } function is_gradle_project_export() { return build_option_exists("AcceptExternalModificationsToPlayer"); } function task_setup_teamcity_settings($args = array()) { global $GAME_ROOT; $cmd = "git config --get remote.origin.url"; $url = str_replace("\n", "", shell_exec($cmd)); $name = "\"git: ${url}\""; taskman_propset("TEAM_CITY_SETTINGS_NAME_HERE", $name); taskman_propset("TEAM_CITY_SETTINGS_URL_HERE", "\"$url\""); gen_build_file("$GAME_ROOT/Assets/Configs/in/settings.kts.in", "$GAME_ROOT/.teamcity/settings.kts"); } //END_UNITY_BLOCK