Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

不养闲人任务合并+优化ui路径+自定义副表名称+仅回满提前上班 #693

Merged
merged 16 commits into from
Sep 27, 2024
Merged
26 changes: 26 additions & 0 deletions arknights_mower/solvers/base_schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
add_release_dorm,
check_dorm_ordering,
find_next_task,
merge_release_dorm,
scheduling,
try_add_release_dorm,
)
Expand Down Expand Up @@ -463,7 +464,11 @@ def plan_metadata(self):
__time = dorm.time
else:
__time = datetime.max
need_early = True
for x in __rest_agent:
# 如果小组内没有耗尽,则提前8分钟上班
if self.op_data.operators[x].exhaust_require:
need_early = False
# 如果同小组也是rest_in_full则取最大休息时间 否则忽略
if x in low_priority:
logger.debug("检测到回满组已经安排")
Expand All @@ -489,6 +494,9 @@ def plan_metadata(self):
if __time < datetime.now():
__time = datetime.now()
if __time != datetime.max:
if need_early:
__time -= timedelta(minutes=8)
logger.info("全组无耗尽,提前8分钟上班")
self.tasks.append(
SchedulerTask(
time=__time,
Expand Down Expand Up @@ -578,19 +586,33 @@ def plan_metadata(self):
logger.debug("检测到时间数据不存在")
self.op_data.reset_dorm_time()
self.error = True
self.tasks.sort(key=lambda task: task.time)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这行不需要了对吧?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

之前append的任务应该默认是在tasks的最后一个吧?我不是很清楚有没有排过序,就加了一行这个。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scheduling 方法每次任务开始的时候都自带排序的,所以不要刻意排序

# 最后再做不养闲人刷新
if self.op_data.config.free_room:

def should_keep(task):
if task.type != TaskTypes.RELEASE_DORM:
return True
name = task.meta_data
for key, value in task.plan.items():
dorm_name = key
dorm_op = value
break
if (
self.op_data.operators[name].current_room != dorm_name
or dorm_op[self.op_data.operators[name].current_index] != "Free"
):
logger.info(f"检测到{task.meta_data}不在对应位置,移除相关任务")
return False
i, d = self.op_data.get_dorm_by_name(task.meta_data)
if i is None:
logger.info(f"检测到{task.meta_data}不在宿舍,移除相关任务")
return False
return True

self.tasks = [t for t in self.tasks if should_keep(t)]
merge_interval = config.conf.merge_interval
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/ArkMowers/arknights-mower/blob/2024.9.4/arknights_mower/utils/scheduler_task.py

有关改动能移到这里嘛,这边是对任务进行的改动。

merge_release_dorm(self.tasks, merge_interval)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这部分能移到任务开始的时候嘛。那里有个任务调度逻辑

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这样做问题就是生成不养闲人时候,假如不养闲人就是最近的任务怎么办


def infra_main(self):
"""位于基建首页"""
Expand Down Expand Up @@ -3287,6 +3309,7 @@ def append_maa_task(self, type):
"credit_fight": conf.maa_credit_fight
and "" not in self.stages
and self.credit_fight is None,
"select_formation": conf.credit_fight.squad,
"force_shopping_if_credit_full": conf.maa_mall_ignore_blacklist_when_full,
},
)
Expand Down Expand Up @@ -3339,6 +3362,9 @@ def maa_plan_solver(self, tasks="All", one_time=False):
):
self.MAA.stop()
hard_stop = True
elif config.stop_maa.is_set():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这是里是什么意思呀

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

就是立即停止上面有个停止maa按钮,点了那个可以中断maa的任务。

self.MAA.stop()
hard_stop = True
else:
self.sleep(5)
if hard_stop:
Expand Down
2 changes: 2 additions & 0 deletions arknights_mower/utils/config/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,8 @@ class RunOrderGrandetModeConf(ConfModel):
"菲亚防呆"
fia_threshold: float = 0.9
"菲亚阈值"
merge_interval: float = 10
"不养闲人合并间隔"


class SimulatorPart(ConfModel):
Expand Down
1 change: 1 addition & 0 deletions arknights_mower/utils/config/plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class BackupPlan(BaseModel):
task: Task = {}
trigger: Trigger = {}
trigger_timing: str = "AFTER_PLANNING"
name: str = "plan"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

名字可以不用传到后端,因为后端不需要名字对吧?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

是的,只在前端的标题里面看



class PlanModel(BaseModel):
Expand Down
14 changes: 2 additions & 12 deletions arknights_mower/utils/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def calculate_switch_time(self, support: SkillUpgradeSupport):
# 基本5%
basic = 5
if support.add_on:
# 阿斯卡伦
# 阿斯卡纶
basic += 5
if hour == 0:
hour = level * 8
Expand Down Expand Up @@ -364,16 +364,6 @@ def init_mood_limit(self):
else:
self.set_mood_limit(TOTTER, upper_limit=24, lower_limit=20)

