mirror of
https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced.git
synced 2026-03-21 11:03:15 +00:00
Merge branch 'main' into 'main'
refactor: Refactor random Chinese IP generator
This commit is contained in:
commit
2047bdfa65
@ -7,9 +7,9 @@
|
|||||||
!/app.js
|
!/app.js
|
||||||
!/server.js
|
!/server.js
|
||||||
!/package.json
|
!/package.json
|
||||||
!/package-lock.json
|
|
||||||
!/index.js
|
!/index.js
|
||||||
!/generateConfig.js
|
!/generateConfig.js
|
||||||
!/main.js
|
!/main.js
|
||||||
!/data
|
!/data
|
||||||
!/.env
|
!/.env
|
||||||
|
!/pnpm-lock.yaml
|
||||||
2
.github/dependabot.yml
vendored
2
.github/dependabot.yml
vendored
@ -16,7 +16,7 @@ updates:
|
|||||||
# 自动合并小版本更新的 PR (可选)
|
# 自动合并小版本更新的 PR (可选)
|
||||||
# 可以设置针对 patch 或 minor 版本更新自动合并
|
# 可以设置针对 patch 或 minor 版本更新自动合并
|
||||||
commit-message:
|
commit-message:
|
||||||
prefix: "chore(packages):" # PR 合并提交信息的前缀
|
prefix: "build(packages):" # PR 合并提交信息的前缀
|
||||||
|
|
||||||
# 更新 GitHub Actions 依赖
|
# 更新 GitHub Actions 依赖
|
||||||
- package-ecosystem: "github-actions"
|
- package-ecosystem: "github-actions"
|
||||||
|
|||||||
@ -1,26 +0,0 @@
|
|||||||
开始IP,结束IP,IP个数,位置
|
|
||||||
1.0.1.0 ,1.0.3.255 ,768,福州
|
|
||||||
1.0.8.0 ,1.0.15.255 ,2048,广州
|
|
||||||
1.0.32.0 ,1.0.63.255 ,8192,广州
|
|
||||||
1.1.0.0 ,1.1.0.255 ,256,福州
|
|
||||||
1.1.2.0 ,1.1.63.255 ,15872,广州
|
|
||||||
1.2.0.0 ,1.2.2.255 ,768,北京
|
|
||||||
1.2.4.0 ,1.2.127.255 ,31744,广州
|
|
||||||
1.3.0.0 ,1.3.255.255 ,65536,广州
|
|
||||||
1.4.1.0 ,1.4.127.255 ,32512,广州
|
|
||||||
1.8.0.0 ,1.8.255.255 ,65536,北京
|
|
||||||
1.10.0.0 ,1.10.9.255 ,2560,福州
|
|
||||||
1.10.11.0 ,1.10.127.255 ,29952,广州
|
|
||||||
1.12.0.0 ,1.15.255.255 ,262144,上海
|
|
||||||
1.18.128.0 ,1.18.128.255 ,256,北京
|
|
||||||
1.24.0.0 ,1.31.255.255 ,524288,赤峰
|
|
||||||
1.45.0.0 ,1.45.255.255 ,65536,北京
|
|
||||||
1.48.0.0 ,1.51.255.255 ,262144,济南
|
|
||||||
1.56.0.0 ,1.63.255.255 ,524288,伊春
|
|
||||||
1.68.0.0 ,1.71.255.255 ,262144,忻州
|
|
||||||
1.80.0.0 ,1.95.255.255 ,1048576,北京
|
|
||||||
1.116.0.0 ,1.117.255.255 ,131072,上海
|
|
||||||
1.119.0.0 ,1.119.255.255 ,65536,北京
|
|
||||||
1.180.0.0 ,1.185.255.255 ,393216,桂林
|
|
||||||
1.188.0.0 ,1.199.255.255 ,786432,洛阳
|
|
||||||
1.202.0.0 ,1.207.255.255 ,393216,铜仁
|
|
||||||
|
4147
data/china_ip_ranges.txt
Normal file
4147
data/china_ip_ranges.txt
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
网易云音乐 NodeJS API Enhanced
|
网易云音乐 NodeJS API Enhanced
|
||||||
|
|
||||||
|
最后更新于: 2026.2.15
|
||||||
|
|
||||||
## 灵感来自
|
## 灵感来自
|
||||||
|
|
||||||
[disoul/electron-cloud-music](https://github.com/disoul/electron-cloud-music)
|
[disoul/electron-cloud-music](https://github.com/disoul/electron-cloud-music)
|
||||||
|
|||||||
27
server.js
27
server.js
@ -227,20 +227,23 @@ async function consturctServer(moduleDefs) {
|
|||||||
const moduleResponse = await moduleDef.module(query, (...params) => {
|
const moduleResponse = await moduleDef.module(query, (...params) => {
|
||||||
// 参数注入客户端IP
|
// 参数注入客户端IP
|
||||||
const obj = [...params]
|
const obj = [...params]
|
||||||
// 获取请求中的 IP 参数
|
const options = obj[2] || {}
|
||||||
let ip = req.ip
|
if (!options.randomCNIP) {
|
||||||
|
let ip = req.ip
|
||||||
|
|
||||||
if (ip.substring(0, 7) == '::ffff:') {
|
if (ip.substring(0, 7) == '::ffff:') {
|
||||||
ip = ip.substring(7)
|
ip = ip.substring(7)
|
||||||
}
|
}
|
||||||
if (ip == '::1') {
|
if (ip == '::1') {
|
||||||
ip = global.cnIp
|
ip = global.cnIp
|
||||||
}
|
}
|
||||||
// logger.info('Requested from ip:', ip)
|
// logger.info('Requested from ip:', ip)
|
||||||
obj[2] = {
|
obj[2] = {
|
||||||
...(obj[2] || {}),
|
...options,
|
||||||
ip,
|
ip,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return request(...obj)
|
return request(...obj)
|
||||||
})
|
})
|
||||||
logger.info(`Request Success: ${decode(req.originalUrl)}`)
|
logger.info(`Request Success: ${decode(req.originalUrl)}`)
|
||||||
|
|||||||
105
util/index.js
105
util/index.js
@ -1,36 +1,8 @@
|
|||||||
const logger = require('./logger')
|
const logger = require('./logger')
|
||||||
// 预先定义常量和函数引用
|
const fs = require('fs')
|
||||||
// 中国 IP 段(来源:data/ChineseIPGenerate.csv)
|
const path = require('path')
|
||||||
const chinaIPRangesRaw = [
|
|
||||||
// 开始IP, 结束IP, IP个数, 位置
|
|
||||||
['1.0.1.0', '1.0.3.255', 768, '福州'],
|
|
||||||
['1.0.8.0', '1.0.15.255', 2048, '广州'],
|
|
||||||
['1.0.32.0', '1.0.63.255', 8192, '广州'],
|
|
||||||
['1.1.0.0', '1.1.0.255', 256, '福州'],
|
|
||||||
['1.1.2.0', '1.1.63.255', 15872, '广州'],
|
|
||||||
['1.2.0.0', '1.2.2.255', 768, '北京'],
|
|
||||||
['1.2.4.0', '1.2.127.255', 31744, '广州'],
|
|
||||||
['1.3.0.0', '1.3.255.255', 65536, '广州'],
|
|
||||||
['1.4.1.0', '1.4.127.255', 32512, '广州'],
|
|
||||||
['1.8.0.0', '1.8.255.255', 65536, '北京'],
|
|
||||||
['1.10.0.0', '1.10.9.255', 2560, '福州'],
|
|
||||||
['1.10.11.0', '1.10.127.255', 29952, '广州'],
|
|
||||||
['1.12.0.0', '1.15.255.255', 262144, '上海'],
|
|
||||||
['1.18.128.0', '1.18.128.255', 256, '北京'],
|
|
||||||
['1.24.0.0', '1.31.255.255', 524288, '赤峰'],
|
|
||||||
['1.45.0.0', '1.45.255.255', 65536, '北京'],
|
|
||||||
['1.48.0.0', '1.51.255.255', 262144, '济南'],
|
|
||||||
['1.56.0.0', '1.63.255.255', 524288, '伊春'],
|
|
||||||
['1.68.0.0', '1.71.255.255', 262144, '忻州'],
|
|
||||||
['1.80.0.0', '1.95.255.255', 1048576, '北京'],
|
|
||||||
['1.116.0.0', '1.117.255.255', 131072, '上海'],
|
|
||||||
['1.119.0.0', '1.119.255.255', 65536, '北京'],
|
|
||||||
['1.180.0.0', '1.185.255.255', 393216, '桂林'],
|
|
||||||
['1.188.0.0', '1.199.255.255', 786432, '洛阳'],
|
|
||||||
['1.202.0.0', '1.207.255.255', 393216, '铜仁'],
|
|
||||||
]
|
|
||||||
|
|
||||||
// 将原始字符串段转换为数值段并计算总数(在模块初始化时完成一次)
|
// IP地址转换函数
|
||||||
function ipToInt(ip) {
|
function ipToInt(ip) {
|
||||||
const parts = ip.split('.').map(Number)
|
const parts = ip.split('.').map(Number)
|
||||||
const a = (parts[0] << 24) >>> 0
|
const a = (parts[0] << 24) >>> 0
|
||||||
@ -49,20 +21,56 @@ function intToIp(int) {
|
|||||||
].join('.')
|
].join('.')
|
||||||
}
|
}
|
||||||
|
|
||||||
const chinaIPRanges = (function buildRanges() {
|
// 解析CIDR格式的IP段
|
||||||
const arr = []
|
function parseCIDR(cidr) {
|
||||||
let total = 0
|
const [ipStr, prefixLengthStr] = cidr.split('/')
|
||||||
for (let i = 0; i < chinaIPRangesRaw.length; i++) {
|
const prefixLength = parseInt(prefixLengthStr, 10)
|
||||||
const r = chinaIPRangesRaw[i]
|
|
||||||
const start = ipToInt(r[0])
|
const ipInt = ipToInt(ipStr)
|
||||||
const end = ipToInt(r[1])
|
const mask = (0xffffffff << (32 - prefixLength)) >>> 0
|
||||||
const count = r[2] || end - start + 1
|
const start = (ipInt & mask) >>> 0
|
||||||
arr.push({ start, end, count, location: r[3] || '' })
|
const end = (start | (~mask >>> 0)) >>> 0
|
||||||
total += count
|
const count = end - start + 1
|
||||||
|
|
||||||
|
return { start, end, count, cidr }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从china_ip_ranges.txt加载中国IP段(CIDR格式)
|
||||||
|
const chinaIPRanges = (function loadChinaIPRanges() {
|
||||||
|
try {
|
||||||
|
const filePath = path.join(__dirname, '../data/china_ip_ranges.txt')
|
||||||
|
const content = fs.readFileSync(filePath, 'utf-8')
|
||||||
|
const lines = content
|
||||||
|
.split('\n')
|
||||||
|
.filter((line) => line.trim() && !line.startsWith('#'))
|
||||||
|
|
||||||
|
const arr = []
|
||||||
|
let total = 0
|
||||||
|
|
||||||
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
const line = lines[i].trim()
|
||||||
|
if (!line) continue
|
||||||
|
|
||||||
|
const range = parseCIDR(line)
|
||||||
|
arr.push(range)
|
||||||
|
total += range.count
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按IP段大小排序,提高随机选择效率
|
||||||
|
arr.sort((a, b) => b.count - a.count)
|
||||||
|
|
||||||
|
// attach total for convenience
|
||||||
|
arr.totalCount = total
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
`Loaded ${arr.length} Chinese IP ranges from china_ip_ranges.txt, total ${total} IPs`,
|
||||||
|
)
|
||||||
|
return arr
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('Failed to load china_ip_ranges.txt:', error.message)
|
||||||
|
// 返回空数组,generateRandomChineseIP会使用兜底逻辑
|
||||||
|
return { totalCount: 0 }
|
||||||
}
|
}
|
||||||
// attach total for convenience
|
|
||||||
arr.totalCount = total
|
|
||||||
return arr
|
|
||||||
})()
|
})()
|
||||||
const floor = Math.floor
|
const floor = Math.floor
|
||||||
const random = Math.random
|
const random = Math.random
|
||||||
@ -144,16 +152,11 @@ module.exports = {
|
|||||||
// 如果没有选中(理论上不应该发生),回退到最后一个段
|
// 如果没有选中(理论上不应该发生),回退到最后一个段
|
||||||
if (!chosen) chosen = chinaIPRanges[chinaIPRanges.length - 1]
|
if (!chosen) chosen = chinaIPRanges[chinaIPRanges.length - 1]
|
||||||
|
|
||||||
// 在段内随机生成一个 IP(使用段真实的数值范围,而非 csv 中的 count)
|
// 在段内随机生成一个 IP(使用段真实的数值范围)
|
||||||
const segSize = chosen.end - chosen.start + 1
|
const segSize = chosen.end - chosen.start + 1
|
||||||
const ipInt = chosen.start + Math.floor(random() * segSize)
|
const ipInt = chosen.start + Math.floor(random() * segSize)
|
||||||
const ip = intToIp(ipInt)
|
const ip = intToIp(ipInt)
|
||||||
logger.info(
|
logger.info('Generated Random Chinese IP:', ip, 'from CIDR:', chosen.cidr)
|
||||||
'Generated Random Chinese IP:',
|
|
||||||
ip,
|
|
||||||
'location:',
|
|
||||||
chosen.location,
|
|
||||||
)
|
|
||||||
return ip
|
return ip
|
||||||
},
|
},
|
||||||
// 生成chainId的函数
|
// 生成chainId的函数
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user