mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 18:34:56 -04:00
wip modding (4): event api, logger, example in Modding.md
This commit is contained in:
parent
5e2ac9646d
commit
30cbabe1c8
@ -68,4 +68,57 @@ There are different phases (states) for the loading. There are the following pha
|
|||||||
|
|
||||||
The most important thing is performance. To archive fast loading times, etc, all mods (if they don't on each other) are getting loaded async.
|
The most important thing is performance. To archive fast loading times, etc, all mods (if they don't on each other) are getting loaded async.
|
||||||
One phase is completed (= Next phase starts), once all mods have completed the previous phase. Everything is async.
|
One phase is completed (= Next phase starts), once all mods have completed the previous phase. Everything is async.
|
||||||
If your start function needs much time, you can set the loading priority in the `mod.json` to start at the beginning. The `start` method returns a success boolean.
|
If your start function needs much time, you can set the loading priority in the `mod.json` to start at the beginning. The `start` method returns a success boolean.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
Add Minosoft to your maven dependencies with
|
||||||
|
Repository:
|
||||||
|
```xml
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>jitpack.io</id>
|
||||||
|
<url>https://jitpack.io</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
```
|
||||||
|
Dependency:
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.bixilon.gitlab.bixilon</groupId>
|
||||||
|
<artifactId>minosoft</artifactId>
|
||||||
|
<version>master-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
```
|
||||||
|
Create a Main class, here is an example
|
||||||
|
```java
|
||||||
|
package de.bixilon.example.mod.main;
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.modding.MinosoftMod;
|
||||||
|
import de.bixilon.minosoft.modding.loading.ModPhases;
|
||||||
|
|
||||||
|
public class TestMod extends MinosoftMod {
|
||||||
|
public boolean start(ModPhases phase) {
|
||||||
|
if (phase == ModPhases.BOOTING) {
|
||||||
|
getLogger().info("Hello world!");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Your `mod.json` can look like this
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"uuid": "1f37a8e0-9ec7-45db-ad2f-40afd2eb5a07",
|
||||||
|
"versionId": 1,
|
||||||
|
"versionName": "1.0",
|
||||||
|
"authors": ["Bixilon"],
|
||||||
|
"name": "Example Mod",
|
||||||
|
"identifier": "example",
|
||||||
|
"mainClass": "de.bixilon.example.mod.main.TestMod"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Events
|
||||||
|
There are global events (which works on all connections) and connections events (server specific).
|
||||||
|
|
||||||
|
@ -25,8 +25,8 @@ public class Log {
|
|||||||
static LogLevels level = LogLevels.PROTOCOL;
|
static LogLevels level = LogLevels.PROTOCOL;
|
||||||
static Thread logThread;
|
static Thread logThread;
|
||||||
|
|
||||||
public static void log(LogLevels l, String message, TextComponent.ChatAttributes color) {
|
public static void log(LogLevels level, String message, TextComponent.ChatAttributes color) {
|
||||||
if (l.ordinal() > level.ordinal()) {
|
if (level.ordinal() > Log.level.ordinal()) {
|
||||||
// log level too low
|
// log level too low
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -36,7 +36,7 @@ public class Log {
|
|||||||
builder.append("] [");
|
builder.append("] [");
|
||||||
builder.append(Thread.currentThread().getName());
|
builder.append(Thread.currentThread().getName());
|
||||||
builder.append("] [");
|
builder.append("] [");
|
||||||
builder.append(l.name());
|
builder.append(level.name());
|
||||||
builder.append("] ");
|
builder.append("] ");
|
||||||
if (color != null && Config.colorLog) {
|
if (color != null && Config.colorLog) {
|
||||||
builder.append(color);
|
builder.append(color);
|
||||||
|
93
src/main/java/de/bixilon/minosoft/modding/Logger.java
Normal file
93
src/main/java/de/bixilon/minosoft/modding/Logger.java
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Codename Minosoft
|
||||||
|
* Copyright (C) 2020 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.modding;
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.game.datatypes.TextComponent;
|
||||||
|
import de.bixilon.minosoft.logging.Log;
|
||||||
|
import de.bixilon.minosoft.logging.LogLevels;
|
||||||
|
|
||||||
|
public class Logger {
|
||||||
|
private final String modName;
|
||||||
|
|
||||||
|
public Logger(String modName) {
|
||||||
|
this.modName = modName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void log(LogLevels level, String message, TextComponent.ChatAttributes color) {
|
||||||
|
Log.log(level, String.format("[%s] %s", modName, message), color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs all game related things (chunk loading, rendering, ...)
|
||||||
|
*
|
||||||
|
* @param message Raw message to log
|
||||||
|
*/
|
||||||
|
public void game(String message) {
|
||||||
|
log(LogLevels.GAME, message, TextComponent.ChatAttributes.GREEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs all fatal errors (critical exceptions, etc)
|
||||||
|
*
|
||||||
|
* @param message Raw message to log
|
||||||
|
*/
|
||||||
|
public void fatal(String message) {
|
||||||
|
log(LogLevels.FATAL, message, TextComponent.ChatAttributes.DARK_RED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs all general infos (connecting to server, ...)
|
||||||
|
*
|
||||||
|
* @param message Raw message to log
|
||||||
|
*/
|
||||||
|
public void info(String message) {
|
||||||
|
log(LogLevels.INFO, message, TextComponent.ChatAttributes.WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs all warnings (connection to server failed, ...)
|
||||||
|
*
|
||||||
|
* @param message Raw message to log
|
||||||
|
*/
|
||||||
|
public void warn(String message) {
|
||||||
|
log(LogLevels.WARNING, message, TextComponent.ChatAttributes.RED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs all debug relevant infos (...)
|
||||||
|
*
|
||||||
|
* @param message Raw message to log
|
||||||
|
*/
|
||||||
|
public void debug(String message) {
|
||||||
|
log(LogLevels.DEBUG, message, TextComponent.ChatAttributes.GRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs all debug relevant infos (even higher level!) (connection status, ...)
|
||||||
|
*
|
||||||
|
* @param message Raw message to log
|
||||||
|
*/
|
||||||
|
public void verbose(String message) {
|
||||||
|
log(LogLevels.VERBOSE, message, TextComponent.ChatAttributes.YELLOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs all protocol data (received protocol with length and command x,...)
|
||||||
|
*
|
||||||
|
* @param message Raw message to log
|
||||||
|
*/
|
||||||
|
public void protocol(String message) {
|
||||||
|
log(LogLevels.PROTOCOL, message, TextComponent.ChatAttributes.BLUE);
|
||||||
|
}
|
||||||
|
}
|
@ -13,11 +13,43 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.modding;
|
package de.bixilon.minosoft.modding;
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.modding.loading.ModInfo;
|
||||||
import de.bixilon.minosoft.modding.loading.ModPhases;
|
import de.bixilon.minosoft.modding.loading.ModPhases;
|
||||||
|
|
||||||
interface MinosoftModInterface {
|
interface MinosoftModInterface {
|
||||||
|
/**
|
||||||
|
* @param phase The current loading phase
|
||||||
|
* @return If the loading was successful. If not, the mod is getting disabled.
|
||||||
|
*/
|
||||||
boolean start(ModPhases phase);
|
boolean start(ModPhases phase);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class MinosoftMod implements MinosoftModInterface {
|
public abstract class MinosoftMod implements MinosoftModInterface {
|
||||||
|
protected boolean enabled = false;
|
||||||
|
private ModInfo info;
|
||||||
|
private Logger logger;
|
||||||
|
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModInfo getInfo() {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInfo(ModInfo info) {
|
||||||
|
if (this.info != null) {
|
||||||
|
throw new RuntimeException(String.format("Mod info already set %s vs %s", this.info, info));
|
||||||
|
}
|
||||||
|
this.info = info;
|
||||||
|
this.logger = new Logger(info.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Logger getLogger() {
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Codename Minosoft
|
||||||
|
* Copyright (C) 2020 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.modding.event;
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.modding.event.events.ChatMessageReceivingEvent;
|
||||||
|
|
||||||
|
public class EventListener {
|
||||||
|
public void onChatMessageReceiving(ChatMessageReceivingEvent event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Codename Minosoft
|
||||||
|
* Copyright (C) 2020 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.modding.event.events;
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.game.datatypes.ChatTextPositions;
|
||||||
|
import de.bixilon.minosoft.game.datatypes.TextComponent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ChatMessageReceivingEvent extends Event {
|
||||||
|
private final TextComponent message;
|
||||||
|
private final ChatTextPositions position;
|
||||||
|
private final UUID sender;
|
||||||
|
|
||||||
|
public ChatMessageReceivingEvent(TextComponent message, ChatTextPositions position, UUID sender) {
|
||||||
|
this.message = message;
|
||||||
|
this.position = position;
|
||||||
|
this.sender = sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextComponent getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChatTextPositions getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The uuid of the sender
|
||||||
|
*/
|
||||||
|
@MinimumProtocolVersion(protocolId = 718)
|
||||||
|
public UUID getSender() {
|
||||||
|
return this.sender;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Codename Minosoft
|
||||||
|
* Copyright (C) 2020 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.modding.event.events;
|
||||||
|
|
||||||
|
public class Event {
|
||||||
|
boolean cancelled = false;
|
||||||
|
|
||||||
|
protected Event() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCancelled(boolean cancelled) {
|
||||||
|
this.cancelled = cancelled;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Codename Minosoft
|
||||||
|
* Copyright (C) 2020 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.modding.event.events;
|
||||||
|
|
||||||
|
public @interface MaximumProtocolVersion {
|
||||||
|
int protocolId() default Integer.MAX_VALUE;
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Codename Minosoft
|
||||||
|
* Copyright (C) 2020 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.modding.event.events;
|
||||||
|
|
||||||
|
public @interface MinimumProtocolVersion {
|
||||||
|
int protocolId() default 0;
|
||||||
|
}
|
@ -28,8 +28,6 @@ import java.util.zip.ZipFile;
|
|||||||
public class ModLoader {
|
public class ModLoader {
|
||||||
static TreeMap<ModInfo, MinosoftMod> modMap;
|
static TreeMap<ModInfo, MinosoftMod> modMap;
|
||||||
|
|
||||||
ModPhases currentPhase;
|
|
||||||
|
|
||||||
public static void loadMods() {
|
public static void loadMods() {
|
||||||
modMap = new TreeMap<>((a, b) -> {
|
modMap = new TreeMap<>((a, b) -> {
|
||||||
LoadingPriorities priorityA = getLoadingPriorityOrDefault(a);
|
LoadingPriorities priorityA = getLoadingPriorityOrDefault(a);
|
||||||
@ -61,6 +59,7 @@ public class ModLoader {
|
|||||||
JclObjectFactory factory = JclObjectFactory.getInstance();
|
JclObjectFactory factory = JclObjectFactory.getInstance();
|
||||||
|
|
||||||
MinosoftMod instance = (MinosoftMod) factory.create(jcl, modInfo.getMainClass());
|
MinosoftMod instance = (MinosoftMod) factory.create(jcl, modInfo.getMainClass());
|
||||||
|
instance.setInfo(modInfo);
|
||||||
Log.verbose(String.format("[MOD] Mod file loaded (%s)", modInfo));
|
Log.verbose(String.format("[MOD] Mod file loaded (%s)", modInfo));
|
||||||
modMap.put(modInfo, instance);
|
modMap.put(modInfo, instance);
|
||||||
zipFile.close();
|
zipFile.close();
|
||||||
|
@ -29,20 +29,15 @@ public class PacketChatMessageReceiving implements ClientboundPacket {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean read(InByteBuffer buffer) {
|
public boolean read(InByteBuffer buffer) {
|
||||||
|
message = buffer.readTextComponent();
|
||||||
if (buffer.getProtocolId() < 7) {
|
if (buffer.getProtocolId() < 7) {
|
||||||
message = buffer.readTextComponent();
|
|
||||||
position = ChatTextPositions.CHAT_BOX;
|
position = ChatTextPositions.CHAT_BOX;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (buffer.getProtocolId() < 718) {
|
|
||||||
message = buffer.readTextComponent();
|
|
||||||
position = ChatTextPositions.byId(buffer.readByte());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
message = buffer.readTextComponent();
|
|
||||||
position = ChatTextPositions.byId(buffer.readByte());
|
position = ChatTextPositions.byId(buffer.readByte());
|
||||||
sender = buffer.readUUID();
|
if (buffer.getProtocolId() >= 718) {
|
||||||
|
sender = buffer.readUUID();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,4 +34,18 @@ public class ServerAddress {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return getHostname() + ":" + getPort();
|
return getHostname() + ":" + getPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return hostname.hashCode() * port;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (super.equals(obj)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
ServerAddress their = (ServerAddress) obj;
|
||||||
|
return hostname.equals(their.getHostname()) && port == their.getPort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user