@rian8337/osu-base 2.0.0-alpha.8 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,11 +4,33 @@ The base module required for all my osu! modules.
4
4
 
5
5
  # Features
6
6
 
7
- This module provides the required feature for all my osu! related modules, which is the beatmap parser.
7
+ This module serves as the foundation of all my osu! modules. It provides multiple features such as:
8
+
9
+ - Accuracy calculator and estimator
10
+ - Calculate an accuracy value from hit values or estimate hit values from an accuracy value.
11
+ - API request builders
12
+ - Supports osu!droid API and osu! API v1.
13
+ - Beatmap decoder
14
+ - Fully decodes an `.osu` file into a `Beatmap` object that is easier to work with.
15
+ - Beatmap encoder
16
+ - Will encode a beatmap into an `.osu` file with format version 14.
17
+ - Hit window converters
18
+ - Convert an OD value to its hit window values and vice versa.
19
+ - Map statistics calculator
20
+ - Calculate a given map statistics (CS, AR, OD, and HP) with modifications applied (mods, custom speed multiplier, etc).
21
+ - Mod conversion utilities
22
+ - Convert a mod combination string in osu!droid (i.e. `hr`) and osu!standard (i.e. `HDHR`) into an array of mods.
23
+ - Available mods can be looked at the documentation.
24
+ - Storyboard decoder
25
+ - Supports `.osb` and `.osu` files.
26
+ - Storyboard encoder
27
+ - Storyboard will be encoded into a format that is supported by `.osu` files (that is, all variable instances will be replaced).
8
28
 
9
29
  # Specific Requirements
10
30
 
11
- If you want to retrieve a beatmap using osu! API, you need to have an osu! API key set as `OSU_API_KEY` environment variable.
31
+ If you want to use the osu!droid API, you need to have an osu!droid API key set as `DROID_API_KEY` environment variable.
32
+
33
+ If you want to use the osu! API, you need to have an osu! API key set as `OSU_API_KEY` environment variable.
12
34
 
13
35
  See usage for more details.
14
36
 
@@ -26,43 +48,264 @@ yarn add @rian8337/osu-base
26
48
 
27
49
  # Usage
28
50
 
29
- ## Using osu! API
51
+ ## Accuracy Calculator and Estimator
52
+
53
+ ### Calculate Accuracy Value (0-1) from Hit Values
30
54
 
31
55
  ```js
32
- import { MapInfo } from "@rian8337/osu-base";
56
+ import { Accuracy } from "@rian8337/osu-base";
57
+
58
+ // If you specified the amount of great hits (`n300`).
59
+ let accuracyValue = new Accuracy({
60
+ n300: 1000,
61
+ n100: 125,
62
+ n50: 10,
63
+ nmiss: 5,
64
+ }).value();
65
+
66
+ console.log(accuracyValue);
67
+
68
+ // If you didn't specify the amount of great hits (`n300`).
69
+ const objectCount = 2000;
33
70
 
34
- // MD5 hash is also supported, but when both options are specified, beatmap ID is used
35
- const beatmapInfo = await MapInfo.getInformation({
36
- beatmapID: 901854,
37
- hash: "hash123",
38
- file: true,
71
+ accuracyValue = new Accuracy({
72
+ n100: 125,
73
+ n50: 10,
74
+ nmiss: 5,
75
+ }).value(objectCount);
76
+ ```
77
+
78
+ ### Hit Values Estimation
79
+
80
+ The way this estimation works is that the estimator will see if the accuracy can be estimated by just using good hit values. Otherwise, the estimator will use meh hit values.
81
+
82
+ Keep in mind that it will not use the miss hit value.
83
+
84
+ ```js
85
+ import { Accuracy } from "@rian8337/osu-base";
86
+
87
+ const accuracy = new Accuracy({
88
+ percent: 99.7,
89
+ nobjects: 2000,
39
90
  });
40
91
 
92
+ console.log(accuracy.n300);
93
+ console.log(accuracy.n100);
94
+ console.log(accuracy.n50);
95
+ ```
96
+
97
+ ## API Request Builders
98
+
99
+ ```js
100
+ import {
101
+ DroidAPIRequestBuilder,
102
+ OsuAPIRequestBuilder,
103
+ } from "@rian8337/osu-base";
104
+
105
+ const droidBuilder = new DroidAPIRequestBuilder()
106
+ .setEndpoint("getuserinfo.php")
107
+ .addParameter("uid", 51076);
108
+
109
+ const droidResult = await droidBuilder.sendRequest();
110
+
111
+ console.log(droidResult);
112
+
113
+ const osuBuilder = new OsuAPIRequestBuilder()
114
+ .setEndpoint("get_beatmaps")
115
+ .addParamter("b", 901854);
116
+
117
+ const osuResult = await osuBuilder.sendRequest();
118
+
119
+ console.log(osuResult);
120
+ ```
121
+
122
+ ## Beatmap Decoder
123
+
124
+ There are two primary ways of using the beatmap decoder.
125
+
126
+ ### Using osu! API
127
+
128
+ ```js
129
+ import { MapInfo } from "@rian8337/osu-base";
130
+
131
+ // MD5 hash is also supported in the first parameter
132
+ const beatmapInfo = await MapInfo.getInformation(901854);
133
+
41
134
  if (!beatmapInfo.title) {
42
135
  return console.log("Beatmap not found");
43
136
  }
44
137
 
45
- // Parsed beatmap can be accessed via the `map` field
46
- // Note that the parsed beatmap will be cloned every time this is called. This allows caching of the original instance when needed
138
+ // Decoded beatmap can be accessed via the `map` field
47
139
  console.log(beatmapInfo.map);
48
140
  ```
