Skip to content

Commit

Permalink
Add local av bv id calculation logic (#22)
Browse files Browse the repository at this point in the history
* Update CodeExt.swift

* Update VideoCommentsView.swift

* Update CodeExt.swift

* Update status-check.yml

Updated checker with building logs shader

* Update status-check.yml

* Update status-check.yml

* Update status-check.yml

* Update CodeExt.swift

* Update CodeExt.swift

Updated for new ver logic

* Update CodeExt.swift

* Update VideoCommentsView.swift

* Update VideoCommentsView.swift

* Update VideoCommentsView.swift

* Update CodeExt.swift

* Update CodeExt.swift
  • Loading branch information
WindowsMEMZ committed Oct 12, 2024
1 parent 47a8c59 commit 41b505a
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 69 deletions.
53 changes: 53 additions & 0 deletions DarockBili Watch App/Extension/CodeExt.swift
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,59 @@ func biliWbiSign(paramEncoded: String, completion: @escaping (String?) -> Void)
}
}

// AV & BV ID Convert Logic
fileprivate let XOR_CODE: UInt64 = 23442827791579
fileprivate let MASK_CODE: UInt64 = 2251799813685247
fileprivate let MAX_AID: UInt64 = 1 << 51

fileprivate let data: [UInt8] = [70, 99, 119, 65, 80, 78, 75, 84, 77, 117, 103, 51, 71, 86, 53, 76, 106, 55, 69, 74, 110, 72, 112, 87, 115, 120, 52, 116, 98, 56, 104, 97, 89, 101, 118, 105, 113, 66, 122, 54, 114, 107, 67, 121, 49, 50, 109, 85, 83, 68, 81, 88, 57, 82, 100, 111, 90, 102]

fileprivate let BASE: UInt64 = 58
fileprivate let BV_LEN: Int = 12
fileprivate let PREFIX: String = "BV1"

func av2bv(avid: UInt64) -> String {
var bytes: [UInt8] = [66, 86, 49, 48, 48, 48, 48, 48, 48, 48, 48, 48]
var bvIdx = BV_LEN - 1
var tmp = (MAX_AID | avid) ^ XOR_CODE

while tmp != 0 {
bytes[bvIdx] = data[Int(tmp % BASE)]
tmp /= BASE
bvIdx -= 1
}

bytes.swapAt(3, 9)
bytes.swapAt(4, 7)

return String(decoding: bytes, as: UTF8.self)
}

func bv2av(bvid: String) -> UInt64 {
let fixedBvid: String
if bvid.hasPrefix("BV") {
fixedBvid = bvid
} else {
fixedBvid = "BV" + bvid
}
var bvidArray = Array(fixedBvid.utf8)

bvidArray.swapAt(3, 9)
bvidArray.swapAt(4, 7)

let trimmedBvid = String(decoding: bvidArray[3...], as: UTF8.self)

var tmp: UInt64 = 0

for char in trimmedBvid {
if let idx = data.firstIndex(of: char.utf8.first!) {
tmp = tmp * BASE + UInt64(idx)
}
}

return (tmp & MASK_CODE) ^ XOR_CODE
}

