Skip to content

Commit bc608b2

Browse files
Add support for reconnecting when restarting SwiftSplit
1 parent 3e2d80b commit bc608b2

File tree

3 files changed

+44
-9
lines changed

3 files changed

+44
-9
lines changed

SwiftSplit/CelesteScanner.swift

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,39 @@ import Foundation
1414
class CelesteScanner {
1515
var enableDebugPrinting: Bool = false
1616

17-
var header: UInt64 = 0
17+
var pid: pid_t
18+
var headerInfo: HeaderInfo? = nil {
19+
didSet {
20+
if let info = headerInfo {
21+
self.headerSignature = MemscanSignature(from: info.signatureData)
22+
} else {
23+
self.headerSignature = nil
24+
}
25+
}
26+
}
1827
var headerSignature: MemscanSignature? = nil
1928
var pointer: vm_address_t = 0
2029
let target: MemscanTarget
2130
let filter: MemscanFilter
2231

2332
init(pid: pid_t) throws {
33+
self.pid = pid
2434
target = try MemscanTarget(pid: pid)
2535
filter = MemscanFilter(startAddress: 0, endAddress: 0x0000700000000000)
2636
}
2737

2838
func findHeader() throws {
2939
print("Scanning for the AutoSplitterData object header")
40+
41+
if let data = UserDefaults.standard.value(forKey: "lastHeader") as? Data,
42+
let lastHeader = try? PropertyListDecoder().decode(HeaderInfo.self, from: data) {
43+
if lastHeader.pid == pid {
44+
print("Found existing header for pid \(pid)")
45+
headerInfo = lastHeader
46+
return
47+
}
48+
}
49+
3050
let bigboisignature = MemscanSignature(parsing:
3151
"7f00000000000000000000????????????????ffffffffffffffff000000000000000000000" +
3252
"000000000000000000000000000000000000000000000000000000000000000000000000000"
@@ -36,8 +56,9 @@ class CelesteScanner {
3656
let address = match.address - 5
3757
print(String(format: " Found a candiate object at %016llx", address))
3858
let data = try target.read(at: address, count: 16)
39-
headerSignature = MemscanSignature(from: data.buffer)
40-
header = try readData(at: address).header
59+
let info = HeaderInfo(pid: pid, signatureData: Array(data.buffer.bindMemory(to: UInt8.self)), header: try readData(at: address).header)
60+
headerInfo = info
61+
UserDefaults.standard.set(try? PropertyListEncoder().encode(info), forKey: "lastHeader")
4162
return
4263
}
4364
}
@@ -62,14 +83,17 @@ class CelesteScanner {
6283
if let match = try scanner.next() {
6384
self.pointer = match.address
6485
print(String(format: " Found the instance at %llx", match.address))
86+
} else {
87+
pointer = 0
6588
}
6689
}
6790

6891
func getInfo() throws -> AutoSplitterInfo? {
6992
if pointer == 0 { try findData() }
7093
if pointer == 0 { return nil }
94+
guard let headerInfo = self.headerInfo else { return nil }
7195
var data = try readData(at: pointer)
72-
if data.header != self.header || data.headerPad != 0 {
96+
if data.header != headerInfo.header || data.headerPad != 0 {
7397
try findData()
7498
if pointer == 0 { return nil }
7599
data = try readData(at: pointer)
@@ -141,6 +165,18 @@ class CelesteScanner {
141165
}
142166
}
143167

168+
struct HeaderInfo: Codable {
169+
var pid: pid_t
170+
var signatureData: [UInt8]
171+
var header: UInt64
172+
173+
init(pid: pid_t, signatureData: [UInt8], header: UInt64) {
174+
self.pid = pid
175+
self.signatureData = signatureData
176+
self.header = header
177+
}
178+
}
179+
144180
/**
145181
A representation of the C# AutoSplitterInfo memory.
146182

SwiftSplit/CelesteSplitter.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class CelesteSplitter {
2929
self.server = server
3030
self.server.pauseGameTime() // make sure gameTimeRunning is accurate
3131
try scanner.findHeader()
32-
if scanner.headerSignature == nil {
32+
if scanner.headerInfo == nil {
3333
throw SplitterError.noHeader
3434
}
3535
}

SwiftSplit/ViewController.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class ViewController: NSViewController, RouteBoxDelegate {
3131

3232
// we will ignore the celeste instance that was open when we first launched (if any). We don't know if they're in a clean state.
3333
// we also ignore the pid once it has been connected to. this prevents attempting to reconnect immediately after the game closes and we disconnect
34-
var ignorePid: pid_t?
34+
var ignorePid: pid_t? = nil
3535

3636
var hasRouteConfig = false
3737
var routeConfig = RouteConfig() {
@@ -49,7 +49,6 @@ class ViewController: NSViewController, RouteBoxDelegate {
4949
super.viewDidLoad()
5050

5151
self.eventStream = Array(repeating: "", count: eventStreamLength)
52-
self.ignorePid = findCelestePid()
5352

5453
timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
5554
self.update()
@@ -123,7 +122,7 @@ class ViewController: NSViewController, RouteBoxDelegate {
123122
let pid = apps[0].processIdentifier
124123

125124
if pid == ignorePid {
126-
return nil // this celeste process was open when we launched, so we don't know that it's in a clean state.
125+
return nil // we ran into an error connecting to this pid
127126
}
128127

129128
return pid
@@ -138,8 +137,8 @@ class ViewController: NSViewController, RouteBoxDelegate {
138137
self.splitter = try CelesteSplitter(pid: pid, server: server)
139138
self.splitter?.routeConfig = routeConfig
140139
connectionStatusLabel.stringValue = "Connected"
141-
self.ignorePid = pid
142140
} catch {
141+
self.ignorePid = pid
143142
print("Error creating splitter: \(error)")
144143
}
145144
}

0 commit comments

Comments
 (0)