Recently, I fully transitioned from Windows to the Manjaro system, and I must say it is really user-friendly. After switching to Manjaro, one important issue was how to run multiple instances of MAA Arknights to collect resources like before, since I need to collect resources twice a day, and manually collecting them for multiple accounts is too cumbersome.
Emulator#
First, MAA supports three types of Linux emulators: one is AVD, one is Waydroid, and one is redroid. I chose to use AVD, as it is relatively easier to use with Google support. The concept of Waydroid's containerization is good, but it seems to have no support for NVIDIA cards, so I passed on that.
AVD is integrated into Android Studio. First, download Android Studio from the AUR repository (do not use the flatpak repository, as containerization will make subsequent command line launches of the emulator very troublesome), configure the proxy, and after downloading the SDK, select
Of course, you can also choose to use AVD directly without Android Studio, but Android Studio provides a graphical interface that saves a lot of trouble.
Create a new device, set the resolution to 16:9 and greater than 720p, select the framework (R - 30 - x86 - Android 11.0), allocate appropriate configurations for each emulator according to your setup, and remember to enable hardware acceleration. At this point, you have successfully created an emulator supported by MAA, and you can install Arknights via adb.
Opening Android Studio every time to launch the emulator is very troublesome. In fact, you can directly open the emulator from the command line:
~/Android/Sdk/emulator/emulator -list-avds // Get the list of emulators
~/Android/Sdk/emulator/emulator -avd emulator_name // Start the specified emulator
MAA Configuration#
After downloading and extracting MAA from the official website, several methods are provided to call MAA: one is maa-cli, and the other is the Python interface, which are the AppImage file and the Python folder in the root directory of the extracted package. I looked at the configuration of maa-cli, and configuring tasks and running multiple instances is quite troublesome, so I chose to use the Python interface to start MAA. Open the sample.py file in the Python folder and modify it to complete the task configuration. First, configure the adb address and adb device name, then add tasks and set task parameters according to the documentation as needed. You can directly run python sample.py
to start collecting resources.
Every time a task is executed, having to modify the py file is very troublesome, so you can accept parameters when executing Python to choose which tasks to execute. Modify this sample file; below is my task configuration.
import json
import pathlib
import time
import argparse
from asst.asst import Asst
from asst.utils import Message, Version, InstanceOptionType
from asst.updater import Updater
from asst.emulator import Bluestacks
@Asst.CallBackType
def my_callback(msg, details, arg):
m = Message(msg)
d = json.loads(details.decode('utf-8'))
print(m, d, arg)
if __name__ == "__main__":
# Create ArgumentParser object
parser = argparse.ArgumentParser(description='Arknights Assistant Script')
# Add enable options for each task
parser.add_argument('--start-up', action='store_true', help='Enable StartUp task')
parser.add_argument('--recruit', action='store_true', help='Enable Recruit task')
parser.add_argument('--infrast', action='store_true', help='Enable Infrast task')
parser.add_argument('--visit', action='store_true', help='Enable Visit task')
parser.add_argument('--mall', action='store_true', help='Enable Mall task')
parser.add_argument('--fight', action='store_true', help='Enable Fight task')
parser.add_argument('--award', action='store_true', help='Enable Award task')
parser.add_argument('--stage', type=str, default=None, help='Specify the stage for Fight task')
args = parser.parse_args()
# Please set the path for storing dll files and resources
path = pathlib.Path(__file__).resolve().parent.parent
# Set the updater's path and target version and update
# Updater(path, Version.Stable).update()
Asst.load(path=path)
asst = Asst()
asst.set_instance_option(InstanceOptionType.touch_type, 'maatouch')
# Please configure the adb environment variable yourself, or modify it to the path of the adb executable
if asst.connect('/home/linsoap/Android/Sdk/platform-tools/adb', 'emulator-5554'):
print('Connection successful')
else:
print('Connection failed')
exit()
# For tasks and parameters, please refer to docs/integration_document.md
if args.start_up:
asst.append_task('StartUp', {
'client_type': 'Official',
'start_game_enabled': True
})
if args.recruit:
asst.append_task('Recruit', {
'enable': True,
'select': [4],
'confirm': [3, 4],
'times': 4
})
if args.infrast:
asst.append_task('Infrast', {
'enable': True,
'facility': [
"Mfg", "Trade", "Control", "Power", "Reception", "Office", "Dorm"
],
'drones': "Money"
})
if args.visit:
asst.append_task('Visit')
if args.mall:
asst.append_task('Mall', {
'shopping': True,
'buy_first': ['Recruit Permit', 'Lungmen Coins'],
'blacklist': ['Furniture', 'Carbon'],
})
if args.fight:
fight_params = {'enable': True}
if args.stage:
fight_params['stage'] = args.stage
asst.append_task('Fight', fight_params)
if args.award:
asst.append_task('Award', {
'enable': True,
})
asst.start()
while asst.running():
time.sleep(0)
The Updater class currently has some issues, so it is recommended to comment it out for now, and uncomment it when the bug is fixed.
After installing the above configuration, you can use the following command to start MAA.
python emulator-54.py --start-up --recruit --infrast --visit --mall --fight --stage AP-5 --award
One-Click Script#
One-Click Start Emulator#
To achieve one-click resource collection, a script is needed to start multiple emulators and MAA with one click.
First, copy multiple sample.py files and modify the adb names within them.
The first issue encountered is that the adb names for AVD are not fixed but are assigned according to the launch order. I have two official accounts and one B server account, and the random adb names can cause the StartUp task to fail. Therefore, when running multiple instances, it is necessary to specify ports so that the corresponding clients can execute the corresponding tasks.
#!/bin/bash
while [ "$#" -gt 0 ]; do
case "$1" in
--start)
shift
while [ "$#" -gt 0 ]; do
case "$1" in
--all)
echo "Starting all emulators..."
/home/linsoap/Android/Sdk/emulator/emulator -avd aknz -ports 5554,5555 &
/home/linsoap/Android/Sdk/emulator/emulator -avd aknz_1 -ports 5556,5557 &
/home/linsoap/Android/Sdk/emulator/emulator -avd mrfz -ports 5558,5559 &
shift
;;
--list)
echo "Available emulators:"
/home/linsoap/Android/Sdk/emulator/emulator -list-avds
shift
;;
-*)
echo "Unknown option: $1"
exit 1
;;
*)
echo "Starting emulator: $1"
/home/linsoap/Android/Sdk/emulator/emulator -avd "$1" &
shift
;;
esac
done
;;
--stop)
shift
while [ "$#" -gt 0 ]; do
case "$1" in
--all)
echo "Stopping all emulators..."
/home/linsoap/Android/Sdk/platform-tools/adb -s emulator-5554 emu kill
/home/linsoap/Android/Sdk/platform-tools/adb -s emulator-5556 emu kill
/home/linsoap/Android/Sdk/platform-tools/adb -s emulator-5558 emu kill
shift
;;
-*)
echo "Unknown option: $1"
exit 1
;;
*)
echo "Stopping emulator: $1"
/home/linsoap/Android/Sdk/platform-tools/adb -s "$1" emu kill
shift
;;
esac
done
;;
-*)
echo "Unknown option: $1"
exit 1
;;
esac
done
The above is a one-click start script generated by ChatGPT. You can let GPT generate scripts according to your needs.
- Start all emulators:
./your_script.sh --start --all
- Start a specific emulator:
./your_script.sh --start <emulator_name>
- View the list of available emulators:
./your_script.sh --start --list
- Stop all emulators:
./your_script.sh --stop --all
- Stop a specific emulator:
./your_script.sh --stop <emulator_name>
One-Click Start MAA#
After modifying sample.py to accept parameters for selecting enabled tasks, writing a one-click start MAA script becomes easy. You can also use ChatGPT to generate scripts according to your needs. Below is my script.
#!/bin/bash
# Set the list of Python script files to execute
python_scripts=("emulator-54.py" "emulator-56.py" "emulator-58.py")
# Default parameter values
all_flag=false
only_fight_flag=false
unfight_flag=false
stage_value=""
# Parse command line parameters
while [ "$#" -gt 0 ]; do
case "$1" in
--all)
all_flag=true
;;
--only-fight)
only_fight_flag=true
;;
--unfight)
unfight_flag=true
;;
-stage|--stage)
shift
stage_value="$1"
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
shift
done
# Check parameter combinations
if [ "$all_flag" = true ] && [ "$only_fight_flag" = true ]; then
echo "Cannot use --all and --only-fight together."
exit 1
fi
# Construct command line argument string
args="--start-up"
if [ "$all_flag" = true ] || [ "$only_fight_flag" = true ]; then
args+=" --recruit --infrast --visit --mall --award --fight"
fi
if [ "$only_fight_flag" = true ]; then
args+=" --fight"
fi
if [ -n "$stage_value" ]; then
args+=" --stage $stage_value"
fi
# Execute three Python commands serially
for script in "${python_scripts[@]}"; do
# Output the current task being executed
echo "Executing tasks in $script"
# Execute serially
python "$script" $args & echo "Finished tasks in $script" || echo "Failed to execute tasks in $script"
done
echo "All tasks completed"
This script supports the following commands:
--all
: Start all tasks, including--start-up
,--recruit
,--infrast
,--visit
,--mall
,--award
, and--fight
.--only-fight
: Start all tasks, including--start-up
and--fight
.--unfight
: Start all tasks but exclude--fight
.--stage <value>
or-stage <value>
: Specify the value for the task stage.