Skip to content

Commit 8cb6e8d

Browse files
Add more Everest extended data
1 parent 2b73f8e commit 8cb6e8d

File tree

3 files changed

+76
-92
lines changed

3 files changed

+76
-92
lines changed

SwiftSplit/CelesteScanner.swift

Lines changed: 41 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,12 @@ class CelesteScanner {
4040
print("Scanning for the AutoSplitterData object header")
4141

4242
extendedInfo = try process.findPointer(by: "11efbeadde11")
43+
if let info = extendedInfo {
44+
try Mono.debugMemory(around: info, before: 64, after: 64)
45+
}
4346

4447
if CelesteScanner.canImmediatelyConnect(pid: pid) {
4548
headerInfo = CelesteScanner.lastHeader
46-
try? debugPointers()
4749
return
4850
}
4951

@@ -58,12 +60,10 @@ class CelesteScanner {
5860
}
5961

6062
func readExtended() throws -> ExtendedAutoSplitterData? {
61-
// if guard let extendedInfo = extendedInfo else {
62-
// return nil
63-
// }
64-
// let buf = try target.read(at: extendedPointer, count: )
65-
// return ExtendedAutoSplitterData(from: extendedInfo)
66-
return nil
63+
guard let extendedInfo = extendedInfo else {
64+
return nil
65+
}
66+
return try ExtendedAutoSplitterData(from: extendedInfo)
6767
}
6868

6969
func getInfo() throws -> AutoSplitterInfo? {
@@ -75,50 +75,6 @@ class CelesteScanner {
7575
return try AutoSplitterInfo(from: try AutoSplitterData(from: info))
7676
}
7777

78-
/**
79-
Run a scan for the level strings, printing the memory of every match. Useful for figuring out the memory layout
80-
*/
81-
func debugPointers() throws {
82-
83-
// print("Running a pointer debug")
84-
// guard let signature = headerSignature else {
85-
// print(" There is no header signature. Please open the AUTOSPLIT save and scan for the header.")
86-
// pointer = 0
87-
// return
88-
// }
89-
//
90-
// let scanner = MemscanScanner(target: target, signature: signature, filter: filter)
91-
// while let match = try scanner.next() {
92-
// print(String(format: "Object @ %016llx", match.address))
93-
//
94-
// let vTable_ptr = try readPointer(from: match.address, offset: 0)
95-
// print(String(format: "VTable @ %016llx", vTable_ptr))
96-
//
97-
//// try debugMemoryAround(vTable_ptr, before: 0, after: 64)
98-
//
99-
// let monoClass_ptr = try readPointer(from: vTable_ptr, offset: 0)
100-
// print(String(format: "MonoClass @ %016llx", monoClass_ptr))
101-
//
102-
//// try debugMemoryAround(monoClass_ptr, before: 0, after: 64)
103-
//
104-
// let name_ptr = try readPointer(from: monoClass_ptr, offset: 8)
105-
// print(String(format: "MonoClass.name @ %016llx", name_ptr))
106-
// try debugMemoryAround(name_ptr, before: 0, after: 128)
107-
//
108-
// }
109-
}
110-
111-
func readPointer(from address: vm_address_t, offset: vm_offset_t) throws -> vm_address_t {
112-
let data = try target.read(at: address + offset, count: 8)
113-
return data.buffer.bindMemory(to: vm_address_t.self)[0]
114-
}
115-
116-
func debugMemoryAround(_ address: vm_address_t, before: vm_offset_t, after: vm_offset_t) throws {
117-
let data = try target.read(at: address - before, count: before + after)
118-
print(" Forward: \(data.debugString(withCursor: Int(before)))")
119-
print(" Reversed: \(data.debugStringReversed(withCursor: Int(before)))")
120-
}
121-
12278
static var lastHeader: HeaderInfo? {
12379
get {
12480
if let data = UserDefaults.standard.value(forKey: "lastHeader") as? Data,
@@ -188,9 +144,6 @@ struct HeaderInfo: Codable {
188144
```
189145
*/
190146
struct AutoSplitterData {
191-
var header: UInt64
192-
var monoSync: UInt64
193-
194147
var chapter: Int32
195148
var mode: Int32
196149
var level: RmaPointer
@@ -207,23 +160,21 @@ struct AutoSplitterData {
207160
var fileHearts: Int32
208161

209162
init(from pointer: RmaPointer) throws {
210-
let preload = try pointer.preload(size: 80)
211-
header = preload.value(at: 0)
212-
monoSync = preload.value(at: 8)
213-
level = preload.value(at: 16)
214-
chapter = preload.value(at: 24)
215-
mode = preload.value(at: 28)
216-
timerActive = preload.value(at: 32)
217-
chapterStarted = preload.value(at: 33)
218-
chapterComplete = preload.value(at: 34)
219-
chapterTime = preload.value(at: 40)
220-
chapterStrawberries = preload.value(at: 48)
221-
chapterCassette = preload.value(at: 52)
222-
chapterHeart = preload.value(at: 53)
223-
fileTime = preload.value(at: 56)
224-
fileStrawberries = preload.value(at: 64)
225-
fileCassettes = preload.value(at: 68)
226-
fileHearts = preload.value(at: 72)
163+
let body = try pointer.offset(by: Mono.HEADER_BYTES).preload(size: 60)
164+
level = body.value(at: 0)
165+
chapter = body.value(at: 8)
166+
mode = body.value(at: 12)
167+
timerActive = body.value(at: 16)
168+
chapterStarted = body.value(at: 17)
169+
chapterComplete = body.value(at: 18)
170+
chapterTime = body.value(at: 24)
171+
chapterStrawberries = body.value(at: 32)
172+
chapterCassette = body.value(at: 36)
173+
chapterHeart = body.value(at: 37)
174+
fileTime = body.value(at: 40)
175+
fileStrawberries = body.value(at: 48)
176+
fileCassettes = body.value(at: 52)
177+
fileHearts = body.value(at: 56)
227178
}
228179
}
229180

@@ -285,7 +236,7 @@ class AutoSplitterInfo {
285236
default:
286237
self.mode = .Other(value: Int(data.mode))
287238
}
288-
self.level = try Mono.readString(at: data.level)
239+
self.level = try Mono.readString(at: data.level) ?? ""
289240
self.timerActive = data.timerActive != 0
290241
self.chapterStarted = data.chapterStarted != 0
291242
self.chapterComplete = data.chapterComplete != 0
@@ -301,14 +252,26 @@ class AutoSplitterInfo {
301252
}
302253

303254
struct ExtendedAutoSplitterData {
304-
var madelineX: Float = 0.0
305-
var madelineY: Float = 0.0
306-
307-
init() {}
255+
var madelineX: Float
256+
var madelineY: Float
257+
var fileDeaths: Int32
258+
var levelDeaths: Int32
259+
var areaName: String
260+
var areaSID: String
261+
var levelSet: String
262+
var completeScreenName: String
308263

309264
init(from pointer: RmaPointer) throws {
310-
madelineX = try pointer.value(at: 0)
311-
madelineY = try pointer.value(at: 4)
265+
// offset to skip the `11deadbeef11`
266+
let body = try pointer.offset(by: 8).preload(size: 48)
267+
madelineX = body.value(at: 0)
268+
madelineY = body.value(at: 4)
269+
fileDeaths = body.value(at: 8)
270+
levelDeaths = body.value(at: 12)
271+
areaName = try Mono.readString(at: body.value(at: 16)) ?? ""
272+
areaSID = try Mono.readString(at: body.value(at: 24)) ?? ""
273+
levelSet = try Mono.readString(at: body.value(at: 32)) ?? ""
274+
completeScreenName = try Mono.readString(at: body.value(at: 40)) ?? ""
312275
}
313276
}
314277

SwiftSplit/Core/Mono.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import Foundation
1111
final class Mono {
1212
private init() {}
1313

14+
static let HEADER_BYTES: Int = 16
15+
1416
/**
1517
Parse a C# string object
1618

@@ -24,9 +26,19 @@ final class Mono {
2426
0 8 16 20
2527
```
2628
*/
27-
static func readString(at pointer: RmaPointer) throws -> String {
29+
static func readString(at pointer: RmaPointer) throws -> String? {
30+
if pointer.address == 0 {
31+
return nil
32+
}
2833
let length: Int32 = try pointer.value(at: 16)
2934
let stringData = try pointer.raw(at: 20, count: vm_offset_t(length) * 2)
3035
return String(utf16CodeUnits: stringData.buffer.bindMemory(to: unichar.self).baseAddress!, count: Int(length))
3136
}
37+
38+
static func debugMemory(around pointer: RmaPointer, before: vm_offset_t, after: vm_offset_t) throws {
39+
let data = try pointer.raw(at: -Int(before), count: before + after)
40+
print(" Forward: \(data.debugString(withCursor: Int(before)))")
41+
print(" Reversed: \(data.debugStringReversed(withCursor: Int(before)))")
42+
}
43+
3244
}

SwiftSplit/ViewController.swift

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -205,20 +205,29 @@ class ViewController: NSViewController, RouteBoxDelegate {
205205
Cassettes: \(info.fileCassettes)
206206
Hearts: \(info.fileHearts)
207207
"""
208-
let extended = try? self.splitter?.scanner.readExtended()
209-
if let extended = extended {
210-
var address = "none"
211-
if let p = self.splitter?.scanner.extendedInfo?.address {
212-
address = String(format: "%llx", p)
208+
do {
209+
let extended = try self.splitter?.scanner.readExtended()
210+
if let extended = extended {
211+
var address = "none"
212+
if let p = self.splitter?.scanner.extendedInfo?.address {
213+
address = String(format: "%llx", p)
214+
}
215+
dataText += """
216+
217+
Extended:
218+
Address: \(address)
219+
Madeline X: \(extended.madelineX)
220+
Madeline Y: \(extended.madelineY)
221+
File Deaths: \(extended.fileDeaths)
222+
Level Deaths: \(extended.levelDeaths)
223+
Area Name: \(extended.areaName)
224+
Area SID: \(extended.areaSID)
225+
Level Set: \(extended.levelSet)
226+
"""
227+
213228
}
214-
dataText += """
215-
216-
Extended:
217-
Address: \(address)
218-
Madeline X: \(extended.madelineX)
219-
Madeline Y: \(extended.madelineY)
220-
"""
221-
229+
} catch {
230+
print(error)
222231
}
223232
celesteDataLabel.stringValue = dataText
224233
} else {

0 commit comments

Comments
 (0)