49
141
 
50
- ### Not retrieving beatmap file
142
+ #### Not retrieving beatmap file
51
143
 
52
- You can also opt out from downloading the beatmap (`.osu`) file if you just want to retrieve information from the API by setting `file` to `false`, however a parsed beatmap will not be provided.
144
+ You can also opt out from downloading the beatmap (`.osu`) file if you just want to retrieve information from the API by setting `file` to `false`, however a decoded beatmap will not be provided.
53
145
 
54
- ## Using without osu! API
146
+ ### Not using osu! API
55
147
 
56
148
  ```js
57
149
  import { readFile } from "fs";
58
- import { Parser } from "@rian8337/osu-base";
150
+ import { BeatmapDecoder } from "@rian8337/osu-base";
59
151
 
60
152
  readFile("path/to/file.osu", { encoding: "utf-8" }, (err, data) => {
61
153
  if (err) throw err;
62
154
 
63
- const parser = new Parser().parse(data);
155
+ const decoder = new BeatmapDecoder().decode(data);
156
+
157
+ // Decoded beatmap can be accessed via the `result` field
158
+ console.log(decoder.result);
159
+ });
160
+ ```
161
+
162
+ ## Beatmap Encoder
163
+
164
+ ```js
165
+ import { Beatmap, BeatmapEncoder } from "@rian8337/osu-base";
166
+
167
+ const beatmap = new Beatmap();
168
+
169
+ const encoder = new BeatmapEncoder(beatmap).encode();
170
+
171
+ // Encoded beatmap can be accessed via the `result` field
172
+ console.log(encoder.result);
173
+ ```
174
+
175
+ ## Hit Window Converters
176
+
177
+ ### OD to Hit Window
178
+
179
+ ```js
180
+ import { DroidHitWindow, OsuHitWindow } from "@rian8337/osu-base";
181
+
182
+ // Convert OD to osu!droid hit window
183
+ const droidWindow = new DroidHitWindow(10);
184
+
185
+ console.log(droidHitWindow.hitWindowFor300());
186
+ console.log(droidHitWindow.hitWindowFor100());
187
+ console.log(droidHitWindow.hitWindowFor50());
188
+
189
+ // Calculating for the Precise mod in mind is also possible
190
+ console.log(droidHitWindow.hitWindowFor300(true));
191
+ console.log(droidHitWindow.hitWindowFor100(true));
192
+ console.log(droidHitWindow.hitWindowFor50(true));
193
+
194
+ // Convert OD to osu!standard hit window
195
+ const osuWindow = new OsuHitWindow(10);
196
+
197
+ console.log(osuWindow.hitWindowFor300());
198
+ console.log(osuWindow.hitWindowFor100());
199
+ console.log(osuWindow.hitWindowFor50());
200
+ ```
201
+
202
+ ### Hit Window to OD
203
+
204
+ ```js
205
+ import { DroidHitWindow, OsuHitWindow } from "@rian8337/osu-base";
206
+
207
+ // Convert hit window to osu!droid OD
208
+ console.log(DroidHitWindow.hitWindow300ToOD(50));
209
+ console.log(DroidHitWindow.hitWindow100ToOD(100));
210
+ console.log(DroidHitWindow.hitWindow50ToOD(200));
211
+
212
+ // Calculating for the Precise mod in mind is also possible
213
+ console.log(DroidHitWindow.hitWindow300ToOD(25, true));
214
+ console.log(DroidHitWindow.hitWindow100ToOD(80, true));
215
+ console.log(DroidHitWindow.hitWindow50ToOD(130, true));
216
+
217
+ // Convert hit window to osu!standard OD
218
+ console.log(OsuHitWindow.hitWindow300ToOD(20));
219
+ console.log(OsuHitWindow.hitWindow100ToOD(60));
220
+ console.log(OsuHitWindow.hitWindow50ToOD(100));
221
+ ```
222
+
223
+ ## Map Statistics Calculator
224
+
225
+ The map statistics calculator can only be used once per instance.
226
+
227
+ ### General Usage
228
+
229
+ ```js
230
+ import { MapStats } from "@rian8337/osu-base";
231
+
232
+ const stats = new MapStats({
233
+ cs: 4,
234
+ ar: 9,
235
+ od: 8,
236
+ hp: 6,
237
+ }).calculate();
238
+
239
+ console.log(stats);
240
+ ```
241
+
242
+ Every value is optional.
243
+
244
+ ### Available Options
245
+
246
+ You can specify more options to alter the final result of the calculation:
247
+
248
+ - Mods
249
+ - Custom speed multiplier
250
+ - Force AR (whether to keep the AR at its original value)
251
+ - Game mode (switch between osu!droid and osu!standard, defaults to osu!standard)
252
+
253
+ ```js
254
+ import { MapStats, ModUtil, modes } from "@rian8337/osu-base";
255
+
256
+ const stats = new MapStats({
257
+ cs: 4,
258
+ ar: 9,
259
+ od: 8,
260
+ hp: 6,
261
+ mods: ModUtil.pcStringToMods("HDHR"),
262
+ speedMultiplier: 1.25,
263
+ isForceAR: true,
264
+ }).calculate({ mode: modes.osu });
265
+
266
+ console.log(stats);
267
+ ```
268
+
269
+ ## Mod Conversion Utilities
270
+
271
+ ```js
272
+ import { ModUtil } from "@rian8337/osu-base";
273
+
274
+ // Convert droid mod string into an array of mods
275
+ console.log(ModUtil.droidStringToMods("hr"));
276
+
277
+ // Convert PC modbits into an array of mods
278
+ console.log(ModUtil.pcModbitsToMods(12));
279
+
280
+ // Convert PC mod string into an array mods
281
+ console.log(ModUtil.pcStringToMods("HDHR"));
282
+ ```
283
+
284
+ ## Storyboard Decoder
285
+
286
+ ```js
287
+ import { readFile } from "fs";
288
+ import { StoryboardDecoder } from "@rian8337/osu-base";
289
+
290
+ readFile("path/to/file.osb", { encoding: "utf-8" }, (err, data) => {
291
+ if (err) throw err;
292
+
293
+ const decoder = new StoryboardDecoder().decode(data);
64
294
 
65
- // Parsed beatmap can be accessed via the `map` field
66
- console.log(parser.map);
295
+ // Decoded storyboard can be accessed via the `result` field
296
+ console.log(decoder.result);
67
297
  });
68
298
  ```
299
+
300
+ ## Storyboard Encoder
301
+
302
+ ```js
303
+ import { Storyboard, StoryboardEncoder } from "@rian8337/osu-base";
304
+
305
+ const storyboard = new Storyboard();
306
+
307
+ const encoder = new StoryboardEncoder(storyboard).encode();
308
+
309
+ // Encoded storyboard can be accessed via the `result` field
310
+ console.log(encoder.result);
311
+ ```