-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
137 lines (117 loc) · 3.67 KB
/
index.html
File metadata and controls
137 lines (117 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<!DOCTYPE html>
<meta charset="utf-8">
<html>
<!-- https://github.com/iodide-project/pyodide/issues/679#issuecomment-637519913 -->
<head>
<script type="text/javascript">window.languagePluginUrl = 'https://pyodide-cdn2.iodide.io/v0.15.0/full/';</script>
<script src="https://pyodide-cdn2.iodide.io/v0.15.0/full/pyodide.js"></script>
</head>
<body>
<h1>Binary file reader & writer pyodide</h1>
<h3>for collection.db osu game file</h3>
<input type="file" onchange="doit();" id="file">
<input type="button" value="Download" onclick="download_f()">
<div id = "result_id"> </div>
<script type="text/javascript">
var content = null;
function download_f() {
var fname = "duplicated_db.db";
var __data__ = pyodide.globals.new_db;
var blob = new Blob([__data__],{type:"application/octet-stream"});
var elem = window.document.createElement('a');
elem.href = window.URL.createObjectURL(blob);
elem.download = fname;
document.body.appendChild(elem);
elem.click();
document.body.removeChild(elem);
};
function doit() {
var file = document.getElementById("file").files[0];
var reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = evt => {
content = evt.target.result;
pyodide.runPython(`
from js import content
from js import result_id
from struct import unpack
import io
def nextint(f):
return unpack("<I", f.read(4))[0]
def nextstr(f):
if f.read(1) == 0x00:
return
len = 0
shift = 0
while True:
byte = ord(f.read(1))
len |= (byte & 0b01111111) << shift
if (byte & 0b10000000) == 0:
break
shift += 7
return f.read(len).decode("utf-8")
def get_collections(osu_db_file):
"""read .db file, return raw collection"""
#print(osu_db_file,'db fiele',type(osu_db_file))
# convert to bytes buffer
f = io.BytesIO(osu_db_file)
col = {}
version = nextint(f)
ncol = nextint(f)
for i in range(ncol):
colname = nextstr(f)
col[colname] = []
for j in range(nextint(f)):
f.read(2)
col[colname].append(f.read(32).decode("utf-8"))
f.close()
return (col, version)
def write_int(file, integer):
int_b = integer.to_bytes(4, "little")
file.write(int_b)
def get_uleb128(integer):
result = 0
shift = 0
while True:
byte = integer
result |= (byte & 0x7F) << shift
if byte & 0x80 == 0:
break
shift += 7
return result.to_bytes(1, "little")
def write_string(file, string):
if not string:
return bytes([0x00])
else:
result = bytes([0x0B])
result += get_uleb128(len(string))
result += string.encode("utf-8")
file.write(result)
def update_collection(collection_dict,version):
"""manually add beatmaps to .db file
create ingame collections https://github.com/osufiles/osuCollectionManager-backup
"""
name = 'duplicate_collection'
collection_dict[name] = collection_dict[next(iter(collection_dict))]
f = io.BytesIO()
write_int(f, version)
write_int(f, len(collection_dict))
for col_name, col_hashes in collection_dict.items():
write_string(f, col_name)
write_int(f, len(col_hashes))
for h in col_hashes:
write_string(f, h)
f.seek(0)
return f
def main(osu_db_file):
_db = osu_db_file.tobytes()
col,v = get_collections(_db)
f = update_collection(col,v)
return f.read()
new_db = main(content)
`);}}
languagePluginLoader.then(function () {
console.log('Ready');
});
</script>
</body>