# 减少仅回满干员的心情阈值0.5
for name in self.operators:
if (
self.operators[name].rest_in_full
and self.operators[name].exhaust_require is not True
):
self.set_mood_limit(
name, upper_limit=self.operators[name].upper_limit - 0.5
)

def evaluate_expression(self, expression):
try:
result = Expr(expression, self.eval_model).eval({"op_data": self})
Expand Down Expand Up @@ -797,7 +787,7 @@ def not_valid(self):
return False
return (
# 歌蕾蒂娅主班 刷新心情频率提升
self.need_to_refresh(2.5 if self.name != "歌蕾蒂娅" else 0.5)
self.need_to_refresh(2.5)
or self.current_room != self.room
or self.index != self.current_index
)
Expand Down
1 change: 1 addition & 0 deletions arknights_mower/utils/plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ def __init__(
trigger: Optional[LogicExpression] = None,
task: Optional[dict[str, list[str]]] = None,
trigger_timing: Optional[str] = None,
name: Optional[str] = None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我觉得标题在 plan.json存就好 了,没必要传到后端?

):
"""
Args:
Expand Down
24 changes: 24 additions & 0 deletions arknights_mower/utils/scheduler_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,30 @@ def set_type_enum(value):
return TaskTypes.NOT_SPECIFIC


def merge_release_dorm(tasks, merge_interval):
for idx in range(1, len(tasks) + 1):
if idx == 1:
continue
task = tasks[-idx]
last_not_release = None
if task.type != TaskTypes.RELEASE_DORM:
continue
for index_last_not_release in range(idx + 1, len(tasks) + 1):
if tasks[-index_last_not_release].type != TaskTypes.RELEASE_DORM and tasks[
-index_last_not_release
].time > task.time - timedelta(minutes=1):
last_not_release = tasks[-index_last_not_release]
if last_not_release is not None:
continue
elif task.time + timedelta(minutes=merge_interval) > tasks[-idx + 1].time:
task.time = tasks[-idx + 1].time + timedelta(seconds=1)
tasks[-idx], tasks[-idx + 1] = (
tasks[-idx + 1],
tasks[-idx],
)
logger.info(f"自动合并{merge_interval}分钟以内任务")


class SchedulerTask:
time = None
type = ""
Expand Down
2 changes: 1 addition & 1 deletion manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def jump_to_index(window):
api = Api()
window = webview.create_window(
title="多开管理器",
url="dist/index.html",
url="ui/dist/index.html",
js_api=api,
min_size=(400, 500),
width=400,
Expand Down
8 changes: 4 additions & 4 deletions server.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
mimetypes.add_type("text/css", ".css")
mimetypes.add_type("application/javascript", ".js")

app = Flask(__name__, static_folder="dist", static_url_path="")
app = Flask(__name__, static_folder="ui/dist", static_url_path="")
sock = Sock(app)
CORS(app)

Expand Down Expand Up @@ -63,17 +63,17 @@ def decorated_function(*args, **kwargs):

@app.route("/<path:path>")
def serve_index(path):
return send_from_directory("dist", path)
return send_from_directory("ui/dist", path)


@app.errorhandler(404)
def not_found(e):
if (path := request.path).startswith("/docs"):
try:
return send_from_directory("dist" + path, "index.html")
return send_from_directory("ui/dist" + path, "index.html")
except NotFound:
return "<h1>404 Not Found</h1>", 404
return send_from_directory("dist", "index.html")
return send_from_directory("ui/dist", "index.html")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ui 的 read me 可以更新一下嘛

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

改好了



@app.route("/conf", methods=["GET", "POST"])
Expand Down
1 change: 1 addition & 0 deletions ui/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ declare module 'vue' {
PlanEditor: typeof import('./src/components/PlanEditor.vue')['default']
ReclamationAlgorithm: typeof import('./src/components/ReclamationAlgorithm.vue')['default']
Recruit: typeof import('./src/components/Recruit.vue')['default']
RenameDialog: typeof import('./src/components/RenameDialog.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
SecretFront: typeof import('./src/components/SecretFront.vue')['default']
Expand Down
53 changes: 53 additions & 0 deletions ui/src/components/RenameDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<script setup>
import { inject } from 'vue'
const show = inject('show_name_editor')

import { storeToRefs } from 'pinia'
import { usePlanStore } from '@/stores/plan'

const plan_store = usePlanStore()
const { sub_plan, backup_plans } = storeToRefs(plan_store)

const triggerTimingOptions = [
{ label: '任务开始', value: 'BEGINNING' },
{ label: '下班结束', value: 'BEFORE_PLANNING' },
{ label: '上班结束', value: 'AFTER_PLANNING' },
{ label: '任务结束', value: 'END' }
]

function update_trigger(data) {
backup_plans.value[sub_plan.value].trigger = data
}
</script>

<template>
<n-modal
v-model:show="show"
preset="card"
title="重命名"
transform-origin="center"
style="width: auto; max-width: 90vw"
>
<div class="dropdown-container">
<label class="dropdown-label">副表名称 </label>
<n-input v-model:value="backup_plans[sub_plan].name"> </n-input>
</div>
</n-modal>
</template>

<style>
.dropdown-container {
display: flex;
align-items: center;
margin-top: 5px;
}

.dropdown-label {
flex: 0 0 40%;
max-width: 125px;
}

.dropdown-select {
flex: 1;
}
</style>
24 changes: 20 additions & 4 deletions ui/src/pages/Plan.vue
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ const sub_plan_options = computed(() => {
]
for (let i = 0; i < backup_plans.value.length; i++) {
result.push({
label: `副表${i + 1}`,
label: backup_plans.value[i].name,
value: i
})
}
Expand All @@ -116,7 +116,8 @@ function create_sub_plan() {
right: ''
},
trigger_timing: 'AFTER_PLANNING',
task: {}
task: {},
name: `plan${backup_plans.value.length}`
})
sub_plan.value = backup_plans.value.length - 1
}
Expand Down Expand Up @@ -173,6 +174,9 @@ watchEffect(() => {
const show_trigger_editor = ref(false)
provide('show_trigger_editor', show_trigger_editor)

const show_name_editor = ref(false)
provide('show_name_editor', show_name_editor)

const show_task = ref(false)
const add_task = ref(false)
provide('show_task', show_task)
Expand All @@ -186,6 +190,7 @@ import CodeSlash from '@vicons/ionicons5/CodeSlash'
import TrashOutline from '@vicons/ionicons5/TrashOutline'
import AddTaskRound from '@vicons/material/AddTaskRound'
import PlusRound from '@vicons/material/PlusRound'
import Pencil from '@vicons/tabler/Pencil'

function import_plan({ event }) {
const msg = event.target.response
Expand Down Expand Up @@ -228,6 +233,7 @@ async function export_json() {
<template>
<trigger-dialog />
<task-dialog />
<rename-dialog />
<div class="plan-bar w-980 mx-auto mt-12 mw-980">
<n-button-group>
<n-button
Expand All @@ -247,7 +253,14 @@ async function export_json() {
</template>
</n-button>
</n-button-group>
<n-select v-model:value="sub_plan" :options="sub_plan_options" />
<n-button-group>
<n-select v-model:value="sub_plan" :style="{ width: '150px' }" :options="sub_plan_options" />
<n-button :disabled="sub_plan == 'main'" @click="show_name_editor = true">
<template #icon>
<n-icon><Pencil /></n-icon>
</template>
</n-button>
</n-button-group>
<n-button-group>
<n-button @click="create_sub_plan">
<template #icon>
Expand Down Expand Up @@ -370,7 +383,10 @@ async function export_json() {
<n-form-item>
<template #label>
<span>用尽刷新</span>
<help-text>上下班会影响用尽干员心情速率</help-text>
<help-text>
<p>会影响用尽干员心情消耗速率的干员</p>
<p>在填入该选项的干员上下班后,会重新读取用尽干员的下班时间</p>
</help-text>
</template>
<slick-operator-select v-model="current_conf.refresh_drained"></slick-operator-select>
</n-form-item>
Expand Down
13 changes: 13 additions & 0 deletions ui/src/pages/Settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const {
fix_mumu12_adb_disconnect,
touch_method,
free_room,
merge_interval,
fia_fool,
droidcast,
maa_adb_path,
Expand Down Expand Up @@ -527,6 +528,18 @@ const onSelectionChange = (newValue) => {
<help-text>干员心情回满后,立即释放宿舍空位</help-text>
</n-checkbox>
</n-form-item>
<n-form-item v-if="free_room">
<template #label>
<span>任务合并间隔</span>
<help-text>
<div>可填小数</div>
<div>将不养闲人任务合并至下一个指定间隔内的任务</div>
</help-text>
</template>
<n-input-number v-model:value="merge_interval">
<template #suffix>分钟</template>
</n-input-number>
</n-form-item>
<n-form-item :show-label="false">
<n-checkbox v-model:checked="fia_fool">
菲亚防呆
Expand Down
Loading