Skip to content

Commit 1e86cd8

Browse files
committed
2 parents 7361d08 + 9a6d1b3 commit 1e86cd8

File tree

7 files changed

+72
-53
lines changed

7 files changed

+72
-53
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v1.10.3-6b2e6c5
1+
v1.10.4-bb3ac7a

bmclapi_dashboard/static/js/index.min.js

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,14 +1152,12 @@ class WebSocketClient {
11521152
class MinecraftUtils {
11531153
static getVarInt(data) {
11541154
let r = [];
1155-
while (true) {
1156-
if ((data & 0xFFFFFF80) === 0) {
1157-
r.push(data);
1158-
break;
1159-
}
1160-
r.push(data & 0x7F | 0x80);
1161-
data >>= 7;
1155+
data = (data << 1) ^ (data >> 63)
1156+
while ((data & ~0x7F) != 0) {
1157+
r.push((data & 0x7f) | 0x80)
1158+
data >>= 7
11621159
}
1160+
r.push(data);
11631161
return r;
11641162
}
11651163
static getVarIntLength(data) {
@@ -1295,16 +1293,15 @@ class DataInputStream extends BytesBuffer {
12951293
return (new DataView(new Uint8Array(this.readBytes(4)))).getFloat32()
12961294
}
12971295
readVarInt() {
1298-
let i = 0;
1299-
let j = 0;
1300-
let k;
1301-
while (true) {
1302-
k = this.read(1)[0];
1303-
i |= (k & 0x7F) << j * 7;
1304-
j += 1;
1305-
if ((k & 0x80) !== 128) break;
1306-
}
1307-
return i >= 2 ** 31 - 1 ? i - 2 ** 31 * 2 : i;
1296+
let b = this.read(1)[0]
1297+
let n = b & 0x7F
1298+
let shift = 7
1299+
while ((b & 0x80) != 0) {
1300+
b = this.read(1)[0]
1301+
n |= (b & 0x7F) << shift
1302+
shift += 7
1303+
}
1304+
return (n >> 1) ^ -(n & 1)
13081305
}
13091306
readString(maximum = null, encoding = 'utf-8') {
13101307
return new TextDecoder(encoding).decode(new Uint8Array(this.read(maximum == null ? this.readVarInt() : maximum)));

core/api.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ def is_url(self):
5757
if not isinstance(self.path, str):
5858
return False
5959
return self.path.startswith("http://") or self.path.startswith("https://")
60+
61+
def is_path(self):
62+
return isinstance(self.path, Path)
6063

6164
def get_path(self) -> str | Path:
6265
return self.path

core/cluster.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -533,13 +533,14 @@ async def get(self, hash: str, offset: int = 0) -> File:
533533
file.cache = True
534534
return file
535535
path = Path(str(self.dir) + f"/{hash[:2]}/{hash}")
536-
buf = io.BytesIO()
537-
async with aiofiles.open(path, "rb") as r:
538-
while data := await r.read(IO_BUFFER):
539-
buf.write(data)
540-
file = File(path, hash, buf.tell(), time.time(), time.time())
541-
file.set_data(buf.getbuffer())
536+
file = File(path, hash, 0)
542537
if CACHE_ENABLE:
538+
buf = io.BytesIO()
539+
async with aiofiles.open(path, "rb") as r:
540+
while data := await r.read(IO_BUFFER):
541+
buf.write(data)
542+
file = File(path, hash, buf.tell(), time.time(), time.time())
543+
file.set_data(buf.getbuffer())
543544
self.cache[hash] = file
544545
file.cache = False
545546
return file
@@ -1443,7 +1444,7 @@ async def _(request: web.Request, hash: str):
14431444
if data.is_url() and isinstance(data.get_path(), str):
14441445
return web.RedirectResponse(str(data.get_path())).set_headers(name)
14451446
return web.Response(
1446-
data.get_data().getbuffer(), headers=data.headers or {}
1447+
data.get_data().getbuffer() if not data.is_path() else data.get_path(), headers=data.headers or {}
14471448
).set_headers(name)
14481449

14491450
dir = Path("./bmclapi_dashboard/")

core/stats.py

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -563,18 +563,25 @@ def stats_pro(day):
563563
f"select hour, data from access_ip where hour >= ?",
564564
t,
565565
):
566-
hour = (
567-
(q[0] + get_utc_offset())
568-
if not format_day
569-
else (q[0] + get_utc_offset()) // 24
570-
)
571-
data = DataInputStream(zstd.decompress(q[1]))
572-
for ip, c in {
573-
data.readString(): data.readVarInt() for _ in range(data.readVarInt())
574-
}.items():
575-
if hour not in s_ip:
576-
s_ip[hour] = defaultdict(int)
577-
s_ip[hour][ip] += c
566+
hour = (q[0] + get_utc_offset()) if not format_day else (q[0] + get_utc_offset()) // 24
567+
try:
568+
data = DataInputStream(zstd.decompress(q[1]))
569+
for ip, c in {data.readString(): data.readVarInt() for _ in range(data.readVarInt())}.items():
570+
if hour not in s_ip:
571+
s_ip[hour] = defaultdict(int)
572+
s_ip[hour][ip] += c
573+
except:
574+
new_data = DataOutputStream()
575+
data_ip = {data.readString(old_data_read_varint(data)): old_data_read_varint(data) for _ in range(old_data_read_varint(data))}
576+
new_data.writeVarInt(len(data_ip))
577+
for ip, c in data_ip.items():
578+
new_data.writeString(ip)
579+
new_data.writeVarInt(c)
580+
if hour not in s_ip:
581+
s_ip[hour] = defaultdict(int)
582+
s_ip[hour][ip] += c
583+
execute("update access_ip set data = ? where hour = ?", zstd.compress(new_data.io.getbuffer()), hour)
584+
578585
addresses: defaultdict[location.IPInfo, int] = defaultdict(int)
579586
for ips in s_ip.values():
580587
for address, count in ips.items():
@@ -596,3 +603,16 @@ def stats_pro(day):
596603
"bytes": file_bytes,
597604
"downloads": file_download,
598605
}
606+
607+
608+
def old_data_read_varint(input: DataInputStream):
609+
i: int = 0
610+
j: int = 0
611+
k: int
612+
while 1:
613+
k = int.from_bytes(input.read(1), byteorder="big")
614+
i |= (k & 0x7F) << j * 7
615+
j += 1
616+
if (k & 0x80) != 128:
617+
break
618+
return i

core/utils.py

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import re
1111
import sys
1212
import time
13+
import avro
1314
from typing import (
1415
Any,
1516
Coroutine,
@@ -528,12 +529,11 @@ class MinecraftUtils:
528529
@staticmethod
529530
def getVarInt(data: int):
530531
r: bytes = b""
531-
while 1:
532-
if data & 0xFFFFFF80 == 0:
533-
r += data.to_bytes(1, "big")
534-
break
535-
r += (data & 0x7F | 0x80).to_bytes(1, "big")
532+
data = (data << 1) ^ (data >> 63)
533+
while (data & ~0x7F) != 0:
534+
r += ((data & 0x7f) | 0x80).to_bytes(1, "big")
536535
data >>= 7
536+
r += data.to_bytes(1, "big")
537537
return r
538538

539539
@staticmethod
@@ -626,16 +626,14 @@ def readLong(self) -> int:
626626
return value - 2**64 if value > 2**63 - 1 else value
627627

628628
def readVarInt(self) -> int:
629-
i: int = 0
630-
j: int = 0
631-
k: int
632-
while 1:
633-
k = int.from_bytes(self.read(1), byteorder="big")
634-
i |= (k & 0x7F) << j * 7
635-
j += 1
636-
if (k & 0x80) != 128:
637-
break
638-
return i
629+
b = ord(self.read(1))
630+
n = b & 0x7F
631+
shift = 7
632+
while (b & 0x80) != 0:
633+
b = ord(self.read(1))
634+
n |= (b & 0x7F) << shift
635+
shift += 7
636+
return (n >> 1) ^ -(n & 1)
639637

640638
def readString(
641639
self, maximun: Optional[int] = None, encoding: Optional[str] = None

core/web.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ async def __call__(
905905
async with aiofiles.open(content, "rb") as r:
906906
cur_length: int = 0
907907
await r.seek(start_bytes, os.SEEK_SET)
908-
while data := await r.read(min(IO_BUFFER, length - cur_length)):
908+
while data := await r.read(max(0, min(IO_BUFFER, length - cur_length))):
909909
cur_length += len(data)
910910
client.write(data)
911911
await client.drain()

0 commit comments

Comments
 (0)