Skip to content

Commit

Permalink
Map 0-2 fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
waicool20 committed Jul 29, 2024
1 parent 5875573 commit 76634e7
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 155 deletions.
115 changes: 17 additions & 98 deletions modules/assets/combat/maps/0-2/map.json
Original file line number Diff line number Diff line change
@@ -1,110 +1,29 @@
[
{
"x": 491,
"y": 81,
"width": 46,
"height": 46
},
{
"x": 758,
"y": 79,
"width": 46,
"height": 46
},
{
"type": "CommandPost",
"x": 918,
"y": 100,
"width": 70,
"height": 70
"x": 595,
"y": 637,
"width": 75,
"height": 75
},
{
"type": "Heliport",
"x": 390,
"y": 184,
"width": 46,
"height": 46
},
{
"x": 628,
"y": 169,
"width": 46,
"height": 46
},
{
"x": 765,
"y": 262,
"width": 46,
"height": 46
"x": 252,
"y": 628,
"width": 75,
"height": 75
},
{
"x": 1002,
"y": 267,
"width": 46,
"height": 46
},
{
"x": 302,
"y": 299,
"width": 46,
"height": 46
},
{
"type": "Heliport",
"x": 502,
"y": 362,
"width": 46,
"height": 46
},
{
"type": "Heliport",
"x": 886,
"y": 382,
"width": 46,
"height": 46
},
{
"x": 313,
"y": 463,
"width": 46,
"height": 46
},
{
"x": 469,
"y": 559,
"width": 46,
"height": 46
},
{
"x": 762,
"y": 508,
"width": 46,
"height": 46
},
{
"type": "Heliport",
"x": 246,
"y": 640,
"width": 46,
"height": 46
"x": 479,
"y": 111,
"width": 75,
"height": 75
},
{
"type": "CommandPost",
"x": 599,
"y": 630,
"width": 83,
"height": 83
},
{
"x": 220,
"y": 846,
"width": 46,
"height": 46
},
{
"x": 476,
"y": 766,
"width": 46,
"height": 46
"x": 887,
"y": 142,
"width": 75,
"height": 75
}
]
]
Binary file modified modules/assets/combat/maps/0-2/map.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 35 additions & 21 deletions modules/core/src/main/kotlin/com/waicool20/wai2k/game/GFL.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ import com.waicool20.wai2k.events.DollDropEvent
import com.waicool20.wai2k.events.EventBus
import com.waicool20.wai2k.script.ScriptRunner
import com.waicool20.wai2k.util.loggerFor
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference
import kotlin.concurrent.thread

