1 | import { GameSetting } from "@xmcl/common";
|
2 |
|
3 | declare module "@xmcl/common/gamesetting" {
|
4 | namespace GameSetting {
|
5 | |
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | export function parse<T extends boolean>(str: string, strict?: T): T extends true ? GameSetting : GameSetting.Frame;
|
12 |
|
13 | |
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | export function stringify(setting: GameSetting | GameSetting.Frame | any, original?: string, eol?: string): string;
|
21 | }
|
22 | }
|
23 |
|
24 |
|
25 | GameSetting.parse = parse as <T extends boolean>(str: string, strict?: T) => T extends true ? GameSetting : GameSetting.Frame;
|
26 | GameSetting.stringify = stringify;
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 | function parse(str: string, strict?: boolean): GameSetting | GameSetting.Frame {
|
35 | const lines = str.split("\n");
|
36 | const intPattern = /^\d+$/;
|
37 | const floatPattern = /^[-+]?[0-9]*\.[0-9]+$/;
|
38 | const booleanPattern = /^(true)|(false)$/;
|
39 | if (!lines || lines.length === 0) {
|
40 | return strict ? GameSetting.getDefaultFrame() : {};
|
41 | }
|
42 | const setting = lines.map((line) => line.trim().split(":"))
|
43 | .filter((pair) => pair[0].length !== 0)
|
44 | .map((pair) => {
|
45 | let value: any = pair[1];
|
46 | if (intPattern.test(value)) {
|
47 | value = Number.parseInt(value, 10);
|
48 | } else if (floatPattern.test(value)) {
|
49 | value = Number.parseFloat(value);
|
50 | } else if (booleanPattern.test(value)) {
|
51 | value = value === "true";
|
52 | } else {
|
53 | try {
|
54 | value = JSON.parse(value);
|
55 | } catch (e) { }
|
56 | }
|
57 |
|
58 | return { [pair[0]]: value };
|
59 | })
|
60 | .reduce((prev, current) => Object.assign(prev, current), {});
|
61 | if (!strict) { return setting as GameSetting.Frame; }
|
62 | const source: any = GameSetting.getDefaultFrame();
|
63 | const target: any = {};
|
64 | Object.keys(source).forEach((key) => {
|
65 | target[key] = typeof setting[key] === typeof source[key] ? setting[key] : source[key];
|
66 | delete setting.key;
|
67 | });
|
68 | return target as GameSetting;
|
69 | }
|
70 |
|
71 | function stringify(setting: GameSetting | GameSetting.Frame | any, original?: string, eol: string = "\n"): string {
|
72 | let model: any;
|
73 | if (original) {
|
74 | model = parse(original) as any;
|
75 | for (const key in model) {
|
76 | if (model.hasOwnProperty(key) && setting.hasOwnProperty(key)) {
|
77 | model[key] = setting[key];
|
78 | }
|
79 | }
|
80 | } else { model = setting; }
|
81 | return Object.keys(model)
|
82 | .filter((key) => key !== undefined && key !== "undefined")
|
83 | .map((key) => {
|
84 | const val = model[key];
|
85 | return typeof val !== "string" ? `${key}:${JSON.stringify(val)}` : `${key}:${val}`;
|
86 | }).join(eol);
|
87 | }
|
88 |
|
89 | export * from "@xmcl/common/gamesetting";
|