diff --git a/.github/workflows/noop.yml b/.github/workflows/noop.yml new file mode 100644 index 0000000000..28f8b607dc --- /dev/null +++ b/.github/workflows/noop.yml @@ -0,0 +1,9 @@ +name: noop +run-name: noop🚀 +on: [push] +jobs: + noop: + runs-on: ubuntu-latest + steps: + - run: echo "done" + diff --git a/.gitignore b/.gitignore index 73ce58daea..2a63ff51fc 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,9 @@ config/reloadalas test.py test/ +!config/alas.json +.DS_Store + # Created by .ignore support plugin (hsz.mobi) ### JetBrains template @@ -178,7 +181,7 @@ profile_default/ ipython_config.py # pyenv -.python-version +# .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. diff --git a/.python-version b/.python-version new file mode 100644 index 0000000000..168da0f593 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.8.20 \ No newline at end of file diff --git a/alas.py b/alas.py index 6268c638a7..2af37ccebc 100644 --- a/alas.py +++ b/alas.py @@ -72,7 +72,7 @@ def run(self, command, skip_first_screenshot=False): return True except GameNotRunningError as e: logger.warning(e) - self.config.task_call('Restart') + self.start() return False except (GameStuckError, GameTooManyClickError) as e: logger.error(e) @@ -476,17 +476,19 @@ def get_next_task(self): self.is_first_task = False method = self.config.Optimization_WhenTaskQueueEmpty if method == 'close_game': - logger.info('Close game during wait') - self.device.app_stop() + logger.info('Go home during wait') + time.sleep(5) + self.run('goto_main') + self.device.go_home() release_resources() self.device.release_during_wait() if not self.wait_until(task.next_run): del_cached_property(self, 'config') continue - if task.command != 'Restart': - self.config.task_call('Restart') - del_cached_property(self, 'config') - continue + # if task.command != 'Restart': + # self.config.task_call('Restart') + # del_cached_property(self, 'config') + # continue elif method == 'goto_main': logger.info('Goto main page during wait') self.run('goto_main') diff --git a/assets/jp/combat/GET_ITEMS_1.png b/assets/jp/combat/GET_ITEMS_1.png index 1c68ab63ca..3147e6bc37 100644 Binary files a/assets/jp/combat/GET_ITEMS_1.png and b/assets/jp/combat/GET_ITEMS_1.png differ diff --git a/assets/jp/combat/GET_ITEMS_2.png b/assets/jp/combat/GET_ITEMS_2.png index 91d02538b5..2580e2a5b8 100644 Binary files a/assets/jp/combat/GET_ITEMS_2.png and b/assets/jp/combat/GET_ITEMS_2.png differ diff --git a/assets/jp/combat/GET_ITEMS_3.png b/assets/jp/combat/GET_ITEMS_3.png index 8748a7e5ba..3cccc1094b 100644 Binary files a/assets/jp/combat/GET_ITEMS_3.png and b/assets/jp/combat/GET_ITEMS_3.png differ diff --git a/assets/jp/gacha/BUILD_FINISH_RESULTS.png b/assets/jp/gacha/BUILD_FINISH_RESULTS.png index a719ec55a8..6c88e5be91 100644 Binary files a/assets/jp/gacha/BUILD_FINISH_RESULTS.png and b/assets/jp/gacha/BUILD_FINISH_RESULTS.png differ diff --git a/conda.yml b/conda.yml new file mode 100644 index 0000000000..4c7547f28e --- /dev/null +++ b/conda.yml @@ -0,0 +1,218 @@ +name: alas +channels: + - anaconda + - conda-forge +dependencies: + - _mutex_mxnet=0.0.50=openblas + - aiofiles=22.1.0=py38hca03da5_0 + - anyio=1.3.1=py_0 + - aom=3.5.0=h7ea286d_0 + - asgiref=3.5.2=py38hca03da5_0 + - async_generator=1.10=pyhd3eb1b0_0 + - attrs=23.1.0=py38hca03da5_0 + - av=10.0.0=py38h846960b_3 + - blas=1.0=openblas + - brotli-python=1.0.9=py38hc377ac9_7 + - bzip2=1.0.8=h93a5062_5 + - c-ares=1.19.1=h80987f9_0 + - ca-certificates=2024.2.2=hf0a4a13_0 + - cairo=1.16.0=h302bd0f_5 + - certifi=2024.2.2=pyhd8ed1ab_0 + - cffi=1.16.0=py38h80987f9_0 + - charset-normalizer=2.0.4=pyhd3eb1b0_0 + - click=8.1.7=py38hca03da5_0 + - colorama=0.4.6=py38hca03da5_0 + - commonmark=0.9.1=pyhd3eb1b0_0 + - cryptography=41.0.3=py38hd4332d6_0 + - curio=1.4=pyhd3eb1b0_0 + - cyrus-sasl=2.1.28=h9131b1a_1 + - dataclasses=0.8=pyh6d0b6a4_7 + - eigen=3.3.7=h525c30c_1 + - exceptiongroup=1.0.4=py38hca03da5_0 + - expat=2.5.0=h313beb8_0 + - ffmpeg=5.1.2=gpl_hf318d42_106 + - font-ttf-dejavu-sans-mono=2.37=hd3eb1b0_0 + - font-ttf-inconsolata=2.001=hcb22688_0 + - font-ttf-source-code-pro=2.030=hd3eb1b0_0 + - font-ttf-ubuntu=0.83=h8b1ccd4_0 + - fontconfig=2.14.1=hee714a5_2 + - fonts-anaconda=1=h8fa9717_0 + - fonts-conda-ecosystem=1=hd3eb1b0_0 + - freetype=2.12.1=h1192e45_0 + - future=0.18.3=py38hca03da5_0 + - gettext=0.22.5=h8fbad5d_2 + - gettext-tools=0.22.5=h8fbad5d_2 + - giflib=5.2.1=h80987f9_3 + - glib=2.69.1=h514c7bf_2 + - gmp=6.2.1=hc377ac9_3 + - gnutls=3.7.9=hd26332c_0 + - graphite2=1.3.14=hc377ac9_1 + - gst-plugins-base=1.14.1=h313beb8_1 + - gstreamer=1.14.1=h80987f9_1 + - h11=0.12.0=pyhd3eb1b0_0 + - harfbuzz=4.3.0=he9eebac_1 + - hdf5=1.12.1=h05c076b_3 + - icu=68.1=hc377ac9_0 + - idna=3.4=py38hca03da5_0 + - imageio=2.27.0=pyh24c5eb1_0 + - importlib-metadata=6.0.0=py38hca03da5_0 + - inflection=0.5.1=py38hca03da5_0 + - jellyfish=0.11.2=py38hd0c8013_0 + - jpeg=9e=h80987f9_1 + - krb5=1.20.1=hf3e1bf2_1 + - lame=3.100=h1a28f6b_0 + - lcms2=2.12=hba8e193_0 + - lerc=3.0=hc377ac9_0 + - libasprintf=0.22.5=h8fbad5d_2 + - libasprintf-devel=0.22.5=h8fbad5d_2 + - libblas=3.9.0=1_h2ec9a88_netlib + - libcblas=3.9.0=5_h880f123_netlib + - libclang=14.0.6=default_h1b80db6_1 + - libclang13=14.0.6=default_h24352ff_1 + - libcurl=7.88.1=h3e2b118_2 + - libcxx=16.0.6=h4653b0c_0 + - libdeflate=1.17=h80987f9_1 + - libedit=3.1.20221030=h80987f9_0 + - libev=4.33=h1a28f6b_1 + - libffi=3.4.2=h3422bc3_5 + - libgettextpo=0.22.5=h8fbad5d_2 + - libgettextpo-devel=0.22.5=h8fbad5d_2 + - libgfortran=5.0.0=12_2_0_hd922786_32 + - libgfortran5=12.2.0=h0eea778_32 + - libiconv=1.17=h0d3ecfb_2 + - libidn2=2.3.4=h80987f9_0 + - libintl=0.22.5=h8fbad5d_2 + - libintl-devel=0.22.5=h8fbad5d_2 + - liblapack=3.9.0=5_h880f123_netlib + - libllvm14=14.0.6=h7ec7a93_3 + - libmxnet=1.5.1=openblas_h34268ac_0 + - libnghttp2=1.57.0=h62f6fdd_0 + - libopenblas=0.3.23=openmp_hc731615_0 + - libopus=1.3.1=h27ca646_1 + - libpng=1.6.39=h80987f9_0 + - libpq=12.15=h02f6b3c_1 + - libsodium=1.0.18=h1a28f6b_0 + - libsqlite=3.45.2=h091b4b1_0 + - libssh2=1.10.0=h02f6b3c_2 + - libtasn1=4.19.0=h80987f9_0 + - libtiff=4.5.1=h313beb8_0 + - libunistring=0.9.10=h1a28f6b_0 + - libvpx=1.11.0=hc377ac9_0 + - libwebp=1.3.2=ha3663a8_0 + - libwebp-base=1.3.2=h80987f9_0 + - libxml2=2.10.4=h372ba2a_0 + - libxslt=1.1.37=habca612_0 + - libzlib=1.2.13=h53f4e23_5 + - llvm-openmp=20.1.2=hdb05f8b_0 + - lxml=4.9.2=py38h43d3e64_0 + - lz4=4.3.2=py38h80987f9_0 + - lz4-c=1.9.4=h313beb8_0 + - mxnet=1.5.1=hca03da5_0 + - mysql=5.7.24=ha71a6ea_2 + - ncurses=6.4.20240210=h078ce10_0 + - nettle=3.9.1=h40ed0f5_0 + - numpy=1.24.4=py38ha84db1f_0 + - openblas=0.3.23=openmp_hf78f355_0 + - opencv=4.6.0=py38h8794c10_2 + - openh264=2.3.1=hb7217d7_2 + - openjpeg=2.3.0=h7a6adac_2 + - openssl=3.2.1=h0d3ecfb_1 + - outcome=1.1.0=pyhd3eb1b0_0 + - p11-kit=0.24.1=h29577a5_0 + - packaging=24.1=py38hca03da5_0 + - pcre=8.45=hc377ac9_0 + - pillow=10.0.1=py38h3b245a6_0 + - pip=24.0=pyhd8ed1ab_0 + - pixman=0.40.0=h1a28f6b_0 + - platformdirs=3.10.0=py38hca03da5_0 + - pooch=1.7.0=py38hca03da5_0 + - prettytable=2.2.1=pyhd8ed1ab_0 + - psutil=5.9.3=py38hb991d35_1 + - py-mxnet=1.5.1=py38h3f2eb1c_0 + - pycparser=2.21=pyhd3eb1b0_0 + - pydantic=1.10.12=py38h80987f9_1 + - pygments=2.15.1=py38hca03da5_1 + - pyopenssl=23.2.0=py38hca03da5_0 + - pysocks=1.7.1=py38hca03da5_0 + - python=3.8.19=h2469fbe_0_cpython + - python_abi=3.8=4_cp38 + - pyyaml=6.0.1=py38h80987f9_0 + - pyzmq=22.3.0=py38hc377ac9_2 + - qt-main=5.15.2=h9b4df51_9 + - qt-webengine=5.15.9=h2903aaf_7 + - qtwebkit=5.212=h19f419d_5 + - readline=8.2=h92ec313_1 + - requests=2.31.0=py38hca03da5_0 + - retrying=1.3.3=pyhd3eb1b0_2 + - rich=11.2.0=pyhd8ed1ab_0 + - scipy=1.10.1=py38h9d039d2_1 + - setuptools=69.2.0=pyhd8ed1ab_0 + - six=1.16.0=pyhd3eb1b0_1 + - sniffio=1.2.0=py38hca03da5_1 + - sortedcontainers=2.4.0=pyhd3eb1b0_0 + - sqlite=3.41.2=h80987f9_0 + - starlette=0.14.2=pyhd8ed1ab_0 + - svt-av1=1.4.1=h7ea286d_0 + - tk=8.6.13=h5083fa2_1 + - tqdm=4.65.0=py38h86d0a89_0 + - trio=0.22.0=py38hca03da5_0 + - typing-extensions=4.7.1=py38hca03da5_0 + - typing_extensions=4.7.1=py38hca03da5_0 + - urllib3=1.26.18=py38hca03da5_0 + - uvicorn=0.17.6=py38h10201cd_1 + - wcwidth=0.2.5=pyhd3eb1b0_0 + - websockets=12.0=py38h336bac9_0 + - wheel=0.43.0=pyhd8ed1ab_1 + - wrapt=1.13.1=py38hea4295b_0 + - x264=1!164.3095=h57fd34a_2 + - x265=3.5=hbc6ce65_3 + - xz=5.4.2=h80987f9_0 + - yaml=0.2.5=h1a28f6b_0 + - zeromq=4.3.4=hc377ac9_0 + - zipp=3.11.0=py38hca03da5_0 + - zlib=1.2.13=h53f4e23_5 + - zstd=1.5.5=hd90d995_0 + - pip: + - Deprecated==1.2.14 + - adbutils==0.11.0 + - alas-webapp==0.3.7.0 + - apkutils2==1.0.0 + - cached-property==1.5.2 + - cigam==0.0.3 + - cnocr==1.2.3 + - contourpy==1.1.1 + - cycler==0.12.1 + - decorator==5.1.1 + - deprecation==2.1.0 + - filelock==3.13.4 + - fonttools==4.51.0 + - gevent==24.2.1 + - gluoncv==0.6.0 + - greenlet==3.0.3 + - importlib_resources==6.4.0 + - kiwisolver==1.4.5 + - logzero==1.7.0 + - matplotlib==3.7.5 + - msgpack==1.0.8 + - onepush==1.3.0 + - packaging==20.9 + - portalocker==2.8.2 + - progress==1.6 + - py==1.11.0 + - pycryptodome==3.20.0 + - pyelftools==0.31 + - pyparsing==3.1.2 + - pypresence==4.2.1 + - python-dateutil==2.9.0.post0 + - pywebio==1.6.2 + - retry==0.9.2 + - tornado==6.4 + - ua-parser==0.18.0 + - uiautomator2==2.16.17 + - uiautomator2cache==0.3.0.1 + - user-agents==2.2.0 + - whichcraft==0.6.1 + - xmltodict==0.13.0 + - zerorpc==0.6.3 + - zope.event==5.0 + - zope.interface==6.2 \ No newline at end of file diff --git a/config/alas.json b/config/alas.json new file mode 100644 index 0000000000..e6f8a1f62c --- /dev/null +++ b/config/alas.json @@ -0,0 +1,1960 @@ +{ + "Alas": { + "Emulator": { + "Serial": "10.0.0.114:5555", + "PackageName": "com.YoStarJP.AzurLane", + "ServerName": "jp-14", + "ScreenshotMethod": "ADB", + "ControlMethod": "MaaTouch", + "ScreenshotDedithering": false, + "AdbRestart": false + }, + "EmulatorInfo": { + "Emulator": "BlueStacks5", + "name": "Rvc64", + "path": "C:/Program Files/BlueStacks_nxt/HD-Player.exe" + }, + "Error": { + "HandleError": true, + "SaveError": true, + "OnePushConfig": "provider: null", + "ScreenshotLength": 32 + }, + "Optimization": { + "ScreenshotInterval": 0.3, + "CombatScreenshotInterval": 1.0, + "TaskHoardingDuration": 0, + "WhenTaskQueueEmpty": "close_game" + }, + "DropRecord": { + "SaveFolder": "./screenshots", + "AzurStatsID": "p7sbjtzau9w4ym6k12035elhqirncfx8", + "API": "default", + "ResearchRecord": "do_not", + "CommissionRecord": "do_not", + "CombatRecord": "do_not", + "OpsiRecord": "do_not", + "MeowfficerBuy": "do_not", + "MeowfficerTalent": "do_not" + }, + "Storage": { + "Storage": {} + } + }, + "General": { + "Retirement": { + "RetireMode": "enhance" + }, + "OneClickRetire": { + "KeepLimitBreak": "keep_limit_break" + }, + "Enhance": { + "ShipToEnhance": "all", + "Filter": null, + "CheckPerCategory": 5 + }, + "OldRetire": { + "N": true, + "R": true, + "SR": false, + "SSR": false, + "RetireAmount": "retire_all" + }, + "Storage": { + "Storage": {} + } + }, + "Restart": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-14 08:00:00", + "Command": "Restart", + "SuccessInterval": 0, + "FailureInterval": 0, + "ServerUpdate": "00:00" + }, + "Storage": { + "Storage": {} + } + }, + "Main": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-13 07:54:00", + "Command": "Main", + "SuccessInterval": 0, + "FailureInterval": 120, + "ServerUpdate": "00:00" + }, + "Campaign": { + "Name": "10-4", + "Event": "campaign_main", + "Mode": "normal", + "UseClearMode": true, + "UseFleetLock": true, + "UseAutoSearch": true, + "Use2xBook": false, + "AmbushEvade": true + }, + "StopCondition": { + "OilLimit": 4000, + "RunCount": 0, + "MapAchievement": "non_stop", + "StageIncrease": false, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Fleet": { + "Fleet1": 3, + "Fleet1Formation": "double_line", + "Fleet1Mode": "combat_auto", + "Fleet1Step": 3, + "Fleet2": 4, + "Fleet2Formation": "double_line", + "Fleet2Mode": "combat_auto", + "Fleet2Step": 2, + "FleetOrder": "fleet1_mob_fleet2_boss" + }, + "Submarine": { + "Fleet": 1, + "Mode": "every_combat", + "AutoSearchMode": "sub_auto_call", + "DistanceToBoss": "2_grid_to_boss" + }, + "Emotion": { + "Mode": "calculate", + "Fleet1Value": 117, + "Fleet1Record": "2026-06-13 15:22:59", + "Fleet1Control": "prevent_green_face", + "Fleet1Recover": "not_in_dormitory", + "Fleet1Oath": false, + "Fleet2Value": 119, + "Fleet2Record": "2026-06-13 15:22:59", + "Fleet2Control": "prevent_green_face", + "Fleet2Recover": "not_in_dormitory", + "Fleet2Oath": false + }, + "HpControl": { + "UseHpBalance": true, + "UseEmergencyRepair": false, + "UseLowHpRetreat": false, + "HpBalanceThreshold": 0.2, + "HpBalanceWeight": "1000, 1000, 1000", + "RepairUseSingleThreshold": 0.3, + "RepairUseMultiThreshold": 0.6, + "LowHpRetreatThreshold": 0.5 + }, + "EnemyPriority": { + "EnemyScaleBalanceWeight": "default_mode" + }, + "Storage": { + "Storage": {} + } + }, + "Main2": { + "Scheduler": { + "Enable": true, + "NextRun": "2025-08-08 07:46:26", + "Command": "Main2", + "SuccessInterval": 0, + "FailureInterval": 120, + "ServerUpdate": "00:00" + }, + "Campaign": { + "Name": "4-1", + "Event": "campaign_main", + "Mode": "normal", + "UseClearMode": true, + "UseFleetLock": true, + "UseAutoSearch": true, + "Use2xBook": false, + "AmbushEvade": true + }, + "StopCondition": { + "OilLimit": 1000, + "RunCount": 0, + "MapAchievement": "non_stop", + "StageIncrease": false, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Fleet": { + "Fleet1": 1, + "Fleet1Formation": "double_line", + "Fleet1Mode": "combat_auto", + "Fleet1Step": 3, + "Fleet2": 2, + "Fleet2Formation": "double_line", + "Fleet2Mode": "combat_auto", + "Fleet2Step": 2, + "FleetOrder": "fleet1_all_fleet2_standby" + }, + "Submarine": { + "Fleet": 0, + "Mode": "do_not_use", + "AutoSearchMode": "sub_standby", + "DistanceToBoss": "2_grid_to_boss" + }, + "Emotion": { + "Mode": "ignore", + "Fleet1Value": 36, + "Fleet1Record": "2024-11-23 05:14:04", + "Fleet1Control": "prevent_red_face", + "Fleet1Recover": "dormitory_floor_1", + "Fleet1Oath": false, + "Fleet2Value": 150, + "Fleet2Record": "2024-11-23 05:14:04", + "Fleet2Control": "prevent_green_face", + "Fleet2Recover": "dormitory_floor_2", + "Fleet2Oath": false + }, + "HpControl": { + "UseHpBalance": false, + "UseEmergencyRepair": false, + "UseLowHpRetreat": false, + "HpBalanceThreshold": 0.2, + "HpBalanceWeight": "1000, 1000, 1000", + "RepairUseSingleThreshold": 0.3, + "RepairUseMultiThreshold": 0.6, + "LowHpRetreatThreshold": 0.3 + }, + "EnemyPriority": { + "EnemyScaleBalanceWeight": "default_mode" + }, + "Storage": { + "Storage": {} + } + }, + "Main3": { + "Scheduler": { + "Enable": false, + "NextRun": "2020-01-01 00:00:00", + "Command": "Main3", + "SuccessInterval": 0, + "FailureInterval": 120, + "ServerUpdate": "00:00" + }, + "Campaign": { + "Name": "12-4", + "Event": "campaign_main", + "Mode": "normal", + "UseClearMode": true, + "UseFleetLock": true, + "UseAutoSearch": false, + "Use2xBook": false, + "AmbushEvade": true + }, + "StopCondition": { + "OilLimit": 1000, + "RunCount": 0, + "MapAchievement": "non_stop", + "StageIncrease": false, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Fleet": { + "Fleet1": 3, + "Fleet1Formation": "double_line", + "Fleet1Mode": "combat_auto", + "Fleet1Step": 3, + "Fleet2": 4, + "Fleet2Formation": "double_line", + "Fleet2Mode": "combat_auto", + "Fleet2Step": 2, + "FleetOrder": "fleet1_mob_fleet2_boss" + }, + "Submarine": { + "Fleet": 1, + "Mode": "every_combat", + "AutoSearchMode": "sub_standby", + "DistanceToBoss": "2_grid_to_boss" + }, + "Emotion": { + "Mode": "calculate", + "Fleet1Value": 111, + "Fleet1Record": "2025-03-03 01:40:20", + "Fleet1Control": "prevent_yellow_face", + "Fleet1Recover": "not_in_dormitory", + "Fleet1Oath": false, + "Fleet2Value": 119, + "Fleet2Record": "2025-03-03 01:40:20", + "Fleet2Control": "prevent_yellow_face", + "Fleet2Recover": "not_in_dormitory", + "Fleet2Oath": false + }, + "HpControl": { + "UseHpBalance": true, + "UseEmergencyRepair": false, + "UseLowHpRetreat": false, + "HpBalanceThreshold": 0.2, + "HpBalanceWeight": "1000, 1000, 1000", + "RepairUseSingleThreshold": 0.3, + "RepairUseMultiThreshold": 0.6, + "LowHpRetreatThreshold": 0.3 + }, + "EnemyPriority": { + "EnemyScaleBalanceWeight": "default_mode" + }, + "Storage": { + "Storage": {} + } + }, + "GemsFarming": { + "Scheduler": { + "Enable": false, + "NextRun": "2024-03-23 18:12:03", + "Command": "GemsFarming", + "SuccessInterval": 0, + "FailureInterval": 120, + "ServerUpdate": "00:00" + }, + "GemsFarming": { + "CommonCV": "any", + "ChangeVanguard": "ship", + "CommonDD": "any", + "CommissionLimit": false + }, + "Campaign": { + "Name": "4-1", + "Event": "event_20260520_cn", + "Mode": "normal", + "UseClearMode": true, + "UseFleetLock": true, + "UseAutoSearch": true, + "Use2xBook": false, + "AmbushEvade": true + }, + "StopCondition": { + "OilLimit": 10000, + "RunCount": 0, + "MapAchievement": "non_stop", + "StageIncrease": false, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Fleet": { + "Fleet1": 1, + "Fleet1Formation": "double_line", + "Fleet1Mode": "combat_auto", + "Fleet1Step": 3, + "Fleet2": 2, + "Fleet2Formation": "double_line", + "Fleet2Mode": "combat_auto", + "Fleet2Step": 2, + "FleetOrder": "fleet1_all_fleet2_standby" + }, + "Storage": { + "Storage": {} + } + }, + "EventGeneral": { + "EventGeneral": { + "PtLimit": 0, + "TimeLimit": "2020-01-01 00:00:00" + }, + "TaskBalancer": { + "Enable": false, + "CoinLimit": 10000, + "TaskCall": "Main" + }, + "Storage": { + "Storage": {} + } + }, + "Event": { + "Scheduler": { + "Enable": false, + "NextRun": "2025-11-05 18:39:22", + "Command": "Event", + "SuccessInterval": 0, + "FailureInterval": 120, + "ServerUpdate": "00:00" + }, + "Campaign": { + "Name": "D3", + "Event": "event_20260520_cn", + "Mode": "normal", + "UseClearMode": true, + "UseFleetLock": true, + "UseAutoSearch": true, + "Use2xBook": false, + "AmbushEvade": true + }, + "StopCondition": { + "OilLimit": 2000, + "RunCount": 0, + "MapAchievement": "map_3_stars", + "StageIncrease": true, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Fleet": { + "Fleet1": 1, + "Fleet1Formation": "double_line", + "Fleet1Mode": "combat_auto", + "Fleet1Step": 2, + "Fleet2": 2, + "Fleet2Formation": "double_line", + "Fleet2Mode": "combat_auto", + "Fleet2Step": 2, + "FleetOrder": "fleet1_mob_fleet2_boss" + }, + "Submarine": { + "Fleet": 1, + "Mode": "hunt_and_boss", + "AutoSearchMode": "sub_standby", + "DistanceToBoss": "2_grid_to_boss" + }, + "Emotion": { + "Mode": "calculate", + "Fleet1Value": 138, + "Fleet1Record": "2026-06-04 18:25:57", + "Fleet1Control": "prevent_green_face", + "Fleet1Recover": "dormitory_floor_1", + "Fleet1Oath": false, + "Fleet2Value": 148, + "Fleet2Record": "2026-06-04 18:25:57", + "Fleet2Control": "prevent_green_face", + "Fleet2Recover": "dormitory_floor_1", + "Fleet2Oath": false + }, + "HpControl": { + "UseHpBalance": false, + "UseEmergencyRepair": false, + "UseLowHpRetreat": false, + "HpBalanceThreshold": 0.2, + "HpBalanceWeight": "1000, 1000, 1000", + "RepairUseSingleThreshold": 0.3, + "RepairUseMultiThreshold": 0.6, + "LowHpRetreatThreshold": 0.3 + }, + "EnemyPriority": { + "EnemyScaleBalanceWeight": "default_mode" + }, + "Storage": { + "Storage": {} + } + }, + "Event2": { + "Scheduler": { + "Enable": false, + "NextRun": "2026-06-11 21:54:00", + "Command": "Event2", + "SuccessInterval": 0, + "FailureInterval": 120, + "ServerUpdate": "00:00" + }, + "Campaign": { + "Name": "B3", + "Event": "event_20260520_cn", + "Mode": "normal", + "UseClearMode": true, + "UseFleetLock": true, + "UseAutoSearch": true, + "Use2xBook": false, + "AmbushEvade": true + }, + "StopCondition": { + "OilLimit": 1000, + "RunCount": 0, + "MapAchievement": "non_stop", + "StageIncrease": false, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Fleet": { + "Fleet1": 1, + "Fleet1Formation": "double_line", + "Fleet1Mode": "combat_auto", + "Fleet1Step": 3, + "Fleet2": 2, + "Fleet2Formation": "double_line", + "Fleet2Mode": "combat_auto", + "Fleet2Step": 2, + "FleetOrder": "fleet1_all_fleet2_standby" + }, + "Submarine": { + "Fleet": 1, + "Mode": "do_not_use", + "AutoSearchMode": "sub_standby", + "DistanceToBoss": "2_grid_to_boss" + }, + "Emotion": { + "Mode": "calculate", + "Fleet1Value": 42, + "Fleet1Record": "2026-06-11 21:58:22", + "Fleet1Control": "prevent_green_face", + "Fleet1Recover": "dormitory_floor_1", + "Fleet1Oath": false, + "Fleet2Value": 119, + "Fleet2Record": "2026-06-11 21:58:22", + "Fleet2Control": "prevent_green_face", + "Fleet2Recover": "not_in_dormitory", + "Fleet2Oath": false + }, + "HpControl": { + "UseHpBalance": true, + "UseEmergencyRepair": false, + "UseLowHpRetreat": false, + "HpBalanceThreshold": 0.2, + "HpBalanceWeight": "1000, 1000, 1000", + "RepairUseSingleThreshold": 0.3, + "RepairUseMultiThreshold": 0.6, + "LowHpRetreatThreshold": 0.3 + }, + "EnemyPriority": { + "EnemyScaleBalanceWeight": "default_mode" + }, + "Storage": { + "Storage": {} + } + }, + "Raid": { + "Scheduler": { + "Enable": false, + "NextRun": "2024-03-29 15:42:00", + "Command": "Raid", + "SuccessInterval": 0, + "FailureInterval": 120, + "ServerUpdate": "00:00" + }, + "Raid": { + "Mode": "easy", + "UseTicket": false + }, + "Campaign": { + "Name": "dynamic", + "Event": "raid_20260212", + "Mode": "normal", + "UseClearMode": true, + "UseFleetLock": true, + "UseAutoSearch": false, + "Use2xBook": false, + "AmbushEvade": true + }, + "StopCondition": { + "OilLimit": 9000, + "RunCount": 0, + "MapAchievement": "non_stop", + "StageIncrease": false, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Emotion": { + "Mode": "calculate", + "Fleet1Value": 150, + "Fleet1Record": "2024-03-31 03:24:23", + "Fleet1Control": "keep_exp_bonus", + "Fleet1Recover": "dormitory_floor_2", + "Fleet1Oath": false, + "Fleet2Value": 119, + "Fleet2Record": "2020-01-01 00:00:00", + "Fleet2Control": "prevent_yellow_face", + "Fleet2Recover": "not_in_dormitory", + "Fleet2Oath": false + }, + "Storage": { + "Storage": {} + } + }, + "Hospital": { + "Scheduler": { + "Enable": false, + "NextRun": "2025-04-10 08:00:00", + "Command": "Hospital", + "SuccessInterval": 0, + "FailureInterval": 120, + "ServerUpdate": "00:00" + }, + "Hospital": { + "UseRecommendFleet": false + }, + "StopCondition": { + "OilLimit": 1000, + "RunCount": 0, + "MapAchievement": "non_stop", + "StageIncrease": false, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Emotion": { + "Mode": "calculate", + "Fleet1Value": 111, + "Fleet1Record": "2025-03-29 17:59:18", + "Fleet1Control": "prevent_yellow_face", + "Fleet1Recover": "not_in_dormitory", + "Fleet1Oath": false, + "Fleet2Value": 119, + "Fleet2Record": "2020-01-01 00:00:00", + "Fleet2Control": "prevent_yellow_face", + "Fleet2Recover": "not_in_dormitory", + "Fleet2Oath": false + }, + "Storage": { + "Storage": {} + } + }, + "Coalition": { + "Scheduler": { + "Enable": false, + "NextRun": "2025-07-01 07:53:58", + "Command": "Coalition", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "Campaign": { + "Name": "dynamic", + "Event": "coalition_20260122", + "Mode": "normal", + "UseClearMode": true, + "UseFleetLock": true, + "UseAutoSearch": false, + "Use2xBook": false, + "AmbushEvade": true + }, + "Coalition": { + "Mode": "normal", + "Fleet": "single" + }, + "StopCondition": { + "OilLimit": 4000, + "RunCount": 0, + "MapAchievement": "non_stop", + "StageIncrease": false, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Emotion": { + "Mode": "calculate", + "Fleet1Value": 61, + "Fleet1Record": "2025-07-02 23:38:12", + "Fleet1Control": "prevent_green_face", + "Fleet1Recover": "not_in_dormitory", + "Fleet1Oath": false, + "Fleet2Value": 119, + "Fleet2Record": "2020-01-01 00:00:00", + "Fleet2Control": "prevent_yellow_face", + "Fleet2Recover": "not_in_dormitory", + "Fleet2Oath": false + }, + "Storage": { + "Storage": {} + } + }, + "MaritimeEscort": { + "Scheduler": { + "Enable": false, + "NextRun": "2020-01-01 00:00:00", + "Command": "MaritimeEscort", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "MaritimeEscort": { + "Enable": true + }, + "Storage": { + "Storage": {} + } + }, + "WarArchives": { + "Scheduler": { + "Enable": false, + "NextRun": "2020-01-01 00:00:00", + "Command": "WarArchives", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "Campaign": { + "Name": "D3", + "Event": "war_archives_20210225_cn", + "Mode": "normal", + "UseClearMode": true, + "UseFleetLock": true, + "UseAutoSearch": true, + "Use2xBook": false, + "AmbushEvade": true + }, + "StopCondition": { + "OilLimit": 1000, + "RunCount": 0, + "MapAchievement": "non_stop", + "StageIncrease": false, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Fleet": { + "Fleet1": 1, + "Fleet1Formation": "double_line", + "Fleet1Mode": "combat_auto", + "Fleet1Step": 3, + "Fleet2": 2, + "Fleet2Formation": "double_line", + "Fleet2Mode": "combat_auto", + "Fleet2Step": 2, + "FleetOrder": "fleet1_mob_fleet2_boss" + }, + "Submarine": { + "Fleet": 0, + "Mode": "do_not_use", + "AutoSearchMode": "sub_standby", + "DistanceToBoss": "2_grid_to_boss" + }, + "Emotion": { + "Mode": "calculate", + "Fleet1Value": 119, + "Fleet1Record": "2020-01-01 00:00:00", + "Fleet1Control": "prevent_yellow_face", + "Fleet1Recover": "not_in_dormitory", + "Fleet1Oath": false, + "Fleet2Value": 119, + "Fleet2Record": "2020-01-01 00:00:00", + "Fleet2Control": "prevent_yellow_face", + "Fleet2Recover": "not_in_dormitory", + "Fleet2Oath": false + }, + "HpControl": { + "UseHpBalance": false, + "UseEmergencyRepair": false, + "UseLowHpRetreat": false, + "HpBalanceThreshold": 0.2, + "HpBalanceWeight": "1000, 1000, 1000", + "RepairUseSingleThreshold": 0.3, + "RepairUseMultiThreshold": 0.6, + "LowHpRetreatThreshold": 0.3 + }, + "EnemyPriority": { + "EnemyScaleBalanceWeight": "default_mode" + }, + "Storage": { + "Storage": {} + } + }, + "EventA": { + "Scheduler": { + "Enable": false, + "NextRun": "2026-06-12 08:00:00", + "Command": "EventA", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "EventDaily": { + "StageFilter": "A1 > A2 > A3", + "LastStage": "a3" + }, + "Campaign": { + "Name": "dynamic", + "Event": "event_20260520_cn", + "Mode": "normal", + "UseClearMode": true, + "UseFleetLock": true, + "UseAutoSearch": true, + "Use2xBook": false, + "AmbushEvade": true + }, + "StopCondition": { + "OilLimit": 1000, + "RunCount": 0, + "MapAchievement": "non_stop", + "StageIncrease": false, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Fleet": { + "Fleet1": 1, + "Fleet1Formation": "double_line", + "Fleet1Mode": "combat_auto", + "Fleet1Step": 3, + "Fleet2": 2, + "Fleet2Formation": "double_line", + "Fleet2Mode": "combat_auto", + "Fleet2Step": 2, + "FleetOrder": "fleet1_all_fleet2_standby" + }, + "Submarine": { + "Fleet": 0, + "Mode": "do_not_use", + "AutoSearchMode": "sub_standby", + "DistanceToBoss": "2_grid_to_boss" + }, + "Emotion": { + "Mode": "ignore", + "Fleet1Value": 105, + "Fleet1Record": "2024-11-21 01:18:21", + "Fleet1Control": "prevent_yellow_face", + "Fleet1Recover": "not_in_dormitory", + "Fleet1Oath": false, + "Fleet2Value": 117, + "Fleet2Record": "2024-11-21 01:18:21", + "Fleet2Control": "prevent_yellow_face", + "Fleet2Recover": "not_in_dormitory", + "Fleet2Oath": false + }, + "HpControl": { + "UseHpBalance": false, + "UseEmergencyRepair": false, + "UseLowHpRetreat": false, + "HpBalanceThreshold": 0.2, + "HpBalanceWeight": "1000, 1000, 1000", + "RepairUseSingleThreshold": 0.3, + "RepairUseMultiThreshold": 0.6, + "LowHpRetreatThreshold": 0.3 + }, + "EnemyPriority": { + "EnemyScaleBalanceWeight": "default_mode" + }, + "Storage": { + "Storage": {} + } + }, + "EventB": { + "Scheduler": { + "Enable": false, + "NextRun": "2026-06-12 08:00:00", + "Command": "EventB", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "EventDaily": { + "StageFilter": "B1 > B2 > B3", + "LastStage": "b3" + }, + "Campaign": { + "Name": "dynamic", + "Event": "event_20260520_cn", + "Mode": "normal", + "UseClearMode": true, + "UseFleetLock": true, + "UseAutoSearch": true, + "Use2xBook": false, + "AmbushEvade": true + }, + "StopCondition": { + "OilLimit": 1000, + "RunCount": 0, + "MapAchievement": "non_stop", + "StageIncrease": false, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Fleet": { + "Fleet1": 1, + "Fleet1Formation": "double_line", + "Fleet1Mode": "combat_auto", + "Fleet1Step": 3, + "Fleet2": 2, + "Fleet2Formation": "double_line", + "Fleet2Mode": "combat_auto", + "Fleet2Step": 2, + "FleetOrder": "fleet1_all_fleet2_standby" + }, + "Submarine": { + "Fleet": 0, + "Mode": "do_not_use", + "AutoSearchMode": "sub_standby", + "DistanceToBoss": "2_grid_to_boss" + }, + "Emotion": { + "Mode": "ignore", + "Fleet1Value": 99, + "Fleet1Record": "2024-11-21 01:40:46", + "Fleet1Control": "prevent_yellow_face", + "Fleet1Recover": "not_in_dormitory", + "Fleet1Oath": false, + "Fleet2Value": 117, + "Fleet2Record": "2024-11-21 01:40:46", + "Fleet2Control": "prevent_yellow_face", + "Fleet2Recover": "not_in_dormitory", + "Fleet2Oath": false + }, + "HpControl": { + "UseHpBalance": false, + "UseEmergencyRepair": false, + "UseLowHpRetreat": false, + "HpBalanceThreshold": 0.2, + "HpBalanceWeight": "1000, 1000, 1000", + "RepairUseSingleThreshold": 0.3, + "RepairUseMultiThreshold": 0.6, + "LowHpRetreatThreshold": 0.3 + }, + "EnemyPriority": { + "EnemyScaleBalanceWeight": "default_mode" + }, + "Storage": { + "Storage": {} + } + }, + "EventC": { + "Scheduler": { + "Enable": false, + "NextRun": "2024-05-31 00:00:00", + "Command": "EventC", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "EventDaily": { + "StageFilter": "C1 > C2 > C3", + "LastStage": "c3" + }, + "Campaign": { + "Name": "dynamic", + "Event": "event_20260520_cn", + "Mode": "normal", + "UseClearMode": true, + "UseFleetLock": true, + "UseAutoSearch": true, + "Use2xBook": false, + "AmbushEvade": true + }, + "StopCondition": { + "OilLimit": 1000, + "RunCount": 0, + "MapAchievement": "non_stop", + "StageIncrease": false, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Fleet": { + "Fleet1": 1, + "Fleet1Formation": "double_line", + "Fleet1Mode": "combat_auto", + "Fleet1Step": 3, + "Fleet2": 5, + "Fleet2Formation": "double_line", + "Fleet2Mode": "combat_auto", + "Fleet2Step": 2, + "FleetOrder": "fleet1_mob_fleet2_boss" + }, + "Submarine": { + "Fleet": 1, + "Mode": "hunt_and_boss", + "AutoSearchMode": "sub_standby", + "DistanceToBoss": "2_grid_to_boss" + }, + "Emotion": { + "Mode": "calculate", + "Fleet1Value": 99, + "Fleet1Record": "2024-05-30 05:01:03", + "Fleet1Control": "prevent_yellow_face", + "Fleet1Recover": "not_in_dormitory", + "Fleet1Oath": false, + "Fleet2Value": 117, + "Fleet2Record": "2024-05-30 05:01:03", + "Fleet2Control": "prevent_yellow_face", + "Fleet2Recover": "not_in_dormitory", + "Fleet2Oath": false + }, + "HpControl": { + "UseHpBalance": false, + "UseEmergencyRepair": false, + "UseLowHpRetreat": false, + "HpBalanceThreshold": 0.2, + "HpBalanceWeight": "1000, 1000, 1000", + "RepairUseSingleThreshold": 0.3, + "RepairUseMultiThreshold": 0.6, + "LowHpRetreatThreshold": 0.3 + }, + "EnemyPriority": { + "EnemyScaleBalanceWeight": "default_mode" + }, + "Storage": { + "Storage": {} + } + }, + "EventD": { + "Scheduler": { + "Enable": false, + "NextRun": "2024-05-31 00:00:00", + "Command": "EventD", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "EventDaily": { + "StageFilter": "D1 > D2 > D3", + "LastStage": "d3" + }, + "Campaign": { + "Name": "dynamic", + "Event": "event_20260520_cn", + "Mode": "normal", + "UseClearMode": true, + "UseFleetLock": true, + "UseAutoSearch": true, + "Use2xBook": false, + "AmbushEvade": true + }, + "StopCondition": { + "OilLimit": 1000, + "RunCount": 0, + "MapAchievement": "non_stop", + "StageIncrease": false, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Fleet": { + "Fleet1": 1, + "Fleet1Formation": "double_line", + "Fleet1Mode": "combat_auto", + "Fleet1Step": 3, + "Fleet2": 5, + "Fleet2Formation": "double_line", + "Fleet2Mode": "combat_auto", + "Fleet2Step": 2, + "FleetOrder": "fleet1_mob_fleet2_boss" + }, + "Submarine": { + "Fleet": 1, + "Mode": "hunt_and_boss", + "AutoSearchMode": "sub_standby", + "DistanceToBoss": "2_grid_to_boss" + }, + "Emotion": { + "Mode": "calculate", + "Fleet1Value": 95, + "Fleet1Record": "2024-05-30 05:31:09", + "Fleet1Control": "prevent_yellow_face", + "Fleet1Recover": "not_in_dormitory", + "Fleet1Oath": false, + "Fleet2Value": 117, + "Fleet2Record": "2024-05-30 05:31:09", + "Fleet2Control": "prevent_yellow_face", + "Fleet2Recover": "not_in_dormitory", + "Fleet2Oath": false + }, + "HpControl": { + "UseHpBalance": false, + "UseEmergencyRepair": false, + "UseLowHpRetreat": false, + "HpBalanceThreshold": 0.2, + "HpBalanceWeight": "1000, 1000, 1000", + "RepairUseSingleThreshold": 0.3, + "RepairUseMultiThreshold": 0.6, + "LowHpRetreatThreshold": 0.3 + }, + "EnemyPriority": { + "EnemyScaleBalanceWeight": "default_mode" + }, + "Storage": { + "Storage": {} + } + }, + "EventSp": { + "Scheduler": { + "Enable": false, + "NextRun": "2026-06-12 08:00:00", + "Command": "EventSp", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "Campaign": { + "Name": "sp", + "Event": "event_20260520_cn", + "Mode": "normal", + "UseClearMode": true, + "UseFleetLock": true, + "UseAutoSearch": true, + "Use2xBook": false, + "AmbushEvade": true + }, + "StopCondition": { + "OilLimit": 1000, + "RunCount": 0, + "MapAchievement": "non_stop", + "StageIncrease": false, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Fleet": { + "Fleet1": 1, + "Fleet1Formation": "double_line", + "Fleet1Mode": "combat_auto", + "Fleet1Step": 2, + "Fleet2": 2, + "Fleet2Formation": "double_line", + "Fleet2Mode": "combat_auto", + "Fleet2Step": 2, + "FleetOrder": "fleet1_mob_fleet2_boss" + }, + "Submarine": { + "Fleet": 1, + "Mode": "every_combat", + "AutoSearchMode": "sub_standby", + "DistanceToBoss": "2_grid_to_boss" + }, + "Emotion": { + "Mode": "calculate", + "Fleet1Value": 109, + "Fleet1Record": "2026-06-11 09:02:30", + "Fleet1Control": "prevent_yellow_face", + "Fleet1Recover": "not_in_dormitory", + "Fleet1Oath": false, + "Fleet2Value": 117, + "Fleet2Record": "2026-06-11 09:02:30", + "Fleet2Control": "prevent_yellow_face", + "Fleet2Recover": "not_in_dormitory", + "Fleet2Oath": false + }, + "HpControl": { + "UseHpBalance": true, + "UseEmergencyRepair": false, + "UseLowHpRetreat": false, + "HpBalanceThreshold": 0.2, + "HpBalanceWeight": "1000, 1000, 1000", + "RepairUseSingleThreshold": 0.3, + "RepairUseMultiThreshold": 0.6, + "LowHpRetreatThreshold": 0.3 + }, + "EnemyPriority": { + "EnemyScaleBalanceWeight": "default_mode" + }, + "Storage": { + "Storage": {} + } + }, + "RaidDaily": { + "Scheduler": { + "Enable": false, + "NextRun": "2025-02-06 07:00:00", + "Command": "RaidDaily", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "RaidDaily": { + "StageFilter": "easy > ex" + }, + "Campaign": { + "Name": "dynamic", + "Event": "raid_20260212", + "Mode": "normal", + "UseClearMode": true, + "UseFleetLock": true, + "UseAutoSearch": false, + "Use2xBook": false, + "AmbushEvade": true + }, + "StopCondition": { + "OilLimit": 1000, + "RunCount": 0, + "MapAchievement": "non_stop", + "StageIncrease": false, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Emotion": { + "Mode": "calculate", + "Fleet1Value": 87, + "Fleet1Record": "2025-02-05 08:15:52", + "Fleet1Control": "prevent_yellow_face", + "Fleet1Recover": "not_in_dormitory", + "Fleet1Oath": false, + "Fleet2Value": 119, + "Fleet2Record": "2020-01-01 00:00:00", + "Fleet2Control": "prevent_yellow_face", + "Fleet2Recover": "not_in_dormitory", + "Fleet2Oath": false + }, + "Storage": { + "Storage": {} + } + }, + "CoalitionSp": { + "Scheduler": { + "Enable": false, + "NextRun": "2025-07-10 08:00:00", + "Command": "CoalitionSp", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "Campaign": { + "Name": "sp", + "Event": "coalition_20260122", + "Mode": "normal", + "UseClearMode": true, + "UseFleetLock": true, + "UseAutoSearch": false, + "Use2xBook": false, + "AmbushEvade": true + }, + "Coalition": { + "Mode": "sp", + "Fleet": "single" + }, + "StopCondition": { + "OilLimit": 1000, + "RunCount": 0, + "MapAchievement": "non_stop", + "StageIncrease": false, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Emotion": { + "Mode": "calculate", + "Fleet1Value": 117, + "Fleet1Record": "2025-07-09 08:33:47", + "Fleet1Control": "prevent_yellow_face", + "Fleet1Recover": "not_in_dormitory", + "Fleet1Oath": false, + "Fleet2Value": 119, + "Fleet2Record": "2020-01-01 00:00:00", + "Fleet2Control": "prevent_yellow_face", + "Fleet2Recover": "not_in_dormitory", + "Fleet2Oath": false + }, + "Storage": { + "Storage": {} + } + }, + "Commission": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-13 16:15:13", + "Command": "Commission", + "SuccessInterval": "30-60", + "FailureInterval": "30-60", + "ServerUpdate": "00:00" + }, + "Commission": { + "PresetFilter": "cube_24h", + "CustomFilter": "DailyEvent > Gem-4 > Gem-2 > Gem-8 > ExtraCube-0:30\n> UrgentCube-1:30 > UrgentCube-1:45 > UrgentCube-3\n> ExtraDrill-5:20 > ExtraDrill-2 > ExtraDrill-3:20\n> UrgentCube-2:15 > UrgentCube-4\n> ExtraDrill-1 > UrgentCube-6 > ExtraCube-1:30\n> ExtraDrill-2:40 > ExtraDrill-0:20\n> Major > DailyChip > DailyResource\n> ExtraPart-0:30 > ExtraOil-1 > UrgentBox-6\n> ExtraCube-3 > ExtraPart-1 > UrgentBox-3\n> ExtraCube-4 > ExtraPart-1:30 > ExtraOil-4\n> UrgentBox-1 > ExtraCube-5 > UrgentBox-1\n> ExtraCube-8 > ExtraOil-8\n> UrgentDrill-4 > UrgentDrill-2:40 > UrgentDrill-2\n> UrgentDrill-1 > UrgentDrill-1:30 > UrgentDrill-1:10\n> Extra-0:20 > Extra-0:30 > Extra-1:00 > Extra-1:30 > Extra-2:00\n> shortest", + "DoMajorCommission": false + }, + "Storage": { + "Storage": {} + } + }, + "Tactical": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-13 18:01:38", + "Command": "Tactical", + "SuccessInterval": "30-60", + "FailureInterval": "120-240", + "ServerUpdate": "00:00" + }, + "Tactical": { + "TacticalFilter": "SameT1 > BlueT1 > YellowT1 > RedT1 > SameT2 > BlueT2 > YellowT2 > RedT2 > SameT3 > BlueT3 > YellowT3 > RedT3\n> SameT3 > SameT2 > SameT1\n> BlueT3 > YellowT3 > RedT3\n> BlueT4 > YellowT4 > RedT4\n> BlueT1 > YellowT1 > RedT1\n> first", + "RapidTrainingSlot": "do_not_use" + }, + "ControlExpOverflow": { + "Enable": true, + "T4Allow": 100, + "T3Allow": 100, + "T2Allow": 200, + "T1Allow": 200 + }, + "AddNewStudent": { + "Enable": true, + "Favorite": false, + "MinLevel": 50 + }, + "Storage": { + "Storage": {} + } + }, + "Research": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-13 18:13:57", + "Command": "Research", + "SuccessInterval": "30-60", + "FailureInterval": "30-60", + "ServerUpdate": "00:00" + }, + "Research": { + "UseCube": "only_05_hour", + "UseCoin": "only_05_hour", + "UsePart": "always_use", + "AllowDelay": true, + "PresetFilter": "series_8_blueprint_305", + "CustomFilter": "Q0.5 > H0.5 > H1 > H2 > H4 > Q1 > Q2 > Q4 > reset > G1.5 > G2.5 > cheapest\n> S5-Q1 > S5-DR5 > S5-DR8 > S5-G4 > S5-PRY2.5 > 1 > S5-Q2 > reset\n> S5-G2.5 > S5-PRY5 > S5-PRY8 > 1.5 > 2 > S5-Q4 > 2.5 > 3\n> Q4 > G4 > 4 > 5 > S5-C6 > C6 > 6 > S5-C8 > 8\n> S5-C12 > 12" + }, + "Storage": { + "Storage": {} + } + }, + "Dorm": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-13 18:53:35", + "Command": "Dorm", + "SuccessInterval": 278, + "FailureInterval": 278, + "ServerUpdate": "00:00" + }, + "Dorm": { + "Collect": true, + "Feed": true, + "FeedFilter": "20000 > 10000 > 5000 > 3000 > 2000 > 1000" + }, + "BuyFurniture": { + "Enable": true, + "BuyOption": "all", + "LastRun": "2026-06-09 20:44:39" + }, + "Storage": { + "Storage": {} + } + }, + "Meowfficer": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-14 08:00:00", + "Command": "Meowfficer", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "Meowfficer": { + "BuyAmount": 1, + "FortChoreMeowfficer": true + }, + "MeowfficerTrain": { + "Enable": false, + "Mode": "seamlessly", + "RetainTalentedGold": false, + "RetainTalentedPurple": true, + "EnhanceIndex": 12, + "MaxFeedLevel": 5 + }, + "Storage": { + "Storage": {} + } + }, + "Guild": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-13 15:52:21", + "Command": "Guild", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00, 06:00, 12:00, 18:00, 21:00" + }, + "GuildLogistics": { + "Enable": true, + "SelectNewMission": true, + "ExchangeFilter": "PlateTorpedoT1 > PlateAntiAirT1 > PlatePlaneT1 > PlateGunT1 > PlateGeneralT1\n> PlateTorpedoT2 > PlateAntiAirT2 > PlatePlaneT2 > PlateGunT2 > PlateGeneralT2\n> PlateTorpedoT3 > PlateAntiAirT3 > PlatePlaneT3 > PlateGunT3 > PlateGeneralT3\n> OxyCola > Coolant > Merit > Coin > Oil" + }, + "GuildOperation": { + "Enable": true, + "SelectNewOperation": true, + "NewOperationMaxDate": 15, + "JoinThreshold": 1, + "AttackBoss": true, + "BossFleetRecommend": true + }, + "Storage": { + "Storage": {} + } + }, + "Reward": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-13 18:29:23", + "Command": "Reward", + "SuccessInterval": "120-240", + "FailureInterval": "120-240", + "ServerUpdate": "00:00" + }, + "Reward": { + "CollectOil": true, + "CollectCoin": true, + "CollectExp": true, + "CollectMission": true, + "CollectWeeklyMission": true + }, + "Storage": { + "Storage": {} + } + }, + "Awaken": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-14 08:00:00", + "Command": "Awaken", + "SuccessInterval": 0, + "FailureInterval": 120, + "ServerUpdate": "00:00" + }, + "Awaken": { + "LevelCap": "level120", + "Favourite": false + }, + "Storage": { + "Storage": {} + } + }, + "Daily": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-14 08:00:00", + "Command": "Daily", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "Daily": { + "UseDailySkip": true, + "EscortMission": "first", + "EscortMissionFleet": 1, + "AdvanceMission": "first", + "AdvanceMissionFleet": 1, + "FierceAssault": "first", + "FierceAssaultFleet": 1, + "TacticalTraining": "second", + "TacticalTrainingFleet": 1, + "SupplyLineDisruption": "second", + "ModuleDevelopment": "first", + "ModuleDevelopmentFleet": 1, + "EmergencyModuleDevelopment": "first", + "EmergencyModuleDevelopmentFleet": 1 + }, + "Storage": { + "Storage": {} + } + }, + "Hard": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-14 08:00:00", + "Command": "Hard", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "Hard": { + "HardStage": "13-4", + "HardFleet": 2 + }, + "Storage": { + "Storage": {} + } + }, + "Exercise": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-13 20:00:00", + "Command": "Exercise", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00, 12:00, 18:00" + }, + "Exercise": { + "OpponentChooseMode": "max_exp", + "OpponentTrial": 1, + "ExerciseStrategy": "aggressive", + "LowHpThreshold": 0, + "LowHpConfirmWait": 3, + "OpponentRefreshValue": 0, + "OpponentRefreshRecord": "2026-06-13 08:15:16" + }, + "Storage": { + "Storage": {} + } + }, + "ShopFrequent": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-13 20:00:00", + "Command": "ShopFrequent", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00, 12:00, 18:00" + }, + "GeneralShop": { + "UseGems": false, + "Refresh": false, + "BuySkinBox": true, + "ConsumeCoins": true, + "Filter": "BookT3 > BookT2 > BookT1 > PlateT4 > PlateRandomT4 > FoodT6 > FoodT5 > Chip > PlateT3\n> Cube\n> FoodT6 > FoodT5" + }, + "Storage": { + "Storage": {} + } + }, + "ShopOnce": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-14 08:00:00", + "Command": "ShopOnce", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "GuildShop": { + "Refresh": true, + "Filter": "PlateT4 > BookT3 > PR > CatT3 > Chip > BookT2 > Retrofit > FoodT6 > FoodT5 > CatT2 > BoxT4 > PlateT3 > PlateT2", + "BOX_T3": "ironblood", + "BOX_T4": "ironblood", + "BOOK_T2": "red", + "BOOK_T3": "red", + "RETROFIT_T2": "cl", + "RETROFIT_T3": "cl", + "PLATE_T2": "general", + "PLATE_T3": "general", + "PLATE_T4": "general", + "PR1": "neptune", + "PR2": "seattle", + "PR3": "cheshire" + }, + "MedalShop2": { + "Filter": "DR > PR\n> BookRedT3 > BookYellowT3 > BookBlueT3\n> BookRedT2 > BookYellowT2 > BookBlueT2\n> RetrofitT3\n> FoodT6 > FoodT5\n> PlateGeneralT3 > PlateWildT3", + "RETROFIT_T1": "cl", + "RETROFIT_T2": "cl", + "RETROFIT_T3": "cl", + "PLATE_T1": "general", + "PLATE_T2": "general", + "PLATE_T3": "general" + }, + "MeritShop": { + "Refresh": false, + "Filter": "Cube" + }, + "CoreShop": { + "Filter": "Array" + }, + "Storage": { + "Storage": {} + } + }, + "Shipyard": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-14 12:00:00", + "Command": "Shipyard", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "04:00" + }, + "ShipyardDr": { + "ResearchSeries": 5, + "ShipIndex": 1, + "BuyAmount": 2, + "LastRun": "2020-01-01 00:00:00" + }, + "Shipyard": { + "ResearchSeries": 6, + "ShipIndex": 1, + "BuyAmount": 2, + "LastRun": "2020-01-01 00:00:00" + }, + "Storage": { + "Storage": {} + } + }, + "Gacha": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-14 08:00:00", + "Command": "Gacha", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "Gacha": { + "Pool": "light", + "Amount": 1, + "UseTicket": true, + "UseDrill": true + }, + "Storage": { + "Storage": {} + } + }, + "Freebies": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-14 08:00:00", + "Command": "Freebies", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "BattlePass": { + "Collect": true + }, + "DataKey": { + "Collect": true, + "ForceCollect": false + }, + "Mail": { + "ClaimMerit": true, + "ClaimMaintenance": true, + "ClaimTradeLicense": true, + "DeleteCollected": true + }, + "SupplyPack": { + "Collect": true, + "DayOfWeek": 0 + }, + "Storage": { + "Storage": {} + } + }, + "Minigame": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-14 08:00:00", + "Command": "Minigame", + "SuccessInterval": 0, + "FailureInterval": 120, + "ServerUpdate": "00:00" + }, + "Storage": { + "Storage": {} + } + }, + "PrivateQuarters": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-14 08:00:00", + "Command": "PrivateQuarters", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "PrivateQuarters": { + "BuyRoses": true, + "BuyCake": false, + "TargetInteract": true, + "TargetShip": "aegir" + }, + "Storage": { + "Storage": {} + } + }, + "OpsiGeneral": { + "OpsiGeneral": { + "UseLogger": true, + "BuyActionPointLimit": 0, + "OilLimit": 1000, + "RepairThreshold": 0.4, + "DoRandomMapEvent": true, + "AkashiShopFilter": "ActionPoint > PurpleCoins" + }, + "Storage": { + "Storage": {} + } + }, + "OpsiAshBeacon": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-13 15:36:02", + "Command": "OpsiAshBeacon", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "OpsiAshBeacon": { + "AttackMode": "current", + "OneHitMode": true, + "DossierAutoAttackMode": true, + "RequestAssist": true, + "EnsureFullyCollected": true + }, + "Storage": { + "Storage": {} + } + }, + "OpsiAshAssist": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-14 08:00:00", + "Command": "OpsiAshAssist", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "OpsiAshAssist": { + "Tier": 15 + }, + "Storage": { + "Storage": {} + } + }, + "OpsiExplore": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-30 08:00:00", + "Command": "OpsiExplore", + "SuccessInterval": 0, + "FailureInterval": 0, + "ServerUpdate": "00:00" + }, + "OpsiExplore": { + "SpecialRadar": false, + "ForceRun": false, + "LastZone": 0 + }, + "OpsiFleet": { + "Fleet": 1, + "Submarine": false + }, + "Storage": { + "Storage": {} + } + }, + "OpsiShop": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-14 08:00:00", + "Command": "OpsiShop", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "OpsiShop": { + "PresetFilter": "all", + "CustomFilter": "LoggerAbyssalT6 > LoggerAbyssalT5 > LoggerObscure > LoggerAbyssalT4 > ActionPoint > PurpleCoins\n> GearDesignPlanT3 > PlateRandomT4 > DevelopmentMaterialT3 > GearDesignPlanT2 > GearPart\n> OrdnanceTestingReportT3 > OrdnanceTestingReportT2 > DevelopmentMaterialT2 > OrdnanceTestingReportT1\n> METARedBook > CrystallizedHeatResistantSteel > NanoceramicAlloy > NeuroplasticProstheticArm > SupercavitationGenerator" + }, + "Storage": { + "Storage": {} + } + }, + "OpsiVoucher": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-30 08:00:00", + "Command": "OpsiVoucher", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "OpsiVoucher": { + "Filter": "LoggerAbyssal > LoggerObscure > Book > Fragment" + }, + "Storage": { + "Storage": {} + } + }, + "OpsiDaily": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-14 08:00:00", + "Command": "OpsiDaily", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "OpsiDaily": { + "DoMission": true, + "UseTuningSample": true + }, + "OpsiFleet": { + "Fleet": 1, + "Submarine": false + }, + "Storage": { + "Storage": {} + } + }, + "OpsiObscure": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-13 15:40:52", + "Command": "OpsiObscure", + "SuccessInterval": 60, + "FailureInterval": 60, + "ServerUpdate": "00:00" + }, + "OpsiObscure": { + "ForceRun": false + }, + "OpsiFleet": { + "Fleet": 1, + "Submarine": true + }, + "Storage": { + "Storage": {} + } + }, + "OpsiAbyssal": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-13 20:00:00", + "Command": "OpsiAbyssal", + "SuccessInterval": 60, + "FailureInterval": 60, + "ServerUpdate": "00:00, 12:00" + }, + "OpsiAbyssal": { + "ForceRun": false + }, + "OpsiFleetFilter": { + "Filter": "Fleet-2 > CallSubmarine > Fleet-3 > Fleet-4 > Fleet-1" + }, + "Storage": { + "Storage": {} + } + }, + "OpsiArchive": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-16 08:00:00", + "Command": "OpsiArchive", + "SuccessInterval": 60, + "FailureInterval": 60, + "ServerUpdate": "00:00" + }, + "OpsiFleet": { + "Fleet": 1, + "Submarine": false + }, + "Storage": { + "Storage": {} + } + }, + "OpsiStronghold": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-14 08:00:00", + "Command": "OpsiStronghold", + "SuccessInterval": 60, + "FailureInterval": 60, + "ServerUpdate": "00:00" + }, + "OpsiStronghold": { + "ForceRun": false + }, + "OpsiFleetFilter": { + "Filter": "Fleet-2 > CallSubmarine > Fleet-3 > Fleet-4 > Fleet-1" + }, + "Storage": { + "Storage": {} + } + }, + "OpsiMonthBoss": { + "Scheduler": { + "Enable": true, + "NextRun": "2026-06-13 15:40:52", + "Command": "OpsiMonthBoss", + "SuccessInterval": 0, + "FailureInterval": 120, + "ServerUpdate": "00:00" + }, + "OpsiMonthBoss": { + "Mode": "normal_hard", + "CheckAdaptability": true, + "ForceRun": false + }, + "OpsiFleetFilter": { + "Filter": "Fleet-4 > CallSubmarine > Fleet-2 > Fleet-3 > Fleet-1" + }, + "Storage": { + "Storage": {} + } + }, + "OpsiMeowfficerFarming": { + "Scheduler": { + "Enable": false, + "NextRun": "2026-06-07 17:20:14", + "Command": "OpsiMeowfficerFarming", + "SuccessInterval": 30, + "FailureInterval": 30, + "ServerUpdate": "00:00" + }, + "OpsiMeowfficerFarming": { + "ActionPointPreserve": 1000, + "HazardLevel": 5, + "TargetZone": 0 + }, + "OpsiFleet": { + "Fleet": 1, + "Submarine": false + }, + "Storage": { + "Storage": {} + } + }, + "OpsiHazard1Leveling": { + "Scheduler": { + "Enable": false, + "NextRun": "2026-06-07 17:20:14", + "Command": "OpsiHazard1Leveling", + "SuccessInterval": 30, + "FailureInterval": 60, + "ServerUpdate": "00:00, 12:00" + }, + "OpsiHazard1Leveling": { + "TargetZone": 0 + }, + "OpsiFleet": { + "Fleet": 1, + "Submarine": false + }, + "Storage": { + "Storage": {} + } + }, + "OpsiCrossMonth": { + "Scheduler": { + "Enable": false, + "NextRun": "2020-01-01 00:00:00", + "Command": "OpsiCrossMonth", + "SuccessInterval": 0, + "FailureInterval": 120, + "ServerUpdate": "00:00" + }, + "Storage": { + "Storage": {} + } + }, + "Daemon": { + "Daemon": { + "EnterMap": true + }, + "Storage": { + "Storage": {} + } + }, + "OpsiDaemon": { + "OpsiDaemon": { + "RepairShip": true, + "SelectEnemy": true + }, + "Storage": { + "Storage": {} + } + }, + "EventStory": { + "EventStory": { + "SkipBattle": true + }, + "Storage": { + "Storage": {} + } + }, + "Benchmark": { + "Benchmark": { + "DeviceType": "android_phone", + "TestScene": "screenshot_click" + }, + "Storage": { + "Storage": {} + } + }, + "AzurLaneUncensored": { + "AzurLaneUncensored": { + "Repository": "https://gitee.com/LmeSzinc/AzurLaneUncensored" + }, + "Storage": { + "Storage": {} + } + }, + "GameManager": { + "GameManager": { + "AutoRestart": false + }, + "Storage": { + "Storage": {} + } + } +} \ No newline at end of file diff --git a/deploy/docker/Dockerfile b/deploy/docker/Dockerfile index 66d09ad073..dbd9a1f06a 100644 --- a/deploy/docker/Dockerfile +++ b/deploy/docker/Dockerfile @@ -1,23 +1,95 @@ +# syntax=docker/dockerfile:1.4 # docker build -t hgjazhgj/alas:latest . -# docker run -v ${PWD}:/app/AzurLaneAutoScript -p 22267:22267 --name alas -it --rm hgjazhgj/alas +# docker run -v ${PWD}:/app/AzurLaneAutoScript -p 22212:22212 --name alas -it --rm hgjazhgj/alas -FROM python:3.7-slim-bullseye +# Native arm64 needs source builds for some old scientific packages, so keep +# expensive steps split into cacheable layers. +ARG ALAS_DOCKER_PLATFORM=linux/arm64 +FROM --platform=${ALAS_DOCKER_PLATFORM} python:3.7-slim-bullseye +ARG WATCHEXEC_VERSION=2.5.1 WORKDIR /app/AzurLaneAutoScript COPY requirements.txt /tmp/requirements.txt # Initial download of UiAutomator2 is slow outside of China using appetizer mirror, switch to GitHub -RUN apt update \ - && apt install -y git adb libgomp1 openssh-client \ - && apt install -y build-essential pkg-config \ - && apt install -y libavformat-dev libavcodec-dev libavdevice-dev \ - && apt install -y libavutil-dev libswscale-dev libswresample-dev libavfilter-dev \ - && git config --global --add safe.directory '*' \ - && pip install Cython==0.29.37 \ - && pip install av==10.0.0 --no-build-isolation \ - && pip install -r /tmp/requirements.txt \ - && rm /tmp/requirements.txt \ - && rm -r ~/.cache/pip - -CMD python gui.py +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + adb \ + build-essential \ + ca-certificates \ + curl \ + gfortran \ + git \ + libavcodec-dev \ + libavdevice-dev \ + libavfilter-dev \ + libavformat-dev \ + libavutil-dev \ + libgomp1 \ + liblapack-dev \ + libopenblas-dev \ + libswresample-dev \ + libswscale-dev \ + openssh-client \ + pkg-config \ + && rm -rf /var/lib/apt/lists/* + +RUN git config --global --add safe.directory '*' + +RUN set -eux; \ + arch="$(dpkg --print-architecture)"; \ + case "${arch}" in \ + amd64) watchexec_arch="x86_64-unknown-linux-musl" ;; \ + arm64) watchexec_arch="aarch64-unknown-linux-musl" ;; \ + *) echo "Unsupported architecture for watchexec: ${arch}" >&2; exit 1 ;; \ + esac; \ + curl -fsSL -o /tmp/watchexec.deb \ + "https://github.com/watchexec/watchexec/releases/download/v${WATCHEXEC_VERSION}/watchexec-${WATCHEXEC_VERSION}-${watchexec_arch}.deb"; \ + apt-get update; \ + apt-get install -y --no-install-recommends /tmp/watchexec.deb; \ + rm -f /tmp/watchexec.deb; \ + rm -rf /var/lib/apt/lists/* + +RUN --mount=type=cache,target=/root/.cache/pip \ + pip install Cython==0.29.37 + +RUN --mount=type=cache,target=/root/.cache/pip \ + pip install av==10.0.0 --no-build-isolation + +RUN --mount=type=cache,target=/root/.cache/pip \ + pip install numpy==1.16.6 + +RUN --mount=type=cache,target=/root/.cache/pip \ + pip install pybind11==2.4.3 + +ENV FFLAGS="-fallow-argument-mismatch" \ + FCFLAGS="-fallow-argument-mismatch" + +RUN --mount=type=cache,target=/root/.cache/pip \ + pip install scipy==1.4.1 --no-build-isolation + +RUN --mount=type=cache,target=/root/.cache/pip \ + pip install -r /tmp/requirements.txt \ + && rm /tmp/requirements.txt + +# PyPI mxnet 1.6.0 has no usable arm64 libmxnet.so. +RUN --mount=type=cache,target=/root/.cache/pip \ + case "$(uname -m)" in \ + aarch64|arm64) \ + pip uninstall -y mxnet \ + && pip install https://raw.githubusercontent.com/binss/python-wheel/main/mxnet-1.9.1-py3-none-any.whl \ + ;; \ + esac + +# Runtime libs required by the custom arm64 MXNet wheel. +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + libatlas3-base \ + libopencv-imgcodecs4.5 \ + && rm -rf /var/lib/apt/lists/* + +ENV LD_LIBRARY_PATH=/usr/local/mxnet \ + MXNET_LIBRARY_PATH=/usr/local/mxnet/libmxnet.so + +CMD ["watchexec", "--restart", "--poll", "2s", "--debounce", "1s", "--exts", "py,json,yaml,yml,toml,txt,html,css,js,ts,vue,png,jpg,jpeg,gif", "--watch", "alas.py", "--watch", "gui.py", "--watch", "module", "--watch", "campaign", "--watch", "assets", "--watch", "webapp", "--ignore", "**/.git/**", "--ignore", "**/__pycache__/**", "--ignore", "**/.pytest_cache/**", "--ignore", "**/.mypy_cache/**", "--ignore", "**/.ruff_cache/**", "--ignore", "**/.cache/**", "--ignore", "log/**", "--ignore", "logs/**", "--ignore", "tmp/**", "--ignore", "temp/**", "--", "python", "gui.py", "--host", "127.0.0.1", "--port", "22212"] diff --git a/module/combat/assets.py b/module/combat/assets.py index 142b65e71f..d4bb52caf3 100644 --- a/module/combat/assets.py +++ b/module/combat/assets.py @@ -29,10 +29,10 @@ EXP_INFO_C = Button(area={'cn': (332, 56, 345, 107), 'en': (332, 56, 345, 107), 'jp': (332, 56, 345, 107), 'tw': (332, 56, 345, 107)}, color={'cn': (198, 208, 198), 'en': (198, 208, 198), 'jp': (198, 208, 198), 'tw': (198, 208, 198)}, button={'cn': (1133, 634, 1262, 650), 'en': (1133, 634, 1262, 650), 'jp': (1133, 634, 1262, 650), 'tw': (1133, 634, 1262, 650)}, file={'cn': './assets/cn/combat/EXP_INFO_C.png', 'en': './assets/en/combat/EXP_INFO_C.png', 'jp': './assets/jp/combat/EXP_INFO_C.png', 'tw': './assets/tw/combat/EXP_INFO_C.png'}) EXP_INFO_D = Button(area={'cn': (328, 45, 341, 119), 'en': (328, 45, 341, 119), 'jp': (328, 45, 341, 119), 'tw': (328, 45, 341, 119)}, color={'cn': (199, 208, 199), 'en': (199, 208, 199), 'jp': (199, 208, 199), 'tw': (199, 208, 199)}, button={'cn': (1133, 634, 1262, 650), 'en': (1133, 634, 1262, 650), 'jp': (1133, 634, 1262, 650), 'tw': (1133, 634, 1262, 650)}, file={'cn': './assets/cn/combat/EXP_INFO_D.png', 'en': './assets/en/combat/EXP_INFO_D.png', 'jp': './assets/jp/combat/EXP_INFO_D.png', 'tw': './assets/tw/combat/EXP_INFO_D.png'}) EXP_INFO_S = Button(area={'cn': (342, 107, 389, 119), 'en': (342, 107, 389, 119), 'jp': (342, 107, 389, 119), 'tw': (342, 107, 389, 119)}, color={'cn': (233, 242, 127), 'en': (233, 242, 127), 'jp': (233, 242, 127), 'tw': (233, 242, 127)}, button={'cn': (1133, 634, 1262, 650), 'en': (1133, 634, 1262, 650), 'jp': (1133, 634, 1262, 650), 'tw': (1133, 634, 1262, 650)}, file={'cn': './assets/cn/combat/EXP_INFO_S.png', 'en': './assets/en/combat/EXP_INFO_S.png', 'jp': './assets/jp/combat/EXP_INFO_S.png', 'tw': './assets/tw/combat/EXP_INFO_S.png'}) -GET_ITEMS_1 = Button(area={'cn': (538, 217, 741, 253), 'en': (550, 215, 739, 246), 'jp': (539, 220, 741, 252), 'tw': (539, 217, 742, 253)}, color={'cn': (160, 192, 248), 'en': (157, 187, 233), 'jp': (146, 184, 249), 'tw': (155, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_1.png', 'en': './assets/en/combat/GET_ITEMS_1.png', 'jp': './assets/jp/combat/GET_ITEMS_1.png', 'tw': './assets/tw/combat/GET_ITEMS_1.png'}) +GET_ITEMS_1 = Button(area={'cn': (538, 217, 741, 253), 'en': (550, 215, 739, 246), 'jp': (539, 220, 741, 252), 'tw': (539, 217, 742, 253)}, color={'cn': (160, 192, 248), 'en': (157, 187, 233), 'jp': (143, 182, 250), 'tw': (155, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_1.png', 'en': './assets/en/combat/GET_ITEMS_1.png', 'jp': './assets/jp/combat/GET_ITEMS_1.png', 'tw': './assets/tw/combat/GET_ITEMS_1.png'}) GET_ITEMS_1_RYZA = Button(area={'cn': (564, 217, 721, 245), 'en': (577, 211, 704, 239), 'jp': (566, 217, 719, 244), 'tw': (564, 218, 723, 246)}, color={'cn': (176, 199, 243), 'en': (172, 199, 246), 'jp': (179, 201, 243), 'tw': (173, 197, 242)}, button={'cn': (1000, 631, 1055, 689), 'en': (1000, 631, 1055, 689), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_1_RYZA.png', 'en': './assets/en/combat/GET_ITEMS_1_RYZA.png', 'jp': './assets/jp/combat/GET_ITEMS_1_RYZA.png', 'tw': './assets/tw/combat/GET_ITEMS_1_RYZA.png'}) -GET_ITEMS_2 = Button(area={'cn': (538, 146, 742, 182), 'en': (549, 140, 740, 176), 'jp': (536, 146, 741, 182), 'tw': (538, 148, 741, 182)}, color={'cn': (160, 192, 248), 'en': (152, 185, 236), 'jp': (145, 182, 249), 'tw': (155, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_2.png', 'en': './assets/en/combat/GET_ITEMS_2.png', 'jp': './assets/jp/combat/GET_ITEMS_2.png', 'tw': './assets/tw/combat/GET_ITEMS_2.png'}) -GET_ITEMS_3 = Button(area={'cn': (539, 143, 742, 179), 'en': (548, 136, 740, 172), 'jp': (540, 143, 742, 179), 'tw': (546, 145, 742, 178)}, color={'cn': (161, 193, 248), 'en': (152, 185, 237), 'jp': (145, 182, 248), 'tw': (156, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_3.png', 'en': './assets/en/combat/GET_ITEMS_3.png', 'jp': './assets/jp/combat/GET_ITEMS_3.png', 'tw': './assets/tw/combat/GET_ITEMS_3.png'}) +GET_ITEMS_2 = Button(area={'cn': (538, 146, 742, 182), 'en': (549, 140, 740, 176), 'jp': (536, 146, 741, 182), 'tw': (538, 148, 741, 182)}, color={'cn': (160, 192, 248), 'en': (152, 185, 236), 'jp': (132, 169, 233), 'tw': (155, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_2.png', 'en': './assets/en/combat/GET_ITEMS_2.png', 'jp': './assets/jp/combat/GET_ITEMS_2.png', 'tw': './assets/tw/combat/GET_ITEMS_2.png'}) +GET_ITEMS_3 = Button(area={'cn': (539, 143, 742, 179), 'en': (548, 136, 740, 172), 'jp': (540, 143, 742, 179), 'tw': (546, 145, 742, 178)}, color={'cn': (161, 193, 248), 'en': (152, 185, 237), 'jp': (143, 182, 250), 'tw': (156, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_3.png', 'en': './assets/en/combat/GET_ITEMS_3.png', 'jp': './assets/jp/combat/GET_ITEMS_3.png', 'tw': './assets/tw/combat/GET_ITEMS_3.png'}) GET_ITEMS_3_CHECK = Button(area={'cn': (335, 184, 947, 203), 'en': (335, 184, 947, 203), 'jp': (335, 184, 947, 203), 'tw': (335, 184, 947, 203)}, color={'cn': (84, 95, 109), 'en': (84, 95, 109), 'jp': (84, 95, 109), 'tw': (84, 95, 109)}, button={'cn': (335, 184, 947, 203), 'en': (335, 184, 947, 203), 'jp': (335, 184, 947, 203), 'tw': (335, 184, 947, 203)}, file={'cn': './assets/cn/combat/GET_ITEMS_3_CHECK.png', 'en': './assets/en/combat/GET_ITEMS_3_CHECK.png', 'jp': './assets/jp/combat/GET_ITEMS_3_CHECK.png', 'tw': './assets/tw/combat/GET_ITEMS_3_CHECK.png'}) GET_SHIP = Button(area={'cn': (1104, 610, 1110, 630), 'en': (1104, 610, 1110, 630), 'jp': (1104, 610, 1110, 630), 'tw': (1104, 610, 1110, 630)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_SHIP.png', 'en': './assets/en/combat/GET_SHIP.png', 'jp': './assets/jp/combat/GET_SHIP.png', 'tw': './assets/tw/combat/GET_SHIP.png'}) LOADING_BAR = Button(area={'cn': (33, 676, 1247, 680), 'en': (33, 676, 1247, 680), 'jp': (33, 676, 1247, 680), 'tw': (33, 676, 1247, 680)}, color={'cn': (172, 205, 232), 'en': (172, 205, 232), 'jp': (172, 205, 232), 'tw': (172, 205, 232)}, button={'cn': (33, 676, 1247, 680), 'en': (33, 676, 1247, 680), 'jp': (33, 676, 1247, 680), 'tw': (33, 676, 1247, 680)}, file={'cn': './assets/cn/combat/LOADING_BAR.png', 'en': './assets/en/combat/LOADING_BAR.png', 'jp': './assets/jp/combat/LOADING_BAR.png', 'tw': './assets/tw/combat/LOADING_BAR.png'}) diff --git a/module/device/app_control.py b/module/device/app_control.py index 8a681aa6a0..b8f369a8c4 100644 --- a/module/device/app_control.py +++ b/module/device/app_control.py @@ -48,6 +48,10 @@ def app_stop(self): else: self.app_stop_adb() + def go_home(self): + logger.info(f'Go home: {self.package}') + self.go_home_adb() + def hierarchy_timer_set(self, interval=None): if interval is None: interval = 0.1 diff --git a/module/device/connection.py b/module/device/connection.py index f806be4211..5a6d926fb3 100644 --- a/module/device/connection.py +++ b/module/device/connection.py @@ -1004,6 +1004,13 @@ def get_orientation(self): logger.attr('Device Orientation', f'{o} ({Connection._orientation_description.get(o, "Unknown")})') return o + @retry + def wake(self): + """ + Attempts to wake device by pressing power button + """ + self.adb_shell(['input', 'keyevent', 'KEYCODE_WAKEUP']) + @retry def list_device(self): """ diff --git a/module/device/device.py b/module/device/device.py index a1519df472..b1c71c1066 100644 --- a/module/device/device.py +++ b/module/device/device.py @@ -188,6 +188,7 @@ def screenshot(self): self.stuck_record_check() try: + super().wake() super().screenshot() except RequestHumanTakeover: if not self.ascreencap_available: @@ -337,3 +338,12 @@ def app_stop(self): super().app_stop() self.stuck_record_clear() self.click_record_clear() + + def go_home(self): + if not self.config.Error_HandleError: + logger.critical('No app stop/start, because HandleError disabled') + logger.critical('Please enable Alas.Error.HandleError or manually login to AzurLane') + raise RequestHumanTakeover + super().go_home() + self.stuck_record_clear() + self.click_record_clear() diff --git a/module/device/method/adb.py b/module/device/method/adb.py index c4f7499f95..36aad7778b 100644 --- a/module/device/method/adb.py +++ b/module/device/method/adb.py @@ -388,6 +388,13 @@ def app_stop_adb(self, package_name=None): package_name = self.package self.adb_shell(['am', 'force-stop', package_name]) + @retry + def go_home_adb(self, package_name=None): + """ Stop one application: am force-stop""" + if not package_name: + package_name = self.package + self.adb_shell(['input', 'keyevent', 'KEYCODE_HOME']) + @retry def dump_hierarchy_adb(self, temp: str = '/data/local/tmp/hierarchy.xml') -> etree._Element: """ diff --git a/module/gacha/assets.py b/module/gacha/assets.py index efb61b91db..5f88e13162 100644 --- a/module/gacha/assets.py +++ b/module/gacha/assets.py @@ -6,7 +6,7 @@ BUILD_CUBE_COUNT = Button(area={'cn': (853, 104, 938, 138), 'en': (872, 106, 925, 137), 'jp': (861, 108, 936, 134), 'tw': (872, 106, 925, 137)}, color={'cn': (59, 62, 73), 'en': (82, 84, 95), 'jp': (83, 86, 96), 'tw': (82, 84, 95)}, button={'cn': (853, 104, 938, 138), 'en': (872, 106, 925, 137), 'jp': (861, 108, 936, 134), 'tw': (872, 106, 925, 137)}, file={'cn': './assets/cn/gacha/BUILD_CUBE_COUNT.png', 'en': './assets/en/gacha/BUILD_CUBE_COUNT.png', 'jp': './assets/jp/gacha/BUILD_CUBE_COUNT.png', 'tw': './assets/tw/gacha/BUILD_CUBE_COUNT.png'}) BUILD_FINISH_ORDERS = Button(area={'cn': (1117, 95, 1265, 146), 'en': (1122, 99, 1261, 140), 'jp': (1141, 109, 1244, 134), 'tw': (1117, 95, 1265, 145)}, color={'cn': (182, 142, 84), 'en': (175, 132, 76), 'jp': (211, 167, 105), 'tw': (180, 140, 83)}, button={'cn': (1117, 95, 1265, 146), 'en': (1122, 99, 1261, 140), 'jp': (1141, 109, 1244, 134), 'tw': (1117, 95, 1265, 145)}, file={'cn': './assets/cn/gacha/BUILD_FINISH_ORDERS.png', 'en': './assets/en/gacha/BUILD_FINISH_ORDERS.png', 'jp': './assets/jp/gacha/BUILD_FINISH_ORDERS.png', 'tw': './assets/tw/gacha/BUILD_FINISH_ORDERS.png'}) -BUILD_FINISH_RESULTS = Button(area={'cn': (540, 193, 740, 229), 'en': (550, 187, 737, 219), 'jp': (550, 193, 738, 229), 'tw': (561, 193, 726, 230)}, color={'cn': (163, 193, 248), 'en': (158, 187, 234), 'jp': (159, 194, 248), 'tw': (157, 188, 241)}, button={'cn': (540, 193, 740, 229), 'en': (550, 187, 737, 219), 'jp': (550, 193, 738, 229), 'tw': (561, 193, 726, 230)}, file={'cn': './assets/cn/gacha/BUILD_FINISH_RESULTS.png', 'en': './assets/en/gacha/BUILD_FINISH_RESULTS.png', 'jp': './assets/jp/gacha/BUILD_FINISH_RESULTS.png', 'tw': './assets/tw/gacha/BUILD_FINISH_RESULTS.png'}) +BUILD_FINISH_RESULTS = Button(area={'cn': (540, 193, 740, 229), 'en': (550, 187, 737, 219), 'jp': (550, 193, 738, 229), 'tw': (561, 193, 726, 230)}, color={'cn': (163, 193, 248), 'en': (158, 187, 234), 'jp': (158, 193, 247), 'tw': (157, 188, 241)}, button={'cn': (540, 193, 740, 229), 'en': (550, 187, 737, 219), 'jp': (550, 193, 738, 229), 'tw': (561, 193, 726, 230)}, file={'cn': './assets/cn/gacha/BUILD_FINISH_RESULTS.png', 'en': './assets/en/gacha/BUILD_FINISH_RESULTS.png', 'jp': './assets/jp/gacha/BUILD_FINISH_RESULTS.png', 'tw': './assets/tw/gacha/BUILD_FINISH_RESULTS.png'}) BUILD_MINUS = Button(area={'cn': (569, 253, 613, 295), 'en': (525, 255, 565, 293), 'jp': (571, 255, 611, 293), 'tw': (569, 253, 613, 295)}, color={'cn': (80, 131, 200), 'en': (81, 132, 200), 'jp': (81, 132, 201), 'tw': (80, 131, 200)}, button={'cn': (569, 253, 613, 295), 'en': (525, 255, 565, 293), 'jp': (571, 255, 611, 293), 'tw': (569, 253, 613, 295)}, file={'cn': './assets/cn/gacha/BUILD_MINUS.png', 'en': './assets/en/gacha/BUILD_MINUS.png', 'jp': './assets/jp/gacha/BUILD_MINUS.png', 'tw': './assets/tw/gacha/BUILD_MINUS.png'}) BUILD_PLUS = Button(area={'cn': (748, 253, 792, 295), 'en': (704, 255, 744, 293), 'jp': (750, 255, 790, 293), 'tw': (748, 253, 792, 295)}, color={'cn': (85, 135, 203), 'en': (86, 135, 204), 'jp': (87, 136, 204), 'tw': (85, 135, 203)}, button={'cn': (748, 253, 792, 295), 'en': (704, 255, 744, 293), 'jp': (750, 255, 790, 293), 'tw': (748, 253, 792, 295)}, file={'cn': './assets/cn/gacha/BUILD_PLUS.png', 'en': './assets/en/gacha/BUILD_PLUS.png', 'jp': './assets/jp/gacha/BUILD_PLUS.png', 'tw': './assets/tw/gacha/BUILD_PLUS.png'}) BUILD_QUEUE_EMPTY = Button(area={'cn': (639, 362, 700, 409), 'en': (639, 362, 700, 409), 'jp': (639, 362, 700, 409), 'tw': (639, 362, 700, 409)}, color={'cn': (157, 151, 152), 'en': (157, 151, 152), 'jp': (157, 151, 152), 'tw': (157, 151, 152)}, button={'cn': (639, 362, 700, 409), 'en': (639, 362, 700, 409), 'jp': (639, 362, 700, 409), 'tw': (639, 362, 700, 409)}, file={'cn': './assets/cn/gacha/BUILD_QUEUE_EMPTY.png', 'en': './assets/en/gacha/BUILD_QUEUE_EMPTY.png', 'jp': './assets/jp/gacha/BUILD_QUEUE_EMPTY.png', 'tw': './assets/tw/gacha/BUILD_QUEUE_EMPTY.png'}) diff --git a/run_single_task.py b/run_single_task.py new file mode 100644 index 0000000000..5a91aa40e0 --- /dev/null +++ b/run_single_task.py @@ -0,0 +1,4 @@ +from alas import AzurLaneAutoScript + +alas = AzurLaneAutoScript() +alas.research() # or any other task like commission(), tactical(), dorm(), etc. \ No newline at end of file diff --git a/setup.sh b/setup.sh new file mode 100644 index 0000000000..7295fbca6e --- /dev/null +++ b/setup.sh @@ -0,0 +1,3 @@ +conda create --name alas +conda activate alas +conda env update --file conda.yml --prune \ No newline at end of file diff --git a/start.ps1 b/start.ps1 new file mode 100644 index 0000000000..0a8fb32cd3 --- /dev/null +++ b/start.ps1 @@ -0,0 +1,4 @@ +tailscale serve --https=20012 --bg http://localhost:22212 +adb connect 10.0.0.114:5555 +. .venv\Scripts\activate.ps1 +python gui.py --run alas --port 22212 \ No newline at end of file diff --git a/start.sh b/start.sh new file mode 100755 index 0000000000..8594039c41 --- /dev/null +++ b/start.sh @@ -0,0 +1,3 @@ +tailscale serve --https=20012 --bg http://localhost:22212 +adb connect 10.0.0.114:5555 +docker compose up --build