-
Notifications
You must be signed in to change notification settings - Fork 0
/
flowerful.ts
120 lines (94 loc) · 3.35 KB
/
flowerful.ts
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
/*
* Flowerful runtime detour library for Creator of Another World
*/
import { FlowerAPI, IFlowerPlugin, isModule, LogSource } from "@flowerloader/api";
import { flowerPatcher } from "./flowerful.patches";
/* Set this to true to get ALL the spammy log messages */
const debuglogging = false;
type LogCallback = (title: string, message: string) => void;
export class flowerCore<T>
{
//All the plugins live here
Plugins: { [key: string]: IFlowerPlugin } = {};
MyLogSource: LogSource;
Patcher: flowerPatcher;
API: FlowerAPI<T>;
Debug: boolean = debuglogging;
async LoadAllPlugins(plugin_root: string): Promise<void>
{
// load json from local file
const str = `./config.js`
const js = await import(str);
const files: string[] = js.ENABLED_PLUGINS;
this.MyLogSource.writeDebug(`Loading ${files.length} plugins`);
for (const file of files)
{
this.MyLogSource.writeDebug(`Loading File: ${file}`);
await this.LoadPlugin(file);
}
this.MyLogSource.writeDebug(`Running awakes for plugins`);
for (const guid in this.Plugins)
{
try
{
this.Plugins[guid].Awake();
} catch (e: any)
{
this.MyLogSource.write(`Error loading ${guid}: ${e.message}`);
//Delete patches from bad boys that fail on Awake()
delete this.Plugins[guid];
}
}
//This should be completely redundant now
this.Patcher.ApplyAllPatches();
}
async LoadPlugin(file: string): Promise<void>
{
const filePath = `./flower-plugins/${file}`
this.MyLogSource.write(`Importing ${filePath}`);
try
{
const maybePlugin = (await import(filePath));
if (isModule(maybePlugin))
{
const {
META: meta, default: pluginConstructor
} = maybePlugin;
if (!this.Plugins[meta.GUID])
{
//Squawk
this.MyLogSource.writeDebug(`Registering ${meta.GUID}`);
//Check plugin is enabled
if (!meta.ENABLED)
{
this.MyLogSource.writeDebug("Skipping, plugin is disabled");
return;
}
//Where the magic happens
const plugin = new pluginConstructor(this.API, new LogSource(meta.GUID, this.MyLogSource.writer, this.MyLogSource.debugWriter));
this.Plugins[meta.GUID] = plugin;
}
else
{
throw new Error("Duplicate plugin loaded");
}
}
else
throw new Error("Not a valid plugin")
}
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
catch (e: any)
{
this.MyLogSource.write(`Error loading: ${e.message}`);
return;
}
}
constructor(LogSource: LogSource, API: FlowerAPI<T>)
{
this.MyLogSource = LogSource;
this.Patcher = new flowerPatcher(this.MyLogSource);
//API nonsense
API.RegisterPatch = this.Patcher.RegisterPatch.bind(this.Patcher);
this.API = API;
}
}