Skip to content
This repository was archived by the owner on Mar 12, 2025. It is now read-only.

Commit f67148f

Browse files
committed
✨ 完全支持API
1 parent 7f41afa commit f67148f

File tree

6 files changed

+250
-15
lines changed

6 files changed

+250
-15
lines changed

config.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"file"=> [
1313
"cache_dir"=> "./cache",//缓存文件夹
1414
"check"=> "size",//检查文件策略(hash:检查文件hash size:检查文件大小 exists:检查文件是否存在)
15+
"database_dir"=> "./database",//访问数据数据库目录
1516
],
1617
"advanced"=> [
1718
"keepalive"=> 60,//keepalive时间,秒为单位(不建议调整)

inc/database.php

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<?php
2+
use Swoole\Coroutine\Lock;
3+
class Database {
4+
private $dirPath;
5+
6+
public function __construct() {
7+
if (!$this->dirPath) {
8+
$base_dir = api::getconfig();
9+
$this->dirPath = $base_dir['file']['database_dir'];
10+
}
11+
}
12+
13+
public function initializeDatabase() {
14+
$filename = $this->dirPath . '/' . date('Ymd');
15+
if (!is_dir($this->dirPath)) {
16+
mkdir($this->dirPath, 0777, true);
17+
}
18+
if (!file_exists($filename)) {
19+
$initialData = [];
20+
for ($hour = 0; $hour < 24; ++$hour) {
21+
$timeKey = date('Ymd') . str_pad($hour, 2, '0', STR_PAD_LEFT);
22+
$initialData[$timeKey] = ['hits' => 0, 'bytes' => 0];
23+
}
24+
file_put_contents($filename, json_encode($initialData, JSON_PRETTY_PRINT));
25+
}
26+
}
27+
28+
public function writeDatabase($hits, $bytes) {
29+
$filename = $this->dirPath . '/' . date('Ymd');
30+
if (!file_exists($filename)) {
31+
$this->initializeDatabase();
32+
}
33+
$data = json_decode(Swoole\Coroutine\System::readFile($filename), true);
34+
$timeKey = date('Ymd') . str_pad(date('G'), 2, '0', STR_PAD_LEFT);
35+
if (!isset($data[$timeKey])) {
36+
$data[$timeKey] = ['hits' => 0, 'bytes' => 0];
37+
}
38+
$data[$timeKey]['hits'] += $hits;
39+
$data[$timeKey]['bytes'] += $bytes;
40+
$w = Swoole\Coroutine\System::writeFile($filename, json_encode($data, JSON_PRETTY_PRINT));
41+
}
42+
43+
public function getDaysData(): array {
44+
$dailyTraffic = [];
45+
$endDate = date('Ymd');
46+
$startDate = date('Ymd', strtotime('-14 days'));
47+
48+
for ($i = 0; $i <= 14; ++$i) {
49+
$date = date('Ymd', strtotime("-$i days", strtotime($endDate)));
50+
$filename = $this->dirPath . '/' . $date;
51+
$dailySummary = ['hits' => 0, 'bytes' => 0];
52+
if (file_exists($filename)) {
53+
$data = json_decode(Swoole\Coroutine\System::readFile($filename), true);
54+
foreach ($data as $hourlyRecord) {
55+
if (isset($hourlyRecord['hits']) && isset($hourlyRecord['bytes'])) {
56+
$dailySummary['hits'] += $hourlyRecord['hits'];
57+
$dailySummary['bytes'] += $hourlyRecord['bytes'];
58+
}
59+
}
60+
}
61+
$dailyTraffic[$date] = $dailySummary;
62+
}
63+
ksort($dailyTraffic);
64+
return $dailyTraffic;
65+
}
66+
67+
public function getMonthsData(): array {
68+
$monthlyTraffic = [];
69+
$endDate = new DateTime(); // 获取当前日期
70+
$startDate = clone $endDate;
71+
$startDate->modify('-11 months'); // 回溯11个月,以包含完整的12个月数据
72+
73+
while ($startDate <= $endDate) {
74+
$monthStr = $startDate->format('Ym'); // 格式化为YYYYMM格式
75+
$monthlySummary = ['hits' => 0, 'bytes' => 0];
76+
77+
for ($day = 1; $day <= $startDate->format('t'); ++$day) { // 遍历当月的所有天
78+
$dateStr = $startDate->format('Ymd');
79+
$filename = $this->dirPath . '/' . $dateStr;
80+
81+
if (file_exists($filename)) {
82+
$data = json_decode(file_get_contents($filename), true); // 使用file_get_contents以兼容更多环境
83+
84+
foreach ($data as $hourlyRecord) {
85+
if (isset($hourlyRecord['hits']) && isset($hourlyRecord['bytes'])) {
86+
$monthlySummary['hits'] += $hourlyRecord['hits'];
87+
$monthlySummary['bytes'] += $hourlyRecord['bytes'];
88+
}
89+
}
90+
}
91+
$startDate->modify('+1 day'); // 移动到下一天
92+
}
93+
94+
// 累加完一个月的数据后存入结果数组
95+
$monthlyTraffic[$monthStr] = $monthlySummary;
96+
}
97+
98+
return $monthlyTraffic;
99+
}
100+
101+
public function getYearsData(): array {
102+
$annualTraffic = [];
103+
$currentYear = (int)date('Y');
104+
$startYear = $currentYear - 5;
105+
106+
for ($year = $startYear; $year <= $currentYear; ++$year) {
107+
$yearHits = 0;
108+
$yearBytes = 0;
109+
110+
for ($month = 1; $month <= 12; ++$month) {
111+
for ($day = 1; $day <= 31; ++$day) { // 假定每月最多31天,实际应用需按月份调整
112+
$date = sprintf('%04d%02d%02d', $year, $month, $day);
113+
$filename = $this->dirPath . '/' . $date;
114+
115+
if (file_exists($filename)) {
116+
$data = json_decode(Swoole\Coroutine\System::readFile($filename), true);
117+
foreach ($data as $hourlyRecord) {
118+
if (isset($hourlyRecord['hits']) && isset($hourlyRecord['bytes'])) {
119+
$yearHits += $hourlyRecord['hits'];
120+
$yearBytes += $hourlyRecord['bytes'];
121+
}
122+
}
123+
}
124+
}
125+
}
126+
127+
// 累计完一年的数据后存入结果数组
128+
$annualTraffic[$year] = [
129+
'hits' => $yearHits,
130+
'bytes' => $yearBytes
131+
];
132+
}
133+
134+
return $annualTraffic;
135+
}
136+
}

inc/server.php

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,6 @@ public function startserver() {
5555
$end_byte = filesize($filepath) - 1;
5656
}
5757
$length = $end_byte - $start_byte + 1;
58-
$fileSize = filesize($filepath);
59-
if (api::getinfo()['enable']){
60-
global $kacounters;
61-
$kacounters->incr('1','hits');
62-
$kacounters->incr('1','bytes',$length);
63-
}
6458
$code = 206;
6559
$response->header('Content-Type', 'application/octet-stream');
6660
if(isset($request->header['name'])){
@@ -70,12 +64,7 @@ public function startserver() {
7064
$response->sendfile($filepath,$start_byte,$length);
7165
}
7266
else{
73-
$enable = api::getinfo()['enable'];
74-
if ($enable){
75-
global $kacounters;
76-
$kacounters->incr('1','hits');
77-
$kacounters->incr('1','bytes',filesize($filepath));
78-
}
67+
$length = filesize($filepath);
7968
$code = 200;
8069
$response->header('Content-Type', 'application/octet-stream');
8170
if(isset($request->header['name'])){
@@ -84,6 +73,15 @@ public function startserver() {
8473
$response->header('x-bmclapi-hash', $downloadhash);
8574
$response->sendfile($filepath);
8675
}
76+
if (api::getinfo()['enable']){
77+
global $kacounters;
78+
$kacounters->incr('1','hits');
79+
$kacounters->incr('1','bytes',$length);
80+
81+
global $dbcounters;
82+
$dbcounters->incr('1','hits');
83+
$dbcounters->incr('1','bytes',$length);
84+
}
8785
}
8886
else{
8987
$code = 403;
@@ -169,7 +167,10 @@ public function startserver() {
169167
$response->end($type->getstatus());
170168
}
171169
elseif($type === "info"){
172-
170+
$code = 200;
171+
$response->header('Content-Type', 'application/json; charset=utf-8');
172+
$type = new webapi();
173+
$response->end($type->getinfo());
173174
}
174175
else{
175176
$code = 403;
@@ -196,7 +197,7 @@ public function stopserver() {
196197
$this->server->shutdown();
197198
}
198199
//你问我这段函数为什么要放在server里面? 因为只有server需要check_sign(
199-
public function check_sign(string $hash, string $secret, string $s, string $e): bool {
200+
public function check_sign(string $hash, string $secret, string $s=null, string $e=null): bool {
200201
try {
201202
$t = intval($e, 36);
202203
} catch (\Exception $ex) {

inc/socketio.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,16 @@ public function connect() {
8787
$katimeid = Swoole\Timer::tick($this->kattl*1000, function () use ($kacounters) {
8888
$this->keepalive($kacounters);
8989
});
90+
91+
global $dbcounters;
92+
$dbcounters = new Swoole\Table(1024);
93+
$dbcounters->column('hits', Swoole\Table::TYPE_FLOAT);
94+
$dbcounters->column('bytes', Swoole\Table::TYPE_FLOAT);
95+
$dbcounters->create();
96+
$dbcounters->set('1', ['hits' => 0, 'bytes' => 0]);
97+
$dbtimeid = Swoole\Timer::tick(3000, function () use ($dbcounters) {
98+
$this->updatedatabase($dbcounters);
99+
});
90100
}
91101
else{
92102
$client->close();
@@ -197,6 +207,11 @@ public function keepalive($kacounters) {
197207
$kacounters->set('1', ['hits' => 0, 'bytes' => 0]);
198208
}
199209

210+
public function updatedatabase($dbcounters) {
211+
$database = new database();
212+
$database->writeDatabase($dbcounters->get('1','hits'),$dbcounters->get('1','bytes'));
213+
$dbcounters->set('1', ['hits' => 0, 'bytes' => 0]);
214+
}
200215
public function IsTime($inputString) {
201216
$pattern = '/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/';
202217
return preg_match($pattern, $inputString) === 1;
@@ -207,5 +222,7 @@ public function disable() {
207222
if ($enable){
208223
$this->ack("disable");
209224
}
225+
$this->client->close();
226+
$this->Connected = false;
210227
}
211228
}

inc/webapi.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
use Swoole\Lock;
23
class webapi{
34
public function gettype() {
45
$array = [
@@ -25,4 +26,78 @@ public function getstatus() {
2526
$type = json_encode($array);
2627
return $type;
2728
}
29+
public function getinfo() {
30+
31+
$array = [
32+
'data' => [
33+
"hours" => $this->DataTohours(),
34+
"days" => $this->DataTodays(),
35+
"months" => $this->DataTomonths()
36+
]
37+
];
38+
$type = json_encode($array);
39+
return $type;
40+
}
41+
42+
public function DataTohours() {
43+
$base_dir = api::getconfig();
44+
$dirPath = $base_dir['file']['database_dir'];
45+
$data = file_get_contents($dirPath . '/' . date('Ymd')); // 读取文件内容
46+
$dataArray = json_decode($data, true); // 解码JSON数据为关联数组
47+
48+
if (json_last_error() !== JSON_ERROR_NONE) {
49+
echo "Error decoding JSON: " . json_last_error_msg();
50+
return [];
51+
}
52+
53+
$formattedData = [];
54+
$currentHourTimestamp = strtotime(date('Y-m-d H:00:00', time())); // 当前小时的时间戳
55+
$twelveHoursAgoTimestamp = $currentHourTimestamp - (12 * 3600); // 12小时前的时间戳
56+
foreach ($dataArray as $key => $value) {
57+
// 提取日期时间字符串的前8位为日期(如20240610),后两位为小时
58+
$dateStr = substr($key, 0, 8);
59+
$hour = intval(substr($key, 8));
60+
// 假设日期格式为YYYYMMDD,转换为Unix时间戳(这里未考虑时区,实际应用中可能需要调整)
61+
$timestamp = mktime(0, 0, 0, substr($dateStr, 4, 2), substr($dateStr, 6, 2), substr($dateStr, 0, 4)) + ($hour * 3600);
62+
if ($timestamp >= $twelveHoursAgoTimestamp && $timestamp < $currentHourTimestamp){
63+
$formattedData[] = [
64+
'timestamp' => $timestamp,
65+
'hits' => $value['hits'],
66+
'bytes' => $value['bytes']
67+
];
68+
}
69+
}
70+
return $formattedData;
71+
}
72+
73+
public function DataTodays() {
74+
$database = new Database();
75+
$data = $database->getDaysData();
76+
$formattedData = [];
77+
foreach ($data as $date => $stats) {
78+
$timestamp = strtotime($date);
79+
$formattedData[] = [
80+
'timestamp' => $timestamp,
81+
'hits' => $stats['hits'],
82+
'bytes' => $stats['bytes']
83+
];
84+
}
85+
86+
return $formattedData;
87+
}
88+
89+
public function DataTomonths() {
90+
$database = new Database();
91+
$data = $database->getMonthsData();
92+
$formattedData = [];
93+
foreach ($data as $date => $stats) {
94+
$timestamp = strtotime($date . 00);
95+
$formattedData[] = [
96+
'timestamp' => $timestamp,
97+
'hits' => $stats['hits'],
98+
'bytes' => $stats['bytes']
99+
];
100+
}
101+
return $formattedData;
102+
}
28103
}

main.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
}
1111
api::getconfig($config);
1212
const PHPOBAVERSION = '1.6.0';
13-
const VERSION = '1.10.6';
13+
const VERSION = '1.10.9';
1414
$download_dir = api::getconfig()['file']['cache_dir'];
1515
const USERAGENT = 'openbmclapi-cluster/' . VERSION . ' ' . 'php-openbmclapi/'.PHPOBAVERSION;
1616
const OPENBMCLAPIURL = 'openbmclapi.bangbang93.com';
@@ -40,6 +40,11 @@ function registerSigintHandler() {
4040
exits();
4141
});
4242
}
43+
44+
//创建数据库
45+
$database = new database();
46+
$database->initializedatabase();
47+
4348
//获取初次Token
4449
$token = new token($config['cluster']['CLUSTER_ID'],$config['cluster']['CLUSTER_SECRET'],VERSION);
4550
$tokendata = $token->gettoken();

0 commit comments

Comments
 (0)