debug: fix strategy E/F to use eachBuffer instead of followPath, dump snap item bytes

This commit is contained in:
Majjo
2026-04-21 17:11:13 +02:00
parent 8f8c696431
commit 5651d48d96

View File

@@ -381,37 +381,48 @@ class CompanionServer : Feature("CompanionServer") {
}
}
}
// Strategy E: europe-west1 format — field3→3 → snap descriptors at field 1
// Strategy E: europe-west1 repeated-f3 format
// outer: repeated field3 (story group) → field3 (story list) → repeated field3 (snap items)
if (parsed == 0) {
var countE = 0
ProtoReader(buffer).followPath(3)?.followPath(3)?.eachBuffer(1) {
val userId = getString(4, 1) ?: getString(8, 1) ?: getString(1) ?: "public_unknown"
val url = getString(2, 2)?.substringBefore("?") ?: return@eachBuffer
val postedAt = getVarInt(3) ?: return@eachBuffer
val createdAt = getVarInt(27) ?: -1L
val keyB64 = getString(2, 5) ?: return@eachBuffer
val ivB64 = getString(2, 4) ?: return@eachBuffer
if (storeStory(userId, url, postedAt, createdAt, keyB64, ivB64)) countE++
ProtoReader(buffer).eachBuffer(3) { // story group
followPath(3) { // story list
eachBuffer(3) { // snap item
val url = getString(2, 2)?.substringBefore("?") ?: return@eachBuffer
val postedAt = getVarInt(3) ?: return@eachBuffer
val createdAt = getVarInt(27) ?: -1L
val keyB64 = getString(2, 5) ?: return@eachBuffer
val ivB64 = getString(2, 4) ?: return@eachBuffer
val userId = getString(4, 1) ?: getString(8, 1) ?: "public_unknown"
if (storeStory(userId, url, postedAt, createdAt, keyB64, ivB64)) countE++
}
}
}
if (countE > 0) parsed = countE
pushStoryDebug("probe", mapOf("endpoint" to endpoint, "strategy" to "E_f3f3f1", "found" to countE))
pushStoryDebug("probe", mapOf("endpoint" to endpoint, "strategy" to "E_f3f3→f3", "found" to countE))
}
// Strategy F: europe-west1 format — field3→3 → snap items at field 3
// Strategy F: snap item is one level deeper — f3→f3→f3→f1
if (parsed == 0) {
var countF = 0
ProtoReader(buffer).followPath(3)?.followPath(3)?.eachBuffer(3) {
val userId = getString(4, 1) ?: getString(8, 1) ?: "public_unknown"
val url = getString(2, 2)?.substringBefore("?") ?: return@eachBuffer
val postedAt = getVarInt(3) ?: return@eachBuffer
val createdAt = getVarInt(27) ?: -1L
val keyB64 = getString(2, 5) ?: return@eachBuffer
val ivB64 = getString(2, 4) ?: return@eachBuffer
if (storeStory(userId, url, postedAt, createdAt, keyB64, ivB64)) countF++
ProtoReader(buffer).eachBuffer(3) {
followPath(3) {
eachBuffer(3) {
eachBuffer(1) {
val url = getString(2, 2)?.substringBefore("?") ?: return@eachBuffer
val postedAt = getVarInt(3) ?: return@eachBuffer
val createdAt = getVarInt(27) ?: -1L
val keyB64 = getString(2, 5) ?: return@eachBuffer
val ivB64 = getString(2, 4) ?: return@eachBuffer
val userId = getString(4, 1) ?: getString(8, 1) ?: "public_unknown"
if (storeStory(userId, url, postedAt, createdAt, keyB64, ivB64)) countF++
}
}
}
}
if (countF > 0) parsed = countF
pushStoryDebug("probe", mapOf("endpoint" to endpoint, "strategy" to "F_f3f3f3", "found" to countF))
pushStoryDebug("probe", mapOf("endpoint" to endpoint, "strategy" to "F_f3f3f3→f1", "found" to countF))
}
// If still 0, dump hex + first snap descriptor bytes for structure analysis
// If still 0, dump the first snap item's raw bytes to see its actual field layout
if (parsed == 0 && buffer.size > 1000) {
val hexPreview = buffer.take(128).joinToString(" ") { "%02x".format(it) }
val debugMap = mutableMapOf<String, Any>(
@@ -420,14 +431,15 @@ class CompanionServer : Feature("CompanionServer") {
"bytes" to buffer.size
)
runCatching {
ProtoReader(buffer).followPath(3, 3)?.let { storyList ->
storyList.getByteArray(1)?.let { bytes ->
debugMap["f3f3f1_size"] = bytes.size
debugMap["f3f3f1_hex"] = bytes.take(256).joinToString(" ") { "%02x".format(it) }
}
storyList.getByteArray(3)?.let { bytes ->
debugMap["f3f3f3_size"] = bytes.size
debugMap["f3f3f3_hex"] = bytes.take(256).joinToString(" ") { "%02x".format(it) }
// Drill into first group → story list → first snap item and dump its bytes
ProtoReader(buffer).getByteArray(3)?.let { groupBytes ->
ProtoReader(groupBytes).getByteArray(3)?.let { listBytes ->
debugMap["story_list_size"] = listBytes.size
debugMap["story_list_hex"] = listBytes.take(256).joinToString(" ") { "%02x".format(it) }
ProtoReader(listBytes).getByteArray(3)?.let { snapBytes ->
debugMap["snap_item_size"] = snapBytes.size
debugMap["snap_item_hex"] = snapBytes.take(256).joinToString(" ") { "%02x".format(it) }
}
}
}
}
@@ -1072,7 +1084,7 @@ function addStoryDebugRow(e){
else if(t==='null_buffer')extra=' endpoint='+e.endpoint+' (null buffer!)';
else if(t==='parse_error')extra=' endpoint='+e.endpoint+' ERR: '+e.error;
else if(t==='probe')extra=' ['+e.endpoint+'] strategy='+e.strategy+' found='+e.found;
else if(t==='no_match')extra=' ['+e.endpoint+'] ALL STRATEGIES FAILED hex='+e.hex_preview;
else if(t==='no_match'){extra=' ['+e.endpoint+'] bytes='+e.bytes+' hex='+e.hex_preview;if(e.snap_item_hex)extra+=' | snap_item('+e.snap_item_size+'B)='+e.snap_item_hex;}
el.textContent='['+ts(e.ts||'0')+'] '+t.toUpperCase()+extra;
q('sd-log').appendChild(el);
}// ---- Shared ----