SamsonGame/gamectl.d/client.php

824 lines
21 KiB
PHP
Raw Normal View History

2021-12-29 20:50:11 +03:00
<?php
//ANDROID_BLOCK
/**
* @deps urun,unity_kill
*/
function task_build_android($args = array())
{
global $GAME_ROOT;
ensure_mkdir("$GAME_ROOT/build");
foreach(glob(android_path('*.apk')) as $apk)
ensure_rm($apk);
foreach(glob(android_path('*.aab')) as $aab)
ensure_rm($aab);
$apk_full_name = apk_full_name();
$apk_path = android_path($apk_full_name);
putenv("LOCATION_PATH=$apk_path");
if(should_autorun_on_device($args))
unity_batch_exec("BuildUtils.BuildAPKAndRun", "android");
else
unity_batch_exec("BuildUtils.BuildAPKOnly", "android");
extract_apk_from_aab();
}
function extract_apk_from_aab()
{
global $GAME_ROOT;
$aab_full_name = aab_full_name();
$aab_path = android_path($aab_full_name);
$apks_path = "\"$GAME_ROOT/build/app.apks\"";
if(!is_file($aab_path))
throw new Exception("Result .aab not found at '$aab_path'");
$cmd = "bundletool build-apks --bundle={$aab_path} --output={$apks_path} "
. "--overwrite "
. "--mode=universal "
. "--ks={$GAME_ROOT}/user-key-store.keystore "
. "--ks-pass=pass:WV7fx6pRykCk "
. "--ks-key-alias=android-build "
. "--key-pass=pass:WV7fx6pRykCk";
taskman_shell_ensure($cmd);
$output_dir = "$GAME_ROOT/build/android/";
taskman_shell_ensure("unzip -o $apks_path -d \"$output_dir\"");
$standalone_files = scan_files_rec(array($output_dir), array('.apk'));
$apk_full_name = apk_full_name();
$apk_path = android_path($apk_full_name);
foreach($standalone_files as $file)
{
echo "Copy $file to $apk_path\n";
ensure_copy($file, $apk_path);
}
}
function android_path($name)
{
global $GAME_ROOT;
return "$GAME_ROOT/$name";
}
function apk_full_name()
{
$project_name = taskman_propor("GAME_PROJECT_NAME", "game");
$version = taskman_prop("GAME_VERSION");
$flavor = taskman_prop("ANDROID_TARGET_STORE");
return "{$project_name}_{$flavor}_{$version}.apk";
}
function aab_full_name()
{
$apk_full_name = apk_full_name();
return str_replace("apk", "aab", $apk_full_name);
}
function task_install_apk_to_device($args)
{
$apk_path = isset($args[0]) ? $args[0] : android_path(apk_full_name());
$cmd = "adb install -r $apk_path";
taskman_shell_ensure($cmd);
}
//END_ANDROID_BLOCK
//IOS_BLOCK
/**
* @deps urun,unity_kill,build_xcode,xcode_archive,xcode_archive_postprocess
*/
function task_build_ios($args)
{
xcode_export_ipa('adhoc');
xcode_export_ipa('appstore');
}
function task_build_xcode($args)
{
if(should_autorun_on_device($args))
build_option_add("AutoRunPlayer");
if(is_incremental_ios_build($args))
build_option_add("AcceptExternalModificationsToPlayer");
make_cs_settings(true/*force*/);
putenv("LOCATION_PATH=build_xcode");
unity_batch_exec("BuildUtils.BuildXCodeProjectClean", "ios");
}
function xcode_export_ipa($flavor)
{
global $GAME_ROOT;
$ipa_source = task_sign_ipa(array($flavor));
$ipa_dest = ipa_path($flavor);
ensure_copy($ipa_source, $ipa_dest);
taskman_shell_ensure("chmod 0644 $ipa_dest");
}
function xcode_archive()
{
global $GAME_ROOT;
taskman_shell_ensure("rm -rf ~/Library/Developer/Xcode/DerivedData");
$archive_path = xcode_archive_path();
$ipa_path = xcode_ipa_path();
ensure_mkdir(dirname($archive_path));
ensure_mkdir(dirname($ipa_path));
if(is_file($ipa_path))
rename($ipa_path, "$ipa_path.bak");
$xcode_dir = xcode_proj_dir();
taskman_shell_ensure(
"cd $xcode_dir && " .
"xcodebuild -UseNewBuildSystem=NO -workspace Unity-iPhone.xcworkspace -scheme Unity-iPhone -configuration Release clean && " .
"xcodebuild -UseNewBuildSystem=NO -workspace Unity-iPhone.xcworkspace -scheme Unity-iPhone -jobs 4 -archivePath $archive_path archive "
);
ensure_rm("$ipa_path.bak");
}
function task_xcode_archive()
{
xcode_archive();
}
function task_sign_ipa($args = array())
{
global $GAME_ROOT;
if(!isset($args[0]))
throw new Exception("Invalid provisioning");
$provisioning = $args[0];
$ipa_path_raw = xcode_ipa_path();
$xcode_proj_name = "Unity-iPhone";
$exported_file_appendix = "/$xcode_proj_name.ipa";
$ipa_path = "$ipa_path_raw$exported_file_appendix";
$ipa_source = str_replace($xcode_proj_name, $xcode_proj_name.'_'.$provisioning, $ipa_path);
$ipa_source_no_suffix = str_replace('.ipa', '_'.$provisioning.'.ipa', $ipa_path_raw);
try
{
ensure_rm($ipa_source_no_suffix);
$profile = "";
$entitlements = "entitlements.$provisioning.plist";
$profile = "$provisioning.mobileprovision";
$is_appstore = $provisioning == "appstore";
$xcode_dir = xcode_proj_dir();
$archive_path = xcode_archive_path();
$opts_plist = "$GAME_ROOT/maint/ios/export_ipa_options_$provisioning.plist";
gen_file("$opts_plist.in", "$opts_plist", array("$opts_plist.in"), true);
taskman_shell_ensure(
"cd $xcode_dir && " .
"xcodebuild -allowProvisioningUpdates -UseNewBuildSystem=NO -exportArchive -archivePath $archive_path.xcarchive -exportPath $ipa_path_raw -exportOptionsPlist $opts_plist"
);
$package_id_parts = explode(".", taskman_prop("PACKAGE_ID_FULL_IOS"));
$exported_ipa_name = $package_id_parts[count($package_id_parts)-1];
$ipa_path = str_replace($xcode_proj_name, $exported_ipa_name, $ipa_path);
if(!is_file($ipa_path))
throw new Exception(".ipa doesn't exist");
ensure_copy($ipa_path, $ipa_source);
if(!$is_appstore)
task_gen_install_adhoc_plist();
}
catch(Exception $e)
{
throw $e;
}
taskman_shell_ensure("chmod +r ".$ipa_source);
taskman_shell_ensure("mv $ipa_source $ipa_source_no_suffix");
return $ipa_source_no_suffix;
}
function task_gen_install_adhoc_plist()
{
gen_install_adhoc_plist();
}
function gen_install_adhoc_plist()
{
global $GAME_ROOT;
taskman_propset("PLIST_INSTALL_ADHOC_URL_RAND", taskman_prop("PLIST_INSTALL_ADHOC_URL") . "?v=" . mt_rand());
$install_adhoc_plist = "$GAME_ROOT/maint/ios/install_adhoc.plist";
gen_file("$install_adhoc_plist.in", "$install_adhoc_plist", array("$install_adhoc_plist.in"), true);
taskman_shell_ensure("chmod +r $install_adhoc_plist");
}
function extract_provisionin_profile_name($profile)
{
global $GAME_ROOT;
$profile_file = "$GAME_ROOT/maint/ios/$profile";
$line_found = false;
$name = "";
$handle = fopen($profile_file, "r");
if(!$handle)
throw new Exception("Failed to read $profile_file");
//FIXME: poor man's parsing
while(($line = fgets($handle)) !== false)
{
if(strpos($line, "<key>Name</key>") !== false)
{
$line_found = true;
continue;
}
if($line_found)
{
$name = str_replace("<string>", "", $line);
$name = str_replace("</string>", "", $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 xml_block_end($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