object GFL {
Expand All @@ -36,39 +40,43 @@ object GFL {

class LogcatListener(val scriptRunner: ScriptRunner, val device: AndroidDevice) {
private val logger = loggerFor<LogcatListener>()
private val isRunning = AtomicBoolean(false)
private var process: Process? = null
private val currentThread = AtomicReference<Thread?>(null)
private var currentProcess: Process? = null
private val r =
Regex("(\\d\\d-\\d\\d) (\\d\\d:\\d\\d:\\d\\d.\\d{3})\\s+(\\d+)\\s+(\\d+)\\s+([VDIWEFS])\\s+(\\w+)\\s+: (.*)\$")

fun start() {
if (!isRunning.compareAndSet(false, true)) return
thread(isDaemon = true, name = "Logcat Listener [${device.serial}]") {
while (isRunning.get()) {
if (process == null || process?.isAlive == false) {
if (device.isConnected()) {
ADB.execute("-s", device.serial, "logcat", "-c") // Clear logs
process = ADB.execute("-s", device.serial, "logcat", "Unity:V", "*:S")
} else {
TimeUnit.SECONDS.sleep(5)
}
while (!Thread.interrupted()) {
if (!device.isConnected()) {
TimeUnit.SECONDS.sleep(5)
continue
}
ADB.execute("-s", device.serial, "logcat", "-c") // Clear logs
val process = ADB.execute("-s", device.serial, "logcat", "Unity:V", "*:S")
try {
process?.inputStream?.bufferedReader()?.use { reader ->
reader.forEachLine {
if (!isRunning.get()) process?.destroy()
onNewLine(it)
}
}
process.inputStream.bufferedReader().forEachLine(::onNewLine)
} catch (e: Exception) {
// Ignore
}
}
isRunning.set(false)
}
currentProcess?.destroyForcibly()
currentThread.set(null)
}.also { currentThread.set(it) }
}

fun stop() {
isRunning.compareAndSet(true, false)
currentThread.get()?.interrupt()
currentProcess?.destroyForcibly()
}

private val _lines = MutableSharedFlow<String>(
replay = 1,
extraBufferCapacity = 2048,
onBufferOverflow = BufferOverflow.DROP_OLDEST
)
val lines = _lines.asSharedFlow()

private val gunCheckRegex = Regex(".*加载热更资源包名.+character(.+)\\.ab.*")
private var gotGun = false

Expand All @@ -77,6 +85,12 @@ object GFL {
!gotGun && l.contains("预制物GetNewGun") -> gotGun = true
gotGun -> checkForGun(l)
}
scriptRunner.sessionScope.launch {
val match = r.matchEntire(l) ?: return@launch
// date, time, pid, tid, level, tag, msg
val (_, _, _, _, _, _, msg) = match.destructured
_lines.emit(msg)
}
}

private fun checkForGun(l: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import com.waicool20.wai2k.config.Wai2kPersist
import com.waicool20.wai2k.config.Wai2kProfile
import com.waicool20.wai2k.game.location.GameLocation
import com.waicool20.wai2k.util.Ocr
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.first

interface ScriptComponent {
val scriptRunner: ScriptRunner
Expand All @@ -38,4 +40,55 @@ interface ScriptComponent {
val scope get() = scriptRunner.sessionScope
val sessionId get() = scriptRunner.sessionId
val elapsedTime get() = scriptRunner.elapsedTime


/**
* Searches the ADB logs for a certain string, returns false if the op times out or
* does not find the regex in the logs
*/
suspend fun waitForLog(
str: String,
timeout: Long = Long.MAX_VALUE,
fn: suspend () -> Unit = {}
): Boolean {
val job = scriptRunner.sessionScope.launch {
delay(250)
while (coroutineContext.isActive) fn()
}
try {
withTimeout(timeout) {
scriptRunner.logcatListener!!.lines.first { it.contains(str) }
}
return true
} catch (e: TimeoutCancellationException) {
return false
} finally {
job.cancel()
}
}

/**
* Searches the ADB logs for a certain regex string, returns false if the op times out or
* does not find the regex in the logs
*/
suspend fun waitForLog(
regex: Regex,
timeout: Long = Long.MAX_VALUE,
fn: suspend () -> Unit = {}
): Boolean {
val job = scriptRunner.sessionScope.launch {
delay(250)
while (coroutineContext.isActive) fn()
}
try {
withTimeout(timeout) {
scriptRunner.logcatListener!!.lines.first { regex.matchEntire(it) != null }
}
return true
} catch (e: TimeoutCancellationException) {
return false
} finally {
job.cancel()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ class ScriptRunner(

private val logger = loggerFor<ScriptRunner>()
private var _device: AndroidDevice? = null
private var logcatListener: GFL.LogcatListener? = null
var logcatListener: GFL.LogcatListener? = null
private set
private var _config = config
private var _profile = profile

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ import com.waicool20.wai2k.game.CombatMap
import com.waicool20.wai2k.game.Echelon
import com.waicool20.wai2k.game.GFL
import com.waicool20.wai2k.game.MapRunnerRegions
import com.waicool20.wai2k.game.location.LocationId
import com.waicool20.wai2k.script.ScriptComponent
import com.waicool20.wai2k.script.ScriptTimeOutException
import com.waicool20.wai2k.util.*
import kotlinx.coroutines.*
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import org.reflections.Reflections
import java.awt.Color
import java.awt.image.BufferedImage
Expand Down Expand Up @@ -539,36 +541,28 @@ abstract class MapRunner(
*/
protected suspend fun handleBattleResults() {
logger.info("Battle ended, clicking through battle results")
val location = if (this@MapRunner is EventMapRunner) {
if (this@MapRunner is EventMapRunner) {
logger.info("Waiting for event menu")
locations.getValue(LocationId.EVENT)
} else {
logger.info("Waiting for combat menu")
locations.getValue(LocationId.COMBAT_MENU)
}

try {
withTimeout(60000) {
while (!location.isInRegion(region)) {
repeat(Random.nextInt(2, 4)) {
mapRunnerRegions.battleEndClick.click()
delay(50)
}
endTurn()
}
waitForLog("MissionSelectionController:Start()") {
repeat(Random.nextInt(2, 4)) {
mapRunnerRegions.battleEndClick.click()
delay(50)
}
} catch (e: TimeoutCancellationException) {
throw ScriptTimeOutException("Waiting to exit battle", e)
} finally {
EventBus.publish(
SortieDoneEvent(
profile.combat.map,
if (this is CorpseDragging) profile.combat.draggers else emptyList(),
sessionId,
elapsedTime
)
)
delay(500)
}
delay(5000)
EventBus.publish(
SortieDoneEvent(
profile.combat.map,
if (this is CorpseDragging) profile.combat.draggers else emptyList(),
sessionId,
elapsedTime
)
)
}

protected suspend fun terminateMission(incrementSorties: Boolean = true) {
Expand Down Expand Up @@ -700,10 +694,10 @@ abstract class MapRunner(
}

private suspend fun endTurn() {
mapRunnerRegions.endBattle.clickWhile {
ocr.readText(this, threshold = 0.73).contains("end", true)
waitForLog("Dequeue:Mission/endTurn") {
mapRunnerRegions.endBattle.click()
delay(200)
}
region.waitHas(FT("ok.png"), 1000)?.click()
}

/**
Expand Down
Loading

0 comments on commit 76634e7

Please sign in to comment.