1 | export namespace GameSetting {
|
2 | export enum AmbientOcclusion {
|
3 | Off = 0,
|
4 | Minimum = 1,
|
5 | Maximum = 2,
|
6 | }
|
7 | export enum Particles {
|
8 | Minimum = 2,
|
9 | Decreased = 1,
|
10 | All = 0,
|
11 | }
|
12 | export enum Difficulty {
|
13 | Peaceful = 0,
|
14 | Easy = 1,
|
15 | Normal = 2,
|
16 | Hard = 3,
|
17 | }
|
18 | export type MipmapLevel = 0 | 1 | 2 | 3 | 4;
|
19 | export type RenderDistance = 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;
|
20 | export const RenderDistance = Object.freeze({ Tiny: 2, Short: 4, Normal: 8, Far: 16, Extreme: 32 });
|
21 | export const Graphic = Object.freeze({ Fast: false, Fancy: true });
|
22 | export type Graphic = boolean;
|
23 | export const RenderCloud = Object.freeze({ Off: false, Fast: "fast", Fancy: true });
|
24 | export type RenderCloud = true | false | "fast";
|
25 |
|
26 | export enum KeyCode {
|
27 | "Escape" = 1,
|
28 | "Digit1" = 2,
|
29 | "Digit2" = 3,
|
30 | "Digit3" = 4,
|
31 | "Digit4" = 5,
|
32 | "Digit5" = 6,
|
33 | "Digit6" = 7,
|
34 | "Digit7" = 8,
|
35 | "Digit8" = 9,
|
36 | "Digit9" = 10,
|
37 | "Digit0" = 11,
|
38 | "Minus" = 12,
|
39 | "Equal" = 13,
|
40 | "Backspace" = 14,
|
41 | "Tab" = 15,
|
42 |
|
43 | "KeyQ" = 16,
|
44 | "KeyW" = 17,
|
45 | "KeyE" = 18,
|
46 | "KeyR" = 19,
|
47 | "KeyT" = 20,
|
48 | "KeyY" = 21,
|
49 | "KeyU" = 22,
|
50 | "KeyI" = 23,
|
51 | "KeyO" = 24,
|
52 | "KeyP" = 25,
|
53 |
|
54 | "BracketLeft" = 26,
|
55 | "BracketRight" = 27,
|
56 | "Enter" = 28,
|
57 | "ControlLeft" = 29,
|
58 |
|
59 | "KeyA" = 30,
|
60 | "KeyS" = 31,
|
61 | "KeyD" = 32,
|
62 | "KeyF" = 33,
|
63 | "KeyG" = 34,
|
64 | "KeyH" = 35,
|
65 | "KeyJ" = 36,
|
66 | "KeyK" = 37,
|
67 | "KeyL" = 38,
|
68 |
|
69 | "Semicolon" = 39,
|
70 | "Quote" = 40,
|
71 | "Backquote" = 41,
|
72 | "ShiftLeft" = 42,
|
73 | "Backslash" = 43,
|
74 |
|
75 | "KeyZ" = 44,
|
76 | "KeyX" = 45,
|
77 | "KeyC" = 46,
|
78 | "KeyV" = 47,
|
79 | "KeyB" = 48,
|
80 | "KeyN" = 49,
|
81 | "KeyM" = 50,
|
82 |
|
83 | "Comma" = 51,
|
84 | "Period" = 52,
|
85 | "Slash" = 53,
|
86 | "ShiftRight" = 54,
|
87 |
|
88 | "Space" = 57,
|
89 | "CapsLock" = 58,
|
90 |
|
91 | "F1" = 59,
|
92 | "F2" = 60,
|
93 | "F3" = 61,
|
94 | "F4" = 62,
|
95 | "F5" = 63,
|
96 | "F6" = 64,
|
97 | "F7" = 65,
|
98 | "F8" = 66,
|
99 | "F9" = 67,
|
100 | "F10" = 68,
|
101 |
|
102 | "NumLock" = 69,
|
103 | "ScrollLock" = 70,
|
104 | "Numpad7" = 71,
|
105 | "Numpad8" = 72,
|
106 | "Numpad9" = 73,
|
107 | "NumpadSubtract" = 74,
|
108 | "Numpad4" = 75,
|
109 | "Numpad5" = 76,
|
110 | "Numpad6" = 77,
|
111 | "NumpadAdd" = 78,
|
112 | "Numpad1" = 79,
|
113 | "Numpad2" = 80,
|
114 | "Numpad3" = 81,
|
115 | "Numpad0" = 82,
|
116 | "NumpadDecimal" = 83,
|
117 | "F11" = 87,
|
118 | "F12" = 88,
|
119 | "F13" = 100,
|
120 | "F14" = 101,
|
121 | "F15" = 102,
|
122 | "F16" = 103,
|
123 | "F17" = 104,
|
124 | "F18" = 105,
|
125 |
|
126 | "ControlRight" = 157,
|
127 |
|
128 | "ArrowUp" = 200,
|
129 | "ArrowLeft" = 203,
|
130 | "ArrowRight" = 205,
|
131 | "ArrowDown" = 208,
|
132 |
|
133 | "MULTIPLY" = 55,
|
134 | "Left Menu/Alt" = 56,
|
135 |
|
136 | "NumpadEnter" = 156,
|
137 | "NumpadComma" = 179,
|
138 |
|
139 | "Home" = 199,
|
140 | "PageUp" = 201,
|
141 | "End" = 207,
|
142 | "PageDown" = 209,
|
143 | "Insert" = 210,
|
144 | "Delete" = 211,
|
145 |
|
146 | "MouseLeft" = -100,
|
147 | "MouseRight" = -99,
|
148 | "MouseMiddle" = -98,
|
149 | }
|
150 |
|
151 | const DEFAULT_FRAME = {
|
152 | "version": 1139,
|
153 | "invertYMouse": false,
|
154 | "mouseSensitivity": 0.5,
|
155 | "difficulty": Difficulty.Normal,
|
156 |
|
157 |
|
158 | "renderDistance": 12 as RenderDistance,
|
159 | "particles": Particles.Decreased,
|
160 | "fboEnable": true,
|
161 | "fancyGraphics": Graphic.Fancy,
|
162 | "ao": AmbientOcclusion.Maximum,
|
163 | "renderClouds": RenderCloud.Fancy as RenderCloud,
|
164 | "enableVsync": true,
|
165 | "useVbo": true,
|
166 | "mipmapLevels": 4 as MipmapLevel,
|
167 | "anaglyph3d": false,
|
168 |
|
169 | "fov": 0,
|
170 | "gamma": 0,
|
171 | "saturation": 0,
|
172 | "guiScale": 0,
|
173 | "bobView": true,
|
174 | "maxFps": 120,
|
175 | "fullscreen": false,
|
176 |
|
177 | "resourcePacks": [] as string[],
|
178 | "incompatibleResourcePacks": [] as string[],
|
179 | "lastServer": "",
|
180 | "lang": "en_us",
|
181 | "chatVisibility": 0,
|
182 | "chatColors": true,
|
183 | "chatLinks": true,
|
184 | "chatLinksPrompt": true,
|
185 | "chatOpacity": 1,
|
186 | "snooperEnabled": true,
|
187 |
|
188 | "hideServerAddress": false,
|
189 | "advancedItemTooltips": false,
|
190 | "pauseOnLostFocus": true,
|
191 | "touchscreen": false,
|
192 | "overrideWidth": 0,
|
193 | "overrideHeight": 0,
|
194 | "heldItemTooltips": true,
|
195 | "chatHeightFocused": 1,
|
196 | "chatHeightUnfocused": 0.44366196,
|
197 | "chatScale": 1,
|
198 | "chatWidth": 1,
|
199 | "forceUnicodeFont": false,
|
200 | "reducedDebugInfo": false,
|
201 | "useNativeTransport": true,
|
202 | "entityShadows": true,
|
203 | "mainHand": "right",
|
204 | "attackIndicator": 1,
|
205 | "showSubtitles": false,
|
206 | "realmsNotifications": true,
|
207 | "enableWeakAttacks": false,
|
208 | "autoJump": true,
|
209 | "narrator": 0,
|
210 | "tutorialStep": "movement",
|
211 | "key_key.attack": -100 as KeyCode,
|
212 | "key_key.use": -99 as KeyCode,
|
213 | "key_key.forward": 17 as KeyCode,
|
214 | "key_key.left": 30 as KeyCode,
|
215 | "key_key.back": 31 as KeyCode,
|
216 | "key_key.right": 32 as KeyCode,
|
217 | "key_key.jump": 57 as KeyCode,
|
218 | "key_key.sneak": 42 as KeyCode,
|
219 | "key_key.sprint": 29 as KeyCode,
|
220 | "key_key.drop": 16 as KeyCode,
|
221 | "key_key.inventory": 18 as KeyCode,
|
222 | "key_key.chat": 20 as KeyCode,
|
223 | "key_key.playerlist": 15 as KeyCode,
|
224 | "key_key.pickItem": -98 as KeyCode,
|
225 | "key_key.command": 53 as KeyCode,
|
226 | "key_key.screenshot": 60 as KeyCode,
|
227 | "key_key.togglePerspective": 63 as KeyCode,
|
228 | "key_key.smoothCamera": 0 as KeyCode,
|
229 | "key_key.fullscreen": 87 as KeyCode,
|
230 | "key_key.spectatorOutlines": 0 as KeyCode,
|
231 | "key_key.swapHands": 33 as KeyCode,
|
232 | "key_key.saveToolbarActivator": 46 as KeyCode,
|
233 | "key_key.loadToolbarActivator": 45 as KeyCode,
|
234 | "key_key.advancements": 38 as KeyCode,
|
235 | "key_key.hotbar.1": 2 as KeyCode,
|
236 | "key_key.hotbar.2": 3 as KeyCode,
|
237 | "key_key.hotbar.3": 4 as KeyCode,
|
238 | "key_key.hotbar.4": 5 as KeyCode,
|
239 | "key_key.hotbar.5": 6 as KeyCode,
|
240 | "key_key.hotbar.6": 7 as KeyCode,
|
241 | "key_key.hotbar.7": 8 as KeyCode,
|
242 | "key_key.hotbar.8": 9 as KeyCode,
|
243 | "key_key.hotbar.9": 10 as KeyCode,
|
244 | "soundCategory_master": 1 as KeyCode,
|
245 | "soundCategory_music": 1 as KeyCode,
|
246 | "soundCategory_record": 1 as KeyCode,
|
247 | "soundCategory_weather": 1 as KeyCode,
|
248 | "soundCategory_block": 1 as KeyCode,
|
249 | "soundCategory_hostile": 1 as KeyCode,
|
250 | "soundCategory_neutral": 1 as KeyCode,
|
251 | "soundCategory_player": 1 as KeyCode,
|
252 | "soundCategory_ambient": 1 as KeyCode,
|
253 | "soundCategory_voice": 1 as KeyCode,
|
254 | "modelPart_cape": true,
|
255 | "modelPart_jacket": true,
|
256 | "modelPart_left_sleeve": true,
|
257 | "modelPart_right_sleeve": true,
|
258 | "modelPart_left_pants_leg": true,
|
259 | "modelPart_right_pants_leg": true,
|
260 | "modelPart_hat": true,
|
261 | };
|
262 |
|
263 | export type FullFrame = typeof DEFAULT_FRAME;
|
264 | export type Frame = Partial<FullFrame>;
|
265 |
|
266 | export function getDefaultFrame(): FullFrame {
|
267 | return Object.assign({}, DEFAULT_FRAME, {
|
268 | resourcePacks: [] as string[],
|
269 | incompatibleResourcePacks: [] as string[],
|
270 | });
|
271 | }
|
272 |
|
273 | export type ModelPart =
|
274 | "cape" |
|
275 | "jacket" |
|
276 | "left_sleeve" |
|
277 | "right_sleeve" |
|
278 | "left_pants_leg" |
|
279 | "right_pants_leg" |
|
280 | "hat";
|
281 |
|
282 | export type SoundCategories =
|
283 | "master" |
|
284 | "music" |
|
285 | "record" |
|
286 | "weather" |
|
287 | "block" |
|
288 | "hostile" |
|
289 | "neutral" |
|
290 | "player" |
|
291 | "ambient" |
|
292 | "voice";
|
293 |
|
294 | export type HotKeys = "attack" |
|
295 | "use" |
|
296 | "forward" |
|
297 | "left" |
|
298 | "back" |
|
299 | "right" |
|
300 | "jump" |
|
301 | "sneak" |
|
302 | "sprint" |
|
303 | "drop" |
|
304 | "inventory" |
|
305 | "chat" |
|
306 | "playerlist" |
|
307 | "pickItem" |
|
308 | "command" |
|
309 | "screenshot" |
|
310 | "togglePerspective" |
|
311 | "smoothCamera" |
|
312 | "fullscreen" |
|
313 | "spectatorOutlines" |
|
314 | "swapHands" |
|
315 | "saveToolbarActivator" |
|
316 | "loadToolbarActivator" |
|
317 | "advancements" |
|
318 | "hotbar.1" |
|
319 | "hotbar.2" |
|
320 | "hotbar.3" |
|
321 | "hotbar.4" |
|
322 | "hotbar.5" |
|
323 | "hotbar.6" |
|
324 | "hotbar.7" |
|
325 | "hotbar.8" |
|
326 | "hotbar.9";
|
327 |
|
328 |
|
329 | |
330 |
|
331 |
|
332 |
|
333 |
|
334 |
|
335 | export function parse(str: string, strict?: boolean): GameSetting | GameSetting.Frame {
|
336 | const lines = str.split("\n");
|
337 | const intPattern = /^\d+$/;
|
338 | const floatPattern = /^[-+]?[0-9]*\.[0-9]+$/;
|
339 | const booleanPattern = /^(true)|(false)$/;
|
340 | if (!lines || lines.length === 0) {
|
341 | return strict ? GameSetting.getDefaultFrame() : {};
|
342 | }
|
343 | const setting = lines.map((line) => line.trim().split(":"))
|
344 | .filter((pair) => pair[0].length !== 0)
|
345 | .map((pair) => {
|
346 | let value: any = pair[1];
|
347 | if (intPattern.test(value)) {
|
348 | value = Number.parseInt(value, 10);
|
349 | } else if (floatPattern.test(value)) {
|
350 | value = Number.parseFloat(value);
|
351 | } else if (booleanPattern.test(value)) {
|
352 | value = value === "true";
|
353 | } else {
|
354 | try {
|
355 | value = JSON.parse(value);
|
356 | } catch (e) { }
|
357 | }
|
358 |
|
359 | return { [pair[0]]: value };
|
360 | })
|
361 | .reduce((prev, current) => Object.assign(prev, current), {});
|
362 | if (!strict) { return setting as GameSetting.Frame; }
|
363 | const source: any = GameSetting.getDefaultFrame();
|
364 | const target: any = {};
|
365 | Object.keys(source).forEach((key) => {
|
366 | target[key] = typeof setting[key] === typeof source[key] ? setting[key] : source[key];
|
367 | delete setting.key;
|
368 | });
|
369 | return target as GameSetting;
|
370 | }
|
371 |
|
372 | |
373 |
|
374 |
|
375 |
|
376 |
|
377 |
|
378 |
|
379 | export function stringify(setting: GameSetting | GameSetting.Frame | any, original?: string, eol: string = "\n"): string {
|
380 | let model: any;
|
381 | if (original) {
|
382 | model = parse(original) as any;
|
383 | for (const key in model) {
|
384 | if (model.hasOwnProperty(key) && setting.hasOwnProperty(key)) {
|
385 | model[key] = setting[key];
|
386 | }
|
387 | }
|
388 | } else { model = setting; }
|
389 | return Object.keys(model)
|
390 | .filter((key) => key !== undefined && key !== "undefined")
|
391 | .map((key) => {
|
392 | const val = model[key];
|
393 | return typeof val !== "string" ? `${key}:${JSON.stringify(val)}` : `${key}:${val}`;
|
394 | }).join(eol);
|
395 | }
|
396 | }
|
397 |
|
398 | export type GameSetting = ReturnType<typeof GameSetting.getDefaultFrame>;
|