Skip to content

Commit

Permalink
fix bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
kukume committed Oct 29, 2024
1 parent 66a4fd2 commit 1d89ee2
Show file tree
Hide file tree
Showing 17 changed files with 570 additions and 338 deletions.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
19 changes: 12 additions & 7 deletions src/main/kotlin/me/kuku/telegram/entity/NetEaseEntity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,27 @@ import org.springframework.data.repository.kotlin.CoroutineCrudRepository
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

open class NetEaseBaseEntity: BaseEntity() {
var musicU: String = ""
var csrf: String = ""

fun cookie() = "channel=netease; __remember_me=true; MUSIC_U=$musicU; __csrf=$csrf; "

fun pcCookie() = "os=pc; ${cookie()}"

fun androidCookie() = "os=android; ${cookie()}"
}

@Document("net_ease")
class NetEaseEntity: BaseEntity() {
class NetEaseEntity: NetEaseBaseEntity() {
@Id
var id: String? = null
var musicU: String = ""
var csrf: String = ""
var sign: Status = Status.OFF
var musicianSign: Status = Status.OFF
var vipSign: Status = Status.OFF
var listen: Status = Status.OFF

fun cookie() = "channel=netease; __remember_me=true; MUSIC_U=$musicU; __csrf=$csrf; "

fun pcCookie() = "os=pc; ${cookie()}"

fun androidCookie() = "os=android; ${cookie()}"
}

interface NetEaseRepository: CoroutineCrudRepository<NetEaseEntity, String> {
Expand Down
14 changes: 10 additions & 4 deletions src/main/kotlin/me/kuku/telegram/entity/NetEaseSmallEntity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,25 @@ import org.springframework.data.annotation.Id
import org.springframework.data.mongodb.core.mapping.Document
import org.springframework.data.repository.kotlin.CoroutineCrudRepository
import org.springframework.stereotype.Service
import java.time.LocalDateTime
import java.time.temporal.ChronoUnit
import kotlin.math.absoluteValue

@Document("net_ease_small")
class NetEaseSmallEntity {
class NetEaseSmallEntity: NetEaseBaseEntity() {
@Id
var id: String? = null
var username: String = ""
var password: String = ""
var musicU: String = ""
var csrf: String = ""
var status: Status = Status.OFF
var reason: String = ""

fun cookie() = "channel=netease; __remember_me=true; MUSIC_U=$musicU; __csrf=$csrf; "
fun oneDayAgo() = ChronoUnit.DAYS.between(LocalDateTime.now(), super.updateTime).absoluteValue >= 1
}

interface NetEaseSmallRepository: CoroutineCrudRepository<NetEaseSmallEntity, String> {
suspend fun findByUsername(username: String): NetEaseSmallEntity?
suspend fun findByStatus(status: Status): List<NetEaseSmallEntity>
}

@Service
Expand All @@ -33,4 +37,6 @@ class NetEaseSmallService(
suspend fun findAll(): List<NetEaseSmallEntity> = netEaseSmallRepository.findAll().toList()

suspend fun delete(entity: NetEaseSmallEntity) = netEaseSmallRepository.delete(entity)

suspend fun findByStatus(status: Status) = netEaseSmallRepository.findByStatus(status)
}
24 changes: 19 additions & 5 deletions src/main/kotlin/me/kuku/telegram/logic/LeiShenLogic.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,33 @@ package me.kuku.telegram.logic

import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.node.ObjectNode
import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import me.kuku.telegram.entity.LeiShenEntity
import me.kuku.utils.*
import java.net.URLEncoder

object LeiShenLogic {

suspend fun login(phone: String, password: String): LeiShenEntity {
val jsonNode = client.post("https://webapi.leigod.com/wap/login/bind") {
setJsonBody("""
{"username":"$phone","password":"$password","user_type":"0","src_channel":"guanwang","code":"","country_code":86,"lang":"zh_CN"}
""".trimIndent())
}.body<JsonNode>()
val params = """
{"os_type":4,"password":"$password","mobile_num":"$phone","src_channel":"guanwang","country_code":86,"username":"$phone","lang":"zh_CN","region_code":1,"ts":"${System.currentTimeMillis() / 1000}"}
""".trimIndent().toJsonNode() as ObjectNode
val sortedFields = params.fields().asSequence()
.sortedBy { it.key } // 对字段进行排序
.map { entry ->
val key = URLEncoder.encode(entry.key, "UTF-8")
val value = URLEncoder.encode(entry.value.asText(), "UTF-8")
"$key=$value"
}
val convert = sortedFields.joinToString("&") + "&key=5C5A639C20665313622F51E93E3F2783"
val md5 = MD5Utils.toMD5(convert)
params.put("sign", md5)
val jsonNode = client.post("https://webapi.leigod.com/api/auth/login/v1") {
setJsonBody(params)
}.bodyAsText().toJsonNode()
if (jsonNode["code"].asInt() != 0) error(jsonNode["msg"].asText())
val data = jsonNode["data"]
val info = data["login_info"]
Expand Down
134 changes: 114 additions & 20 deletions src/main/kotlin/me/kuku/telegram/logic/NetEaseLogic.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ import kotlinx.coroutines.delay
import me.kuku.pojo.CommonResult
import me.kuku.pojo.UA
import me.kuku.telegram.config.api
import me.kuku.telegram.entity.NetEaseBaseEntity
import me.kuku.telegram.entity.NetEaseEntity
import me.kuku.telegram.entity.NetEaseSmallEntity
import me.kuku.utils.*
import okhttp3.internal.toHexString
import java.time.Duration
import kotlin.time.Duration.Companion.seconds

object NetEaseLogic {

Expand All @@ -37,14 +40,48 @@ object NetEaseLogic {
}
}

private fun prepare(json: String, netEaseEntity: NetEaseEntity? = null): Map<String, String> {
context(HttpRequestBuilder)
fun NetEaseBaseEntity?.encrypt(map: Map<String, String>) {
encrypt(Jackson.toJsonString(map))
}

context(HttpRequestBuilder)
fun NetEaseBaseEntity?.encrypt(json: String) {
val nonce = "0CoJUm6Qyw8W8jud"
val secretKey = "TA3YiYCfY2dDJQgg"
val encSecKey =
"84ca47bca10bad09a6b04c5c927ef077d9b9f1e37098aa3eac6ea70eb59df0aa28b691b7e75e4f1f9831754919ea784c8f74fbfadf2898b0be17849fd656060162857830e241aba44991601f137624094c114ea8d17bce815b0cd4e5b8e2fbaba978c6d1d14dc3d1faf852bdd28818031ccdaaa13a6018e1024e2aae98844210"
val jsonNode = json.toJsonNode()
this?.let {
(jsonNode as ObjectNode).put("csrf_token", it.csrf)
}
var param = aesEncode(jsonNode.toString(), nonce)
param = aesEncode(param, secretKey)
setFormDataContent {
append("params", param)
append("encSecKey", encSecKey)
}
io.ktor.http.headers {
userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36")
this@encrypt?.pcCookie()?.let {
cookieString(it)
}
referer("https://music.163.com")
origin("https://music.163.com")
}
}

private fun prepare(json: String, netEaseEntity: NetEaseEntity? = null, netEaseSmallEntity: NetEaseSmallEntity? = null): Map<String, String> {
val nonce = "0CoJUm6Qyw8W8jud"
val secretKey = "TA3YiYCfY2dDJQgg"
val encSecKey =
"84ca47bca10bad09a6b04c5c927ef077d9b9f1e37098aa3eac6ea70eb59df0aa28b691b7e75e4f1f9831754919ea784c8f74fbfadf2898b0be17849fd656060162857830e241aba44991601f137624094c114ea8d17bce815b0cd4e5b8e2fbaba978c6d1d14dc3d1faf852bdd28818031ccdaaa13a6018e1024e2aae98844210"
val jsonNode = json.toJsonNode()
netEaseEntity?.let {
(jsonNode as ObjectNode).put("csrf_token", netEaseEntity.csrf)
(jsonNode as ObjectNode).put("csrf_token", it.csrf)
}
netEaseSmallEntity?.let {
(jsonNode as ObjectNode).put("csrf_token", it.csrf)
}
var param = aesEncode(jsonNode.toString(), nonce)
param = aesEncode(param, secretKey)
Expand Down Expand Up @@ -170,24 +207,81 @@ object NetEaseLogic {
if (jsonNode.getInteger("code") != 200) error(jsonNode.getString("message"))
}

@Suppress("DuplicatedCode")
suspend fun listenMusic(netEaseSmallEntity: NetEaseSmallEntity, id: Int) {
val ids = Jackson.createArrayNode()
val jsonNode = Jackson.createObjectNode()
jsonNode.put("download", 0)
jsonNode.put("end", "playend")
jsonNode.put("id", id)
jsonNode.put("sourceId", "")
jsonNode.put("time", 240)
jsonNode.put("type", "song")
jsonNode.put("wifi", "0")
val totalJsonNode = Jackson.createObjectNode()
totalJsonNode.set<ObjectNode>("json", jsonNode)
totalJsonNode.put("action", "play")
ids.add(totalJsonNode)
val resultJsonNode = OkHttpKtUtils.postJson("$domain/weapi/feedback/weblog", prepare(mapOf("logs" to ids.toString())),
OkUtils.headers(netEaseSmallEntity.cookie(), domain, UA.PC))
if (resultJsonNode.getInteger("code") != 200) error(resultJsonNode.getString("message"))
suspend fun listenMusic0(netEaseSmallEntity: NetEaseSmallEntity, id: Long) {

// 歌曲详情请求
val songDetailResult = client.post("$domain/weapi/v3/song/detail") {
netEaseSmallEntity.encrypt("""
{"c": "[{\"id\": $id}]", "id": "$id"}
""".trimIndent())
}.body<JsonNode>()
songDetailResult.check()

// 歌词请求
val lyricResult = client.post("$domain/weapi/song/lyric") {
netEaseSmallEntity.encrypt("""
{"id":$id,"lv":-1,"tv":-1}
""".trimIndent())
}.body<JsonNode>()
lyricResult.check()

// 歌曲URL请求
val songUrlResult = client.post("$domain/weapi/song/enhance/player/url/v1") {
netEaseSmallEntity.encrypt(mapOf(
"ids" to "[$id]",
"level" to "standard",
"encodeType" to "aac"
))
}.body<JsonNode>()
songUrlResult.check()
val songUrl = songUrlResult["data"][0]["url"].asText()
val logUrl = "$domain/weapi/feedback/weblog"

client.get(songUrl).body<ByteArray>()

// 反馈日志请求
val log2 = client.post(logUrl) {
netEaseSmallEntity.encrypt(mapOf("logs" to """
[{"action":"play","json":{"id":"$id","type":"song","source":"search","sourceid":"kuku","mainsite":"1","content":"s=kuku&type=1"}}]
""".trimIndent()))
}.body<JsonNode>()
log2.check()

val log3 = client.post(logUrl) {
netEaseSmallEntity.encrypt(mapOf("logs" to """
[{"action":"play","json":{"type":"song","wifi":0,"download":0,"id":$id,"time":297,"end":"ui","source":"search","sourceId":"kuku","mainsite":"1","content":"s=kuku&type=1"}}]
""".trimIndent()))
}.body<JsonNode>()
log3.check()

val log1 = client.post(logUrl) {
netEaseSmallEntity.encrypt(mapOf("logs" to """
[{"action":"startplay","json":{"id":$id,"type":"song","content":"s=kuku&type=1","mainsite":"1"}}]
""".trimIndent()))
}.body<JsonNode>()
log1.check()

val log4 = client.post(logUrl) {
netEaseSmallEntity.encrypt(mapOf("logs" to """
[{"action":"mobile_monitor","json":{"meta._ver":2,"meta._dataName":"pip_lyric_monitor","action":"render","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36","chromeVersion":128,"resourceId":$id,"resourceType":"song","mainsite":"1"}}]
""".trimIndent()))
}.body<JsonNode>()
log4.check()

val log5 = client.post(logUrl) {
netEaseSmallEntity.encrypt(mapOf("logs" to """
[{"action":"sysaction","json":{"dataType":"cdnCompare","cdnType":"NetEase","loadeddataTime":15791,"resourceType":"audiom4a","resourceId":$id,"resourceUrl":"$songUrl","xySupport":true,"error":false,"errorType":"","ua":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36","mainsite":"1"}}]
""".trimIndent()))
}.body<JsonNode>()
log5.check()

}

suspend fun listenMusic(netEaseSmallEntity: NetEaseSmallEntity, id: Long) {
val jsonNode = client.get("http://192.168.1.177:8000/neteasemusic/listen?music_id=${id}&cookie=${netEaseSmallEntity.cookie().toUrlEncode()}")
.body<JsonNode>()
val sleep = jsonNode["sleep"].asLong() + 30
delay(sleep.seconds)
}

private suspend fun musicianStageMission(netEaseEntity: NetEaseEntity): MutableList<Mission> {
Expand Down
46 changes: 33 additions & 13 deletions src/main/kotlin/me/kuku/telegram/logic/NetEaseSmallLogic.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package me.kuku.telegram.logic

import com.fasterxml.jackson.databind.JsonNode
import io.ktor.client.call.*
import io.ktor.client.request.*
import kotlinx.coroutines.delay
import me.kuku.telegram.entity.NetEaseSmallService
import me.kuku.telegram.entity.Status
import me.kuku.utils.client
import org.springframework.stereotype.Service

@Service
Expand All @@ -12,27 +17,42 @@ class NetEaseSmallLogic(
suspend fun check() {
val list = netEaseSmallService.findAll()
for (netEaseSmallEntity in list) {
if (netEaseSmallEntity.csrf.isEmpty()) {
val loginResult = NetEaseLogic.login(netEaseSmallEntity.username, netEaseSmallEntity.password)
delay(2000)
if (loginResult.success()) {
val newEntity = loginResult.data()
netEaseSmallEntity.csrf = newEntity.csrf
netEaseSmallEntity.musicU = newEntity.musicU
if (netEaseSmallEntity.status == Status.ON && !netEaseSmallEntity.oneDayAgo()) continue
val loginResult = NetEaseLogic.login(netEaseSmallEntity.username, netEaseSmallEntity.password)
delay(2000)
if (loginResult.success()) {
val newEntity = loginResult.data()
netEaseSmallEntity.csrf = newEntity.csrf
netEaseSmallEntity.musicU = newEntity.musicU
netEaseSmallEntity.reason = ""
netEaseSmallEntity.status = Status.ON
netEaseSmallService.save(netEaseSmallEntity)
} else {
kotlin.runCatching {
val jsonNode = client.get("http://192.168.1.177:8000/neteasemusic/login?phone=${netEaseSmallEntity.username}&password=${netEaseSmallEntity.password}")
.body<JsonNode>()
val musicU = jsonNode["musicU"].asText()
val csrf = jsonNode["csrf"].asText()
netEaseSmallEntity.csrf = csrf
netEaseSmallEntity.musicU = musicU
netEaseSmallEntity.status = Status.ON
netEaseSmallEntity.reason = ""
netEaseSmallService.save(netEaseSmallEntity)
}.onFailure {
netEaseSmallEntity.status = Status.OFF
netEaseSmallEntity.reason = loginResult.message
netEaseSmallService.save(netEaseSmallEntity)
} else {
netEaseSmallService.delete(netEaseSmallEntity)
}

}
}
}

suspend fun listenMusic(id: Int) {
val list = netEaseSmallService.findAll()
suspend fun listenMusic(id: Long) {
val list = netEaseSmallService.findByStatus(Status.ON)
for (netEaseSmallEntity in list) {
if (netEaseSmallEntity.csrf.isNotEmpty()) {
NetEaseLogic.listenMusic(netEaseSmallEntity, id)
delay(2000)
NetEaseLogic.listenMusic0(netEaseSmallEntity, id)
}
}
}
Expand Down
Loading

0 comments on commit 1d89ee2

Please sign in to comment.