dedicatedserver, events, teavm quirks doc

This commit is contained in:
ZXMushroom63 2024-09-05 18:59:54 +08:00
parent f58750a08a
commit 846eb6533b
6 changed files with 113 additions and 10 deletions

View File

@ -1 +1,30 @@
## ModAPI.dedicatedServer
## ModAPI.dedicatedServer
This is the dedicated server module, used for modding singleplayer in more powerful ways.
ModAPI.dedicatedServer has the following methods:
- `appendCode(code: Function | String) : void`
- Injects provided code into the dedicated server.
### Modding the dedicated server
Eaglercraft runs the dedicated server in a service worker. This means that in order to run code to mod the dedicated server, you have to change context into the service worker.
`ModAPI.dedicatedServer.appendCode()` allows you to inject code into the dedicates server before startup. The code injected will throw errors if it attempts to access resources outside the functions context.
For example, take a look at this mod, which will inject some code that does nothing into the dedicated server:
```javascript
var myVariable = 4;
function myServerSideModCode() {
function subfunction() {
console.log("serverside!!!");
}
subfunction();
//Successfully running serverside
//However, we cannot access `myVariable`
}
ModAPI.dedicatedServer.appendCode(myServerSideModCode);
```
Once serverside, you can only access server side events, like `serverstart` or `tick`.

View File

@ -1 +1,69 @@
## Events
## Events
Events broadcast data for use in mods.
- `ModAPI.addEventListener(eventName: String, callback: Function) : void`
- Used to register an event handler. Eg:
- ```javascript
function myHandler(event) {
console.log(event);
}
ModAPI.addEventListener("update", myHandler);
```
- `ModAPI.removeEventListener(eventName: String, callback: Function) : void`
- Used to unregister an event handler. Eg:
- ```javascript
function myHandler(event) {
console.log(event);
}
ModAPI.removeEventListener("update", myHandler);
```
### Basic Events
- `update`:
- Called every client side tick.
- Event object is blank.
- `load`:
- Called when all mods have finished loading.
- Event object is blank.
- `sendchatmessage`:
- Called just before the player sends a chat message.
- Passes an object with properties:
- `message: String`
- String representing the chat message.
- `preventDefault: Boolean`
- Boolean representing whether or not to cancel processing the chat message. Default is `false`.
- `event`:
- Called when any event is called. Passes an object with properties:
- Passes an object with properties:
- `event: String`
- String representing the type of event being fired.
- `data: Object`
- Object representing the original arguments to be passed to the callback.
### Server Side Events
Can only be used in the context of the dedicated server. More: [DedicatedServerDocumentation](dedicatedserver.md)
- `serverstart`:
- Called when the dedicated server starts.
- Event object is blank.
- `serverstop`:
- Called when the dedicated server stops.
- Event object is blank.
- `tick`:
- Called when the server ticks.
- Passes an object with properties:
- `preventDefault: Boolean`
- Boolean representing whether or not to cancel the tick. Default is `false`.
- `receivechatmessage`:
- Called when the server receives a chat message.
- Passes an object with properties:
- `message: String`
- String representing the chat message.
- `preventDefault: Boolean`
- Boolean representing whether or not to cancel processing the chat message. Default is `false`.
- `processcommand`:
- Called when the server receives a command.
- Passes an object with properties:
- `command: String`
- String representing the command.
- `preventDefault: Boolean`
- Boolean representing whether or not to cancel processing the command. Default is `false`.

View File

@ -35,7 +35,7 @@ The global object has the following properties:
- It can only be accessed in the dedicated server's context. (See `ModAPI.dedicatedServer`)
- It can also be accessed using `ModAPI.serverInstance`
- `ModAPI.rawServer: MinecraftServer`
- This is the dedicated minecraft server in the service worker, generated when the `serverstart`.
- This is the dedicated minecraft server in the service worker, generated when the `serverstart` event is fired.
- It can only be accessed in the dedicated server's context. (See `ModAPI.dedicatedServer`)
- It can also be accessed using `ModAPI.server.getRef()`
- `ModAPI.hooks`

View File

@ -0,0 +1,8 @@
## Quirks in TeaVM
When TeaVM compiles code, it sometimes does strange things.
#### Property Suffixes
TeaVM will add suffixes to some variables, seemingly randomly. An example is the property `inGround` of any entity. When accessing this on the `ModAPI.player.fishEntity` object, TeaVM has renamed it to `inGround2`.
#### Collapsing Methods
When I was trying to hook into the server-side processing of chat messages, I found that chat packets were handled by the method `processChatMessage` in `NetHandlerPlayServer`. However, in the compiled JavaScript, this method no longer exists. This is because it is only used once, in the `processPacket` method of `C01PacketChatMessage`. TeaVM automatically saw this, and collapsed one method into the other.

View File

@ -141,10 +141,8 @@ globalThis.modapi_postinit = `(() => {
}
targetMethodMap[method.replace(compiledName + "_", "")] = {
method: ModAPI.hooks.methods[method],
proxiedMethod: function (...args) {
return ModAPI.hooks.methods[method].apply(this, args);
},
methodName: method
methodName: method,
methodNameShort: method.replace(compiledName + "_", "")
};
//Prototype Injection, allows for far easier access to methods
@ -165,7 +163,7 @@ globalThis.modapi_postinit = `(() => {
}
ModAPI.reflect.getClassByName = function (className) {
var classKeys = Object.keys(ModAPI.hooks._classMap);
var key = classKeys.filter(k => {k.endsWith("_" + className)})[0];
var key = classKeys.filter(k => {return ModAPI.hooks._classMap[k].name === className})[0];
return key ? ModAPI.hooks._classMap[key] : null;
}
var reloadDeprecationWarnings = 0;
@ -444,7 +442,7 @@ globalThis.modapi_postinit = `(() => {
return x;
};
var integratedServerStartup = ModAPI.util.getMethodFromPackage("net.lax1dude.eaglercraft.v1_8.sp.internal.ClientPlatformSingleplayer", "loadIntegratedServerSourceInline");
var integratedServerStartup = ModAPI.util.getMethodFromPackage("net.lax1dude.eaglercraft.v1_8.sp.internal.ClientPlatformSingleplayer", "createBlobObj");
//Integrated server setup has a randomised suffix on the end
integratedServerStartup = ModAPI.hooks._rippedMethodKeys.filter(key => { return key.startsWith(integratedServerStartup); })[0];
const integratedServerStartupMethod = ModAPI.hooks.methods[integratedServerStartup];

View File

@ -442,7 +442,7 @@
return x;
};
var integratedServerStartup = ModAPI.util.getMethodFromPackage("net.lax1dude.eaglercraft.v1_8.sp.internal.ClientPlatformSingleplayer", "loadIntegratedServerSourceInline");
var integratedServerStartup = ModAPI.util.getMethodFromPackage("net.lax1dude.eaglercraft.v1_8.sp.internal.ClientPlatformSingleplayer", "createBlobObj");
//Integrated server setup has a randomised suffix on the end
integratedServerStartup = ModAPI.hooks._rippedMethodKeys.filter(key => { return key.startsWith(integratedServerStartup); })[0];
const integratedServerStartupMethod = ModAPI.hooks.methods[integratedServerStartup];