mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 02:15:34 -04:00
wip modding (4): event api, logger, example in Modding.md
This commit is contained in:
parent
5e2ac9646d
commit
30cbabe1c8
@ -69,3 +69,56 @@ 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.
|
||||
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.
|
||||
|
||||
## 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 Thread logThread;
|
||||
|
||||
public static void log(LogLevels l, String message, TextComponent.ChatAttributes color) {
|
||||
if (l.ordinal() > level.ordinal()) {
|
||||
public static void log(LogLevels level, String message, TextComponent.ChatAttributes color) {
|
||||
if (level.ordinal() > Log.level.ordinal()) {
|
||||
// log level too low
|
||||
return;
|
||||
}
|
||||
@ -36,7 +36,7 @@ public class Log {
|
||||
builder.append("] [");
|
||||
builder.append(Thread.currentThread().getName());
|
||||
builder.append("] [");
|
||||
builder.append(l.name());
|
||||
builder.append(level.name());
|
||||
builder.append("] ");
|
||||
if (color != null && Config.colorLog) {
|
||||
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;
|
||||
|
||||
import de.bixilon.minosoft.modding.loading.ModInfo;
|
||||
import de.bixilon.minosoft.modding.loading.ModPhases;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 {
|
||||
static TreeMap<ModInfo, MinosoftMod> modMap;
|
||||
|
||||
ModPhases currentPhase;
|
||||
|
||||
public static void loadMods() {
|
||||
modMap = new TreeMap<>((a, b) -> {
|
||||
LoadingPriorities priorityA = getLoadingPriorityOrDefault(a);
|
||||
@ -61,6 +59,7 @@ public class ModLoader {
|
||||
JclObjectFactory factory = JclObjectFactory.getInstance();
|
||||
|
||||
MinosoftMod instance = (MinosoftMod) factory.create(jcl, modInfo.getMainClass());
|
||||
instance.setInfo(modInfo);
|
||||
Log.verbose(String.format("[MOD] Mod file loaded (%s)", modInfo));
|
||||
modMap.put(modInfo, instance);
|
||||
zipFile.close();
|
||||
|
@ -29,20 +29,15 @@ public class PacketChatMessageReceiving implements ClientboundPacket {
|
||||
|
||||
@Override
|
||||
public boolean read(InByteBuffer buffer) {
|
||||
message = buffer.readTextComponent();
|
||||
if (buffer.getProtocolId() < 7) {
|
||||
message = buffer.readTextComponent();
|
||||
position = ChatTextPositions.CHAT_BOX;
|
||||
return true;
|
||||
}
|
||||
if (buffer.getProtocolId() < 718) {
|
||||
message = buffer.readTextComponent();
|
||||
position = ChatTextPositions.byId(buffer.readByte());
|
||||
return true;
|
||||
}
|
||||
|
||||
message = buffer.readTextComponent();
|
||||
position = ChatTextPositions.byId(buffer.readByte());
|
||||
sender = buffer.readUUID();
|
||||
if (buffer.getProtocolId() >= 718) {
|
||||
sender = buffer.readUUID();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -34,4 +34,18 @@ public class ServerAddress {
|
||||
public String toString() {
|
||||
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