postfix operator ++
postfix operator --
prefix operator ++
Expand Down
128 changes: 59 additions & 69 deletions DarockBili Watch App/Video/VideoCommentsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct VideoCommentsView: View {
@AppStorage("DedeUserID__ckMd5") var dedeUserID__ckMd5 = ""
@AppStorage("SESSDATA") var sessdata = ""
@AppStorage("bili_jct") var biliJct = ""
@State var avid = -1
@State var avid: UInt64 = 0
@State var comments = [[String: String]]()
@State var sepTexts = [[String]]()
@State var emojiUrls = [[String]]()
Expand Down Expand Up @@ -231,74 +231,68 @@ struct VideoCommentsView: View {
}

func ContinueLoadComment() {
DarockKit.Network.shared.requestString("https://api.darock.top/bili/toav/\(oid)") { respStr, isSuccess in
avid = bv2av(bvid: oid)
debugPrint(avid)
let headers: HTTPHeaders = [
"cookie": "SESSDATA=\(sessdata);"
]
DarockKit.Network.shared.requestJSON("https://api.bilibili.com/x/v2/reply?type=1&oid=\(avid)&sort=1&ps=20&pn=\(nowPage)", headers: headers) { respJson, isSuccess in
if isSuccess {
avid = Int(respStr)!
debugPrint(avid)
let headers: HTTPHeaders = [
"cookie": "SESSDATA=\(sessdata);"
]
DarockKit.Network.shared.requestJSON("https://api.bilibili.com/x/v2/reply?type=1&oid=\(avid)&sort=1&ps=20&pn=\(nowPage)", headers: headers) { respJson, isSuccess in
if isSuccess {
debugPrint(respJson)
let replies = respJson["data"]["replies"]
var calNum = 0
for reply in replies {
isSenderDetailsPresented.append(false)
commentOffsets.append(20)
let repliesInComment = reply.1["replies"]
commentReplies.append([])
for sigReply in repliesInComment {
commentReplies[calNum].append(["Text": sigReply.1["content"]["message"].string ?? "[加载失败]", "Sender": sigReply.1["member"]["uname"].string ?? "[加载失败]", "SenderPic": sigReply.1["member"]["avatar"].string ?? "E", "SenderID": sigReply.1["member"]["mid"].string ?? "E", "IP": sigReply.1["reply_control"]["location"].string ?? "", "UserAction": String(sigReply.1["action"].int ?? 0), "Rpid": String(sigReply.1["rpid"].int ?? -1), "Like": String(sigReply.1["like"].int ?? -1)])
}
let text = reply.1["content"]["message"].string ?? "[加载失败]"
comments.append(["Text": text, "Sender": reply.1["member"]["uname"].string ?? "[加载失败]", "SenderPic": reply.1["member"]["avatar"].string ?? "E", "SenderID": reply.1["member"]["mid"].string ?? "E", "IP": reply.1["reply_control"]["location"].string ?? "", "UserAction": String(reply.1["action"].int ?? 0), "Rpid": String(reply.1["rpid"].int ?? -1), "Like": String(reply.1["like"].int ?? -1)])
// sepTexts.append([])
// isEmoted.append(false)
// // 文本中包含表情
// if text.range(of: "\\[(.*?)\\]", options: .regularExpression) != nil {
// let regex = try! NSRegularExpression(pattern: "\\[(.*?)\\]")
// debugPrint("Contains")
// // 分割文本,同时去除表情
// let tmpSpdText = regex.stringByReplacingMatches(in: text, range: NSRange(text.startIndex..<text.endIndex, in: text), withTemplate: "|").split(separator: "|").map {
// String($0)
// }
// debugPrint(tmpSpdText)
// for text in tmpSpdText {
// sepTexts[calNum].append(String(text))
// }
// // 正则获取表情
// let emojis = regex.matches(in: text, range: NSRange(text.startIndex..., in: text)).map {
// String(text[Range($0.range, in: text)!])
// }
// let jEmotes = reply.1["content"]["emote"]
// debugPrint(jEmotes)
// // 获取表情对应URL
// emojiUrls.append([])
// for emoji in emojis {
// if let sigEUrl = jEmotes[emoji].string {
// emojiUrls[calNum].append(sigEUrl)
// }
// }
// isEmoted[calNum] = true
// debugPrint(emojiUrls)
// } else {
//
// }
calNum += 1
}
} else {
Logger().error("There is a error when request comments from Bilibili server")
debugPrint(respJson)
let replies = respJson["data"]["replies"]
var calNum = 0
for reply in replies {
isSenderDetailsPresented.append(false)
commentOffsets.append(20)
let repliesInComment = reply.1["replies"]
commentReplies.append([])
for sigReply in repliesInComment {
commentReplies[calNum].append(["Text": sigReply.1["content"]["message"].string ?? "[加载失败]", "Sender": sigReply.1["member"]["uname"].string ?? "[加载失败]", "SenderPic": sigReply.1["member"]["avatar"].string ?? "E", "SenderID": sigReply.1["member"]["mid"].string ?? "E", "IP": sigReply.1["reply_control"]["location"].string ?? "", "UserAction": String(sigReply.1["action"].int ?? 0), "Rpid": String(sigReply.1["rpid"].int ?? -1), "Like": String(sigReply.1["like"].int ?? -1)])
}
let text = reply.1["content"]["message"].string ?? "[加载失败]"
comments.append(["Text": text, "Sender": reply.1["member"]["uname"].string ?? "[加载失败]", "SenderPic": reply.1["member"]["avatar"].string ?? "E", "SenderID": reply.1["member"]["mid"].string ?? "E", "IP": reply.1["reply_control"]["location"].string ?? "", "UserAction": String(reply.1["action"].int ?? 0), "Rpid": String(reply.1["rpid"].int ?? -1), "Like": String(reply.1["like"].int ?? -1)])
// sepTexts.append([])
// isEmoted.append(false)
// // 文本中包含表情
// if text.range(of: "\\[(.*?)\\]", options: .regularExpression) != nil {
// let regex = try! NSRegularExpression(pattern: "\\[(.*?)\\]")
// debugPrint("Contains")
// // 分割文本,同时去除表情
// let tmpSpdText = regex.stringByReplacingMatches(in: text, range: NSRange(text.startIndex..<text.endIndex, in: text), withTemplate: "|").split(separator: "|").map {
// String($0)
// }
// debugPrint(tmpSpdText)
// for text in tmpSpdText {
// sepTexts[calNum].append(String(text))
// }
// // 正则获取表情
// let emojis = regex.matches(in: text, range: NSRange(text.startIndex..., in: text)).map {
// String(text[Range($0.range, in: text)!])
// }
// let jEmotes = reply.1["content"]["emote"]
// debugPrint(jEmotes)
// // 获取表情对应URL
// emojiUrls.append([])
// for emoji in emojis {
// if let sigEUrl = jEmotes[emoji].string {
// emojiUrls[calNum].append(sigEUrl)
// }
// }
// isEmoted[calNum] = true
// debugPrint(emojiUrls)
// } else {
//
// }
calNum += 1
}
} else {
Logger().error("There is a error when request avid from Darock server")
Logger().error("There is an error when request comments from Bilibili server")
}
}
}

struct CommentRepliesView: View {
var avid: Int
var avid: UInt64
@State var replies: [[String: String]]
var goto: String? = nil
@AppStorage("DedeUserID") var dedeUserID = ""
Expand Down Expand Up @@ -430,7 +424,7 @@ struct VideoCommentsView: View {
@AppStorage("bili_jct") var biliJct = ""
@State var sendCommentCache = ""
@State var isSendingComment = false
@State var avid = -1
@State var avid: UInt64 = 0
var body: some View {
VStack {
if !isSendingComment {
Expand All @@ -454,28 +448,24 @@ struct VideoCommentsView: View {
}
}
.onAppear {
DarockKit.Network.shared.requestString("https://api.darock.top/bili/toav/\(oid)") { respStr, isSuccess in
if isSuccess {
avid = Int(respStr)!
debugPrint(avid)
}
}
avid = bv2av(bvid: oid)
debugPrint(avid)
}
}
}
}

struct BiliCommentLike: Codable {
var type: Int = 1
let oid: Int
let oid: UInt64
let rpid: Int
let action: Int
let csrf: String
}

struct BiliSubmitComment: Codable {
var type: Int = 1
let oid: Int
let oid: UInt64
var root: Int? = nil
var parent: Int? = nil
let message: String
Expand Down

0 comments on commit 41b505a

Please sign in to comment.