wip: refactoring log levels

This commit is contained in:
Bixilon 2021-04-24 23:34:05 +02:00
parent f934ed2027
commit 91c93e7cca
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
45 changed files with 421 additions and 509 deletions

View File

@ -122,9 +122,6 @@ public final class Minosoft {
throw e;
}
Log.info(String.format("Loaded config file (version=%s)", config.getConfig().getGeneral().getVersion()));
// set log level from config
Log.setLevel(config.getConfig().getGeneral().getLogLevel());
Log.info(String.format("Logging info with level: %s", Log.getLevel()));
}, "Configuration", String.format("Load config file (%s)", StaticConfiguration.CONFIG_FILENAME), Priorities.HIGHEST, TaskImportance.REQUIRED));
taskWorker.addTask(new Task(progress -> LocaleManager.load(config.getConfig().getGeneral().getLanguage()), "Minosoft Language", "Load minosoft language files", Priorities.HIGH, TaskImportance.REQUIRED, "Configuration"));

View File

@ -15,10 +15,10 @@ package de.bixilon.minosoft.config.config.general
import com.squareup.moshi.Json
import de.bixilon.minosoft.config.Configuration
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType
data class GeneralConfig(
var version: Int = Configuration.LATEST_CONFIG_VERSION,
@Json(name = "log_level") var logLevel: LogLevels = LogLevels.WARNING,
@Json(name = "enabled_log_types") var enabledLogTypes: MutableSet<LogMessageType> = LogMessageType.DEFAULT_LOG_MESSAGE_TYPES.toMutableSet(),
var language: String = "en_US",
)

View File

@ -17,8 +17,8 @@ import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.config.StaticConfiguration
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.Util
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.Log.log
import de.bixilon.minosoft.util.logging.LogMessageType
import java.io.*
import java.nio.file.Files
import java.security.MessageDigest
@ -58,7 +58,7 @@ interface FileAssetsManager : AssetsManager {
hash == Util.sha1(File(getAssetDiskPath(hash)))
}
} catch (exception: IOException) {
Log.printException(exception, LogLevels.DEBUG)
log(LogMessageType.OTHER_DEBUG, message = exception)
}
return false
}
@ -74,7 +74,7 @@ interface FileAssetsManager : AssetsManager {
if (checkURL) {
Util.checkURL(url)
}
Log.debug("Downloading %s -> %s", url, hash)
log(LogMessageType.OTHER_DEBUG, message = "Downloading %s -> %s", formatting = arrayOf<Any>(url, hash))
if (compress) {
Util.downloadFileAsGz(url, getAssetDiskPath(hash))
return

View File

@ -29,8 +29,8 @@ import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.util.BitByte
import de.bixilon.minosoft.util.KUtil
import de.bixilon.minosoft.util.enum.ValuesEnum
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.Log.log
import de.bixilon.minosoft.util.logging.LogMessageType
import glm_.vec3.Vec3i
import java.util.*
@ -128,7 +128,7 @@ class EntityMetaData(
try {
return it as K
} catch (e: ClassCastException) {
Log.printException(e, LogLevels.VERBOSE)
log(LogMessageType.OTHER_DEBUG, message = e)
}
}
return field.getDefaultValue()

View File

@ -24,8 +24,8 @@ import de.bixilon.minosoft.protocol.protocol.PacketTypes.S2C
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.CountUpAndDownLatch
import de.bixilon.minosoft.util.Util
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.Log.log
import de.bixilon.minosoft.util.logging.LogMessageType
data class Version(
var versionName: String,
@ -85,7 +85,7 @@ data class Version(
}
latch.countUp()
isGettingLoaded = true
Log.verbose(String.format("Loading mappings for version %s...", this))
log(LogMessageType.OTHER_DEBUG, message = String.format("Loading mappings for version %s...", this), formatting = arrayOf())
initializeAssetManger(latch)
val startTime = System.currentTimeMillis()
@ -99,7 +99,7 @@ data class Version(
Util.readJsonFromStream(assetsManager.readAssetAsStream(Resources.getPixLyzerDataHashByVersion(this)))
} catch (exception: Throwable) {
// should not happen, but if this version is not flattened, we can fallback to the flatten mappings. Some things might not work...
Log.printException(exception, LogLevels.VERBOSE)
log(LogMessageType.OTHER_DEBUG, message = exception)
if (isFlattened()) {
throw exception
}
@ -112,9 +112,9 @@ data class Version(
mapping.load(this, pixlyzerData)
latch.countDown()
if (pixlyzerData.size() > 0) {
Log.verbose(String.format("Loaded mappings for version %s in %dms (%s)", this, (System.currentTimeMillis() - startTime), versionName))
log(LogMessageType.OTHER_DEBUG, message = String.format("Loaded mappings for version %s in %dms (%s)", this, (System.currentTimeMillis() - startTime), versionName), formatting = arrayOf())
} else {
Log.verbose(String.format("Could not load mappings for version %s. Some features will be unavailable.", this))
log(LogMessageType.OTHER_DEBUG, message = String.format("Could not load mappings for version %s. Some features will be unavailable.", this), formatting = arrayOf())
}
isLoaded = true
isGettingLoaded = false

View File

@ -18,7 +18,7 @@ import de.bixilon.minosoft.Minosoft;
import de.bixilon.minosoft.data.mappings.ResourceLocation;
import de.bixilon.minosoft.data.mappings.versions.Version;
import de.bixilon.minosoft.data.mappings.versions.Versions;
import de.bixilon.minosoft.util.logging.LogLevels;
import de.bixilon.minosoft.util.logging.LogMessageType;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
@ -38,7 +38,7 @@ public class GUITools {
public static final Image MINOSOFT_LOGO = new Image(GUITools.class.getResourceAsStream("/assets/minosoft/textures/icons/window_icon.png"));
public static final ObservableList<Version> VERSIONS = FXCollections.observableArrayList();
public static final JFXComboBox<Version> VERSION_COMBO_BOX = new JFXComboBox<>(VERSIONS);
public static final ObservableList<LogLevels> LOG_LEVELS = FXCollections.observableList(Arrays.asList(LogLevels.values().clone()));
public static final ObservableList<LogMessageType> LOG_LEVELS = FXCollections.observableList(Arrays.asList(LogMessageType.values().clone()));
static {
VERSIONS.add(Versions.AUTOMATIC_VERSION);

View File

@ -14,11 +14,9 @@
package de.bixilon.minosoft.gui.main;
import com.jfoenix.controls.JFXComboBox;
import de.bixilon.minosoft.Minosoft;
import de.bixilon.minosoft.data.locale.LocaleManager;
import de.bixilon.minosoft.data.locale.Strings;
import de.bixilon.minosoft.util.logging.Log;
import de.bixilon.minosoft.util.logging.LogLevels;
import de.bixilon.minosoft.util.logging.LogMessageType;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
@ -29,7 +27,7 @@ import java.util.ResourceBundle;
public class SettingsWindow implements Initializable {
public GridPane tabGeneral;
public JFXComboBox<LogLevels> generalLogLevel;
public JFXComboBox<LogMessageType> generalLogLevel;
public Tab general;
public Tab download;
public Label generalLogLevelLabel;
@ -37,16 +35,6 @@ public class SettingsWindow implements Initializable {
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
this.generalLogLevel.setItems(GUITools.LOG_LEVELS);
this.generalLogLevel.getSelectionModel().select(Log.getLevel());
this.generalLogLevel.setOnAction((actionEvent -> {
LogLevels newLevel = this.generalLogLevel.getValue();
if (Log.getLevel() == newLevel) {
return;
}
Log.setLevel(newLevel);
Minosoft.getConfig().getConfig().getGeneral().setLogLevel(newLevel);
Minosoft.getConfig().saveToFile();
}));
this.general.setText(LocaleManager.translate(Strings.SETTINGS_GENERAL));
this.generalLogLevelLabel.setText(LocaleManager.translate(Strings.SETTINGS_GENERAL_LOG_LEVEL));

View File

@ -1,55 +0,0 @@
/*
* 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.data.text.ChatColors;
import de.bixilon.minosoft.data.text.RGBColor;
import de.bixilon.minosoft.util.logging.Log;
import de.bixilon.minosoft.util.logging.LogLevels;
public class Logger {
private final String modName;
public Logger(String modName) {
this.modName = modName;
}
public void log(LogLevels level, RGBColor color, Object message, Object... format) {
Log.log(level, String.format("[%s] ", this.modName), color, message, format);
}
public void game(Object message, Object... format) {
log(LogLevels.GAME, ChatColors.GREEN, message, format);
}
public void fatal(Object message, Object... format) {
log(LogLevels.FATAL, ChatColors.DARK_RED, message, format);
}
public void info(Object message, Object... format) {
log(LogLevels.INFO, ChatColors.WHITE, message, format);
}
public void warn(Object message, Object... format) {
log(LogLevels.WARNING, ChatColors.RED, message, format);
}
public void debug(Object message, Object... format) {
log(LogLevels.DEBUG, ChatColors.GRAY, message, format);
}
public void verbose(Object message, Object... format) {
log(LogLevels.VERBOSE, ChatColors.YELLOW, message, format);
}
}

View File

@ -21,7 +21,6 @@ public abstract class MinosoftMod {
private final EventManager eventManager = new EventManager();
protected boolean enabled = true;
private ModInfo info;
private Logger logger;
public boolean isEnabled() {
return this.enabled;
@ -40,17 +39,12 @@ public abstract class MinosoftMod {
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 EventManager getEventManager() {
return this.eventManager;
}
public Logger getLogger() {
return this.logger;
}
/**
* @param phase The current loading phase
* @return If the loading was successful. If not, the mod is getting disabled.

View File

@ -41,7 +41,8 @@ import de.bixilon.minosoft.terminal.commands.commands.Command
import de.bixilon.minosoft.util.CountUpAndDownLatch
import de.bixilon.minosoft.util.ServerAddress
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.Log.log
import de.bixilon.minosoft.util.logging.LogMessageType
import de.bixilon.minosoft.util.time.TimeWorker
import de.bixilon.minosoft.util.time.TimeWorkerTask
@ -157,11 +158,11 @@ class PlayConnection(
}
latch.waitForChange()
}
Log.info("Connecting to server: $address")
log(LogMessageType.OTHER_INFO, message = "Connecting to server: $address", formatting = arrayOf())
network.connect(address)
} catch (exception: Throwable) {
Log.printException(exception, LogLevels.DEBUG)
Log.fatal("Could not load version $version. This version seems to be unsupported!")
Log.log(LogMessageType.VERSION_LOADING) { exception }
log(LogMessageType.OTHER_FATAL, message = "Could not load version $version. This version seems to be unsupported!", formatting = arrayOf())
version.unload()
lastException = MappingsLoadingException("Mappings could not be loaded", exception)
connectionState = ConnectionStates.FAILED_NO_RETRY
@ -190,9 +191,7 @@ class PlayConnection(
override fun handlePacket(packet: S2CPacket) {
try {
if (Log.getLevel().ordinal >= LogLevels.PROTOCOL.ordinal) {
packet.log()
}
val event = PacketReceiveEvent(this, packet)
if (fireEvent(event)) {
return
@ -201,7 +200,7 @@ class PlayConnection(
packet.handle(this)
}
} catch (exception: Throwable) {
Log.printException(exception, LogLevels.PROTOCOL)
Log.log(LogMessageType.NETWORK_PACKETS_IN_ERROR) { exception }
}
}

View File

@ -33,7 +33,7 @@ import de.bixilon.minosoft.protocol.protocol.Protocol
import de.bixilon.minosoft.util.DNSUtil
import de.bixilon.minosoft.util.ServerAddress
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType
import java.util.*
class StatusConnection(
@ -64,13 +64,13 @@ class StatusConnection(
try {
resolve()
} catch (exception: Exception) {
Log.info("Can not resolve $realAddress")
Log.log(LogMessageType.NETWORK_RESOLVING) { "Can not resolve $realAddress" }
lastException = exception
connectionState = ConnectionStates.FAILED_NO_RETRY
return@execute
}
Log.info("Trying to ping $realAddress (from $address)")
Log.log(LogMessageType.NETWORK_RESOLVING) { "Trying to ping $realAddress (from $address)" }
network.connect(realAddress)
}
@ -102,7 +102,7 @@ class StatusConnection(
val nextIndex = addresses!!.indexOf(realAddress) + 1
if (addresses!!.size > nextIndex) {
val nextAddress = addresses!![nextIndex]
Log.warn(String.format("Could not connect to %s, trying next hostname: %s", address, nextAddress))
Log.log(LogMessageType.NETWORK_RESOLVING) { "Could not connect to $address, trying next hostname: $nextAddress" }
realAddress = nextAddress
ping()
} else {
@ -133,9 +133,7 @@ class StatusConnection(
override fun handlePacket(packet: S2CPacket) {
try {
if (Log.getLevel().ordinal >= LogLevels.PROTOCOL.ordinal) {
packet.log()
}
val event = PacketReceiveEvent(this, packet)
if (fireEvent(event)) {
return
@ -144,7 +142,7 @@ class StatusConnection(
packet.handle(this)
}
} catch (exception: Throwable) {
Log.printException(exception, LogLevels.PROTOCOL)
Log.log(LogMessageType.NETWORK_PACKETS_IN_ERROR) { exception }
}
}

View File

@ -28,7 +28,7 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition;
import de.bixilon.minosoft.util.Pair;
import de.bixilon.minosoft.util.ServerAddress;
import de.bixilon.minosoft.util.logging.Log;
import de.bixilon.minosoft.util.logging.LogLevels;
import de.bixilon.minosoft.util.logging.LogMessageType;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
@ -107,7 +107,7 @@ public class BlockingSocketNetwork extends Network {
var typeAndPacket = prepareS2CPacket(this.inputStream);
handlePacket(typeAndPacket.getKey(), typeAndPacket.getValue());
} catch (PacketParseException e) {
Log.printException(e, LogLevels.PROTOCOL);
Log.printException(e, LogMessageType.NETWORK_PACKETS_IN_ERROR);
}
}
this.connection.disconnect();
@ -121,7 +121,7 @@ public class BlockingSocketNetwork extends Network {
this.connection.setConnectionState(ConnectionStates.DISCONNECTED);
return;
}
Log.printException(exception, LogLevels.PROTOCOL);
Log.printException(exception, LogMessageType.NETWORK_PACKETS_IN_ERROR);
this.connection.setLastException(exception);
this.connection.setConnectionState(ConnectionStates.FAILED);
}
@ -175,9 +175,7 @@ public class BlockingSocketNetwork extends Network {
}
C2SPacket packet = this.queue.take();
if (Log.getLevel().ordinal() >= LogLevels.PROTOCOL.ordinal()) {
packet.log();
}
this.outputStream.write(prepareC2SPacket(packet));
this.outputStream.flush();

View File

@ -24,7 +24,7 @@ import de.bixilon.minosoft.protocol.protocol.CryptManager;
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition;
import de.bixilon.minosoft.util.ServerAddress;
import de.bixilon.minosoft.util.logging.Log;
import de.bixilon.minosoft.util.logging.LogLevels;
import de.bixilon.minosoft.util.logging.LogMessageType;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
@ -140,7 +140,7 @@ public class NonBlockingSocketNetwork extends Network {
var typeAndPacket = receiveS2CPacket(decryptData(currentPacketBuffer.array()));
handlePacket(typeAndPacket.getKey(), typeAndPacket.getValue());
} catch (PacketParseException e) {
Log.printException(e, LogLevels.PROTOCOL);
Log.printException(e, LogMessageType.NETWORK_PACKETS_IN_ERROR);
}
currentPacketBuffer.clear();
currentPacketBuffer = null;
@ -159,7 +159,7 @@ public class NonBlockingSocketNetwork extends Network {
if (exception instanceof SocketException && exception.getMessage().equals("Socket closed")) {
return;
}
Log.printException(exception, LogLevels.PROTOCOL);
Log.printException(exception, LogMessageType.NETWORK_PACKETS_IN_ERROR);
this.connection.setLastException(exception);
this.connection.setConnectionState(ConnectionStates.FAILED);
}

View File

@ -10,27 +10,22 @@
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.protocol.packets.c2s.play
package de.bixilon.minosoft.protocol.packets.c2s.play;
import de.bixilon.minosoft.protocol.packets.c2s.PlayC2SPacket
import de.bixilon.minosoft.protocol.protocol.PlayOutByteBuffer
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
import de.bixilon.minosoft.protocol.packets.c2s.PlayC2SPacket;
import de.bixilon.minosoft.protocol.protocol.PlayOutByteBuffer;
import de.bixilon.minosoft.util.logging.Log;
class ChatMessageC2SPacket(
val message: String,
) : PlayC2SPacket {
public class ChatMessageC2SPacket implements PlayC2SPacket {
private final String message;
public ChatMessageC2SPacket(String message) {
this.message = message;
override fun write(buffer: PlayOutByteBuffer) {
buffer.writeString(message)
}
@Override
public void write(PlayOutByteBuffer buffer) {
buffer.writeString(this.message);
}
@Override
public void log() {
Log.protocol(String.format("[OUT] Sending Chat message: %s", this.message));
override fun log() {
Log.log(LogMessageType.NETWORK_PACKETS_OUT) { "Sending Chat message: $message" }
}
}

View File

@ -19,6 +19,7 @@ import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.compoundCast
import glm_.vec3.Vec3i
@ -41,6 +42,6 @@ class BlockEntityMetaDataS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
}
override fun log() {
Log.protocol("[IN] Received block entity meta data (position=$position, type=$type, nbt=$nbt)")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Block entity meta data (position=$position, type=$type, nbt=$nbt)" }
}
}

View File

@ -17,6 +17,7 @@ import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
import glm_.vec3.Vec3
class EntityVelocityS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
@ -29,6 +30,6 @@ class EntityVelocityS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
}
override fun log() {
Log.protocol("[IN] Entity velocity changed(entityId=$entityId, velocity=$velocity)")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "[IN] Entity velocity changed(entityId=$entityId, velocity=$velocity)" }
}
}

View File

@ -24,6 +24,7 @@ import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
import glm_.vec3.Vec3i
class PacketBlockChange(buffer: PlayInByteBuffer) : PlayS2CPacket() {
@ -60,6 +61,6 @@ class PacketBlockChange(buffer: PlayInByteBuffer) : PlayS2CPacket() {
}
override fun log() {
Log.protocol("[IN] Block change received (position=${blockPosition}, block=$block)")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Block change (position=${blockPosition}, block=$block)" }
}
}

View File

@ -1,77 +0,0 @@
/*
* 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.protocol.packets.s2c.play;
import de.bixilon.minosoft.data.ChatTextPositions;
import de.bixilon.minosoft.data.text.ChatColors;
import de.bixilon.minosoft.data.text.ChatComponent;
import de.bixilon.minosoft.modding.event.events.ChatMessageReceivingEvent;
import de.bixilon.minosoft.protocol.network.connection.PlayConnection;
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket;
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer;
import de.bixilon.minosoft.util.logging.Log;
import java.util.UUID;
import static de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_14W04A;
import static de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_20W21A;
public class PacketChatMessageReceiving extends PlayS2CPacket {
private final ChatComponent message;
private final ChatTextPositions position;
private UUID sender;
public PacketChatMessageReceiving(PlayInByteBuffer buffer) {
this.message = buffer.readChatComponent();
if (buffer.getVersionId() < V_14W04A) {
this.position = ChatTextPositions.CHAT_BOX;
return;
}
this.position = ChatTextPositions.byId(buffer.readUnsignedByte());
if (buffer.getVersionId() >= V_20W21A) {
this.sender = buffer.readUUID();
}
this.message.applyDefaultColor(ChatColors.WHITE);
}
@Override
public void handle(PlayConnection connection) {
ChatMessageReceivingEvent event = new ChatMessageReceivingEvent(connection, this);
if (connection.fireEvent(event)) {
return;
}
Log.game(switch (getPosition()) {
case SYSTEM_MESSAGE -> "[SYSTEM] ";
case ABOVE_HOTBAR -> "[HOTBAR] ";
default -> "[CHAT] ";
} + event.getMessage());
}
@Override
public void log() {
Log.protocol(String.format("[IN] Received chat message (message=\"%s\")", this.message.getMessage()));
}
public ChatComponent getMessage() {
return this.message;
}
public ChatTextPositions getPosition() {
return this.position;
}
public UUID getSender() {
return this.sender;
}
}

View File

@ -0,0 +1,60 @@
/*
* 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.protocol.packets.s2c.play
import de.bixilon.minosoft.data.ChatTextPositions
import de.bixilon.minosoft.data.text.ChatColors
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.modding.event.events.ChatMessageReceivingEvent
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
import java.util.*
class PacketChatMessageReceiving(buffer: PlayInByteBuffer) : PlayS2CPacket() {
val message: ChatComponent = buffer.readChatComponent()
var position: ChatTextPositions
var sender: UUID? = null
init {
if (buffer.versionId < ProtocolVersions.V_14W04A) {
position = ChatTextPositions.CHAT_BOX
} else {
position = ChatTextPositions.byId(buffer.readUnsignedByte())
if (buffer.versionId >= ProtocolVersions.V_20W21A) {
sender = buffer.readUUID()
}
}
message.applyDefaultColor(ChatColors.WHITE)
}
override fun handle(connection: PlayConnection) {
val event = ChatMessageReceivingEvent(connection, this)
if (connection.fireEvent(event)) {
return
}
val additionalPrefix = when (position) {
ChatTextPositions.SYSTEM_MESSAGE -> "[SYSTEM] "
ChatTextPositions.ABOVE_HOTBAR -> "[HOTBAR] "
else -> ""
}
Log.log(LogMessageType.CHAT_IN, ChatComponent.valueOf(raw = additionalPrefix)) { event.message }
}
override fun log() {
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Received chat message (message=\"$message\")" }
}
}

View File

@ -24,6 +24,7 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.util.Util
import de.bixilon.minosoft.util.chunk.ChunkUtil
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
import glm_.vec2.Vec2i
import java.util.*
@ -86,6 +87,6 @@ class PacketChunkBulk() : PlayS2CPacket() {
}
override fun log() {
Log.protocol("[IN] Chunk bulk packet received (chunks=${data.size})")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Mass chunk data (chunks=${data.size})" }
}
}

View File

@ -27,6 +27,8 @@ import de.bixilon.minosoft.util.KUtil.nullCast
import de.bixilon.minosoft.util.Util
import de.bixilon.minosoft.util.chunk.ChunkUtil
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.Log.log
import de.bixilon.minosoft.util.logging.LogMessageType
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.compoundCast
import glm_.vec2.Vec2i
import glm_.vec3.Vec3i
@ -106,7 +108,7 @@ class PacketChunkData() : PlayS2CPacket() {
val position = Vec3i(nbt["x"]?.nullCast<Int>()!!, nbt["y"]?.nullCast<Int>()!!, nbt["z"]?.nullCast<Int>()!!)
val resourceLocation = ResourceLocation(nbt["id"]?.nullCast<String>()!!)
val type = buffer.connection.mapping.blockEntityRegistry.get(resourceLocation) ?: let {
Log.warn("Unknown block entity $resourceLocation")
log(LogMessageType.OTHER_ERROR, message = "Unknown block entity $resourceLocation", formatting = arrayOf())
null
} ?: continue
val entity = type.build(buffer.connection) ?: continue
@ -138,6 +140,6 @@ class PacketChunkData() : PlayS2CPacket() {
}
override fun log() {
Log.protocol("[IN] Chunk packet received (chunkPosition=$chunkPosition)")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Chunk data (chunkPosition=$chunkPosition)" }
}
}

View File

@ -17,6 +17,7 @@ import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.util.KUtil
import de.bixilon.minosoft.util.enum.ValuesEnum
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
class PacketEntityAnimation(buffer: PlayInByteBuffer) : PlayS2CPacket() {
val entityId: Int = buffer.readVarInt()
@ -24,7 +25,7 @@ class PacketEntityAnimation(buffer: PlayInByteBuffer) : PlayS2CPacket() {
override fun log() {
Log.protocol("[IN] Play entity animation (entityId=$entityId, animation=$animation)")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Play entity animation (entityId=$entityId, animation=$animation)" }
}
enum class EntityAnimations {

View File

@ -19,17 +19,11 @@ import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
class PacketEntityMetadata() : PlayS2CPacket() {
var entityId = 0
private set
lateinit var entityData: EntityMetaData
private set
constructor(buffer: PlayInByteBuffer) : this() {
entityId = buffer.readEntityId()
entityData = buffer.readMetaData()
}
class PacketEntityMetadata(buffer: PlayInByteBuffer) : PlayS2CPacket() {
val entityId = buffer.readEntityId()
val entityData: EntityMetaData = buffer.readMetaData()
override fun handle(connection: PlayConnection) {
val entity = connection.world.entities[entityId] ?: return
@ -43,6 +37,6 @@ class PacketEntityMetadata() : PlayS2CPacket() {
}
override fun log() {
Log.protocol(String.format("[IN] Received entity metadata (entityId=%d)", entityId))
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "[IN] Received entity metadata (entityId=$entityId)" }
}
}

View File

@ -17,6 +17,7 @@ import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
class PacketHeldItemChangeReceiving(buffer: PlayInByteBuffer) : PlayS2CPacket() {
val slot: Int = buffer.readByte().toInt()
@ -28,6 +29,6 @@ class PacketHeldItemChangeReceiving(buffer: PlayInByteBuffer) : PlayS2CPacket()
}
override fun log() {
Log.protocol("[IN] Slot change received. Now on slot $slot")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Slot change (slot=$slot)" }
}
}

View File

@ -31,6 +31,7 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_20W27A
import de.bixilon.minosoft.util.BitByte
import de.bixilon.minosoft.util.KUtil.nullCast
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.compoundCast
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.listCast
import kotlin.experimental.and
@ -178,7 +179,7 @@ class PacketJoinGame(buffer: PlayInByteBuffer) : PlayS2CPacket() {
}
override fun log() {
Log.protocol("[IN] Receiving join game packet (entityId=$entityId, gamemode=$gamemode, dimension=$dimension, difficulty=$difficulty, hardcore=$isHardcore, viewDistance=$viewDistance)")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Join game packet (entityId=$entityId, gamemode=$gamemode, dimension=$dimension, difficulty=$difficulty, hardcore=$isHardcore, viewDistance=$viewDistance)" }
}
companion object : ErrorHandler {

View File

@ -24,6 +24,7 @@ import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
import glm_.vec2.Vec2i
import glm_.vec3.Vec3i
@ -98,6 +99,6 @@ class PacketMultiBlockChange(buffer: PlayInByteBuffer) : PlayS2CPacket() {
}
override fun log() {
Log.protocol("[IN] Multi block change received (chunkPosition=${chunkPosition}, count=${blocks.size})")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Multi block change (chunkPosition=${chunkPosition}, count=${blocks.size})" }
}
}

View File

@ -15,6 +15,7 @@ package de.bixilon.minosoft.protocol.packets.s2c.play
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.compoundCast
class PacketNBTQueryResponse(buffer: PlayInByteBuffer) : PlayS2CPacket() {
@ -22,6 +23,6 @@ class PacketNBTQueryResponse(buffer: PlayInByteBuffer) : PlayS2CPacket() {
val nbt: Map<String, Any> = buffer.readNBT()?.compoundCast()!!
override fun log() {
Log.protocol("[IN] Received nbt response (transactionId=$transactionId nbt=$nbt)")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "NBT query response (transactionId=$transactionId nbt=$nbt)" }
}
}

View File

@ -21,6 +21,7 @@ import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.util.BitByte
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
import glm_.vec3.Vec3
class PacketPlayerPositionAndRotation(buffer: PlayInByteBuffer) : PlayS2CPacket() {
@ -80,6 +81,6 @@ class PacketPlayerPositionAndRotation(buffer: PlayInByteBuffer) : PlayS2CPacket(
}
override fun log() {
Log.protocol(String.format("[IN] Received player position (position=%s, rotation=%s, onGround=%b)", position, rotation, isOnGround))
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Player position (position=$position, rotation=$rotation, onGround=$isOnGround)" }
}
}

View File

@ -18,6 +18,7 @@ import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
class PacketReceiveDifficulty(buffer: PlayInByteBuffer) : PlayS2CPacket() {
val difficulty: Difficulties = Difficulties.byId(buffer.readUnsignedByte().toInt())
@ -36,6 +37,6 @@ class PacketReceiveDifficulty(buffer: PlayInByteBuffer) : PlayS2CPacket() {
}
override fun log() {
Log.protocol("[IN] Received server difficulty (difficulty=$difficulty, locked=${locked})")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Server difficulty (difficulty=$difficulty, locked=${locked})" }
}
}

View File

@ -22,6 +22,7 @@ import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.compoundCast
class PacketRespawn(buffer: PlayInByteBuffer) : PlayS2CPacket() {
@ -93,6 +94,6 @@ class PacketRespawn(buffer: PlayInByteBuffer) : PlayS2CPacket() {
}
override fun log() {
Log.protocol("[IN] Respawn packet received (dimension=$dimension, difficulty=$difficulty, gamemode=$gamemode, levelType=$levelType)")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Respawn (dimension=$dimension, difficulty=$difficulty, gamemode=$gamemode, levelType=$levelType)" }
}
}

View File

@ -18,6 +18,7 @@ import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
class PacketSetExperience() : PlayS2CPacket() {
var bar = 0.0f
@ -54,6 +55,6 @@ class PacketSetExperience() : PlayS2CPacket() {
}
override fun log() {
Log.protocol("[IN] Level update received. Now at $level level(s), total $total experience, experience bar at $bar", level, total)
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Level update (bar=$bar, level=$level, total=$total)" }
}
}

View File

@ -24,6 +24,8 @@ import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.util.Util
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.Log.log
import de.bixilon.minosoft.util.logging.LogMessageType
import glm_.vec3.Vec3
import java.util.*
@ -76,7 +78,7 @@ class PacketSpawnPlayer(buffer: PlayInByteBuffer) : PlayS2CPacket() {
if (metaData != null) {
entity.entityMetaData = metaData
if (StaticConfiguration.VERBOSE_ENTITY_META_DATA_LOGGING) {
Log.verbose(String.format("Metadata of entity %s (entityId=%d): %s", entity.toString(), entityId, entity.entityMetaDataAsString))
log(LogMessageType.OTHER_DEBUG, message = String.format("Metadata of entity %s (entityId=%d): %s", entity.toString(), entityId, entity.entityMetaDataAsString), formatting = arrayOf())
}
}
}
@ -89,6 +91,6 @@ class PacketSpawnPlayer(buffer: PlayInByteBuffer) : PlayS2CPacket() {
}
override fun log() {
Log.protocol("[IN] Player spawned at (position=${entity.position}, entityId=$entityId, name=${entity.name}, uuid=$entityUUID)")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Player spawned (position=${entity.position}, entityId=$entityId, name=${entity.name}, uuid=$entityUUID)" }
}
}

View File

@ -24,6 +24,7 @@ import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
import java.nio.charset.StandardCharsets
import java.util.*
@ -173,7 +174,7 @@ class PacketTabListItem(buffer: PlayInByteBuffer) : PlayS2CPacket() {
}
override fun log() {
Log.protocol("[IN] Received tab list items: $items")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Received tab list items: $items" }
}

View File

@ -23,6 +23,7 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.util.KUtil
import de.bixilon.minosoft.util.chunk.LightUtil.readLightPacket
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
import glm_.vec2.Vec2i
import java.util.*
@ -56,7 +57,7 @@ class PacketUpdateLight(buffer: PlayInByteBuffer) : PlayS2CPacket() {
}
override fun log() {
Log.protocol("[IN] Received light update (position=$chunkPosition)")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Light update (position=$chunkPosition)" }
}
override fun handle(connection: PlayConnection) {

View File

@ -21,6 +21,7 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.util.KUtil.unsafeCast
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
import glm_.vec3.Vec3i
class PacketUpdateSignReceiving(buffer: PlayInByteBuffer) : PlayS2CPacket() {
@ -51,6 +52,6 @@ class PacketUpdateSignReceiving(buffer: PlayInByteBuffer) : PlayS2CPacket() {
}
override fun log() {
Log.protocol("[IN] Sign data received (position=$signPosition, lines=$lines")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Sign data (position=$signPosition, lines=$lines" }
}
}

View File

@ -18,6 +18,7 @@ import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.util.BitByte.isBit
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
class PlayerAbilitiesS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
val isInvulnerable: Boolean
@ -30,15 +31,13 @@ class PlayerAbilitiesS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
init {
val flags = buffer.readUnsignedByte()
if (buffer.versionId < ProtocolVersions.V_14W03B) { // ToDo: Find out correct version
isInvulnerable = flags.isBit(0)
isFlying = flags.isBit(1)
canFly = flags.isBit(2)
if (buffer.versionId < ProtocolVersions.V_14W03B) { // ToDo: Find out correct version
isInvulnerable = flags.isBit(0)
canInstantBuild = flags.isBit(3)
} else {
canInstantBuild = flags.isBit(0)
isFlying = flags.isBit(1)
canFly = flags.isBit(2)
isInvulnerable = flags.isBit(3)
}
flyingSpeed = buffer.readFloat()
@ -46,7 +45,7 @@ class PlayerAbilitiesS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
}
override fun log() {
Log.protocol("[IN] Received player abilities: (isInvulnerable=$isInvulnerable, isFlying=$isFlying, canFly=$canFly, canInstantBuild=$canInstantBuild, flyingSpeed=$flyingSpeed, walkingSpeed=$walkingSpeed)")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "Player abilities: (isInvulnerable=$isInvulnerable, isFlying=$isFlying, canFly=$canFly, canInstantBuild=$canInstantBuild, flyingSpeed=$flyingSpeed, walkingSpeed=$walkingSpeed)" }
}
override fun handle(connection: PlayConnection) {

View File

@ -12,11 +12,11 @@
*/
package de.bixilon.minosoft.protocol.packets.s2c.play
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogMessageType
import glm_.vec3.Vec3i
class WorldEventS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
@ -29,10 +29,7 @@ class WorldEventS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
val data: Int = buffer.readInt()
val isGlobal: Boolean = buffer.readBoolean()
override fun handle(connection: PlayConnection) {
}
override fun log() {
Log.protocol("[IN] Received world event packet (position=$position, eventId=$eventId, data=$data, isGlobal=$isGlobal)")
Log.log(LogMessageType.NETWORK_PACKETS_IN) { "World event packet (position=$position, eventId=$eventId, data=$data, isGlobal=$isGlobal)" }
}
}

View File

@ -16,8 +16,8 @@ package de.bixilon.minosoft.util
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.mappings.ResourceLocation
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.Log.log
import de.bixilon.minosoft.util.logging.LogMessageType
import java.text.DateFormat
import java.text.SimpleDateFormat
@ -103,8 +103,8 @@ object GitInfo {
IS_INITIALIZED = true
} catch (exception: Throwable) {
Log.printException(exception, LogLevels.DEBUG)
Log.warn("Can not load git information.")
log(LogMessageType.OTHER_DEBUG, message = exception)
log(LogMessageType.OTHER_ERROR, message = "Can not load git information.", formatting = arrayOf())
}
}
}

View File

@ -1,216 +0,0 @@
/*
* 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.util.logging;
import de.bixilon.minosoft.Minosoft;
import de.bixilon.minosoft.config.StaticConfiguration;
import de.bixilon.minosoft.data.ChatTextPositions;
import de.bixilon.minosoft.data.text.BaseComponent;
import de.bixilon.minosoft.data.text.ChatColors;
import de.bixilon.minosoft.data.text.ChatComponent;
import de.bixilon.minosoft.data.text.RGBColor;
import de.bixilon.minosoft.util.Pair;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.concurrent.LinkedBlockingQueue;
public class Log {
public static final long MINOSOFT_START_TIME = System.currentTimeMillis();
private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
private static final LinkedBlockingQueue<Pair<ChatComponent, ChatComponent>> LOG_QUEUE = new LinkedBlockingQueue<>(); // prefix, message
private static final PrintStream SYSTEM_ERR_STREAM = System.err;
private static final PrintStream SYSTEM_OUT_STREAM = System.out;
private static final PrintStream ERROR_PRINT_STREAM = new LogPrintStream(LogLevels.WARNING);
private static final PrintStream OUT_PRINT_STREAM = new LogPrintStream(LogLevels.INFO);
private static LogLevels level = LogLevels.PROTOCOL;
static {
if (StaticConfiguration.REPLACE_SYSTEM_OUT_STREAMS) {
System.setErr(ERROR_PRINT_STREAM);
System.setOut(OUT_PRINT_STREAM);
}
new Thread(() -> {
while (true) {
// something to print
Pair<ChatComponent, ChatComponent> message;
try {
message = LOG_QUEUE.take();
} catch (InterruptedException e) {
e.printStackTrace();
continue;
}
SYSTEM_OUT_STREAM.println(message.getKey().getAnsiColoredMessage() + message.getValue().getAnsiColoredMessage());
if (StaticConfiguration.SHOW_LOG_MESSAGES_IN_CHAT) {
for (var connection : Minosoft.CONNECTIONS.values()) {
connection.getSender().sendFakeChatMessage(message.getValue(), ChatTextPositions.CHAT_BOX);
}
}
// ToDo: log to file
}
}, "Log").start();
}
public static void log(LogLevels level, RGBColor color, Object message, Object... format) {
log(level, "", color, message, format);
}
public static void log(LogLevels level, Object message, Object... format) {
log(level, "", switch (level) {
case GAME -> ChatColors.GREEN;
case FATAL -> ChatColors.DARK_RED;
case WARNING -> ChatColors.RED;
case DEBUG -> ChatColors.GRAY;
case VERBOSE -> ChatColors.YELLOW;
case PROTOCOL -> ChatColors.BLUE;
case MOJANG -> ChatColors.AQUA;
case INFO -> ChatColors.WHITE;
}, message, format);
}
public static void log(LogLevels level, String prefix, RGBColor color, Object message, Object... format) {
if (level.ordinal() > Log.level.ordinal()) {
// log level too low
return;
}
if (message == null) {
return;
}
if (message instanceof String string) {
if (string.isBlank()) {
return;
}
if (format.length > 0) {
message = String.format(string, format);
}
}
StringBuilder builder = new StringBuilder();
builder.append("[");
if (StaticConfiguration.LOG_RELATIVE_TIME) {
builder.append(System.currentTimeMillis() - MINOSOFT_START_TIME);
} else {
builder.append(TIME_FORMAT.format(System.currentTimeMillis()));
}
builder.append("] [");
builder.append(Thread.currentThread().getName());
builder.append("] [");
builder.append(level.name());
builder.append("] ");
builder.append(prefix);
var component = (BaseComponent) ChatComponent.Companion.valueOf(builder.toString());
var messageComponent = (BaseComponent) ChatComponent.Companion.valueOf(message);
if (color != null && StaticConfiguration.COLORED_LOG) {
messageComponent.applyDefaultColor(color);
}
LOG_QUEUE.add(new Pair<>(component, messageComponent));
}
/**
* Logs all game related things (mostly visible stuff to the user)
*
* @param message Raw message to log
*/
public static void game(Object message, Object... format) {
log(LogLevels.GAME, message, format);
}
/**
* Logs all fatal errors (critical exceptions, etc)
*
* @param message Raw message to log
*/
public static void fatal(Object message, Object... format) {
log(LogLevels.FATAL, message, format);
}
/**
* Logs all warnings (error occurrence, ...)
*
* @param message Raw message to log
*/
public static void warn(Object message, Object... format) {
log(LogLevels.WARNING, message, format);
}
/**
* Logs way more data (data that might be important for resolving issues)
*
* @param message Raw message to log
*/
public static void debug(Object message, Object... format) {
log(LogLevels.DEBUG, message, format);
}
/**
* Logs all debug relevant infos (even higher level!) (connection status, ...). Basically everything that happens
*
* @param message Raw message to log
*/
public static void verbose(Object message, Object... format) {
log(LogLevels.VERBOSE, message, format);
}
/**
* Logs all protocol data (received packet x with data, etc). Should only be used in packets
*
* @param message Raw message to log
*/
public static void protocol(Object message, Object... format) {
log(LogLevels.PROTOCOL, message, format);
}
/**
* Logs all infos (mostly warnings) from data transfer to the mojang api (failed to login, etc)
*
* @param message Raw message to log
*/
public static void mojang(Object message, Object... format) {
log(LogLevels.MOJANG, message, format);
}
/**
* Logs all general infos, that are more or less important to the user (connecting to server, ...)
*
* @param message Raw message to log
*/
public static void info(Object message, Object... format) {
log(LogLevels.INFO, message, format);
}
public static LogLevels getLevel() {
return level;
}
public static void setLevel(LogLevels level) {
if (Log.level == level) {
return;
}
info(String.format("Log level changed from %s to %s", Log.level, level));
Log.level = level;
}
public static boolean printException(Throwable exception, LogLevels minimumLogLevel) {
// ToDo: log to file, print also exceptions that are not printed with this method
if (getLevel().ordinal() >= minimumLogLevel.ordinal()) {
exception.printStackTrace();
return true;
}
return false;
}
public static boolean printException(Exception exception) {
return printException(exception, LogLevels.FATAL); // always print
}
}

View File

@ -0,0 +1,172 @@
/*
* 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.util.logging
import com.google.errorprone.annotations.DoNotCall
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.config.StaticConfiguration
import de.bixilon.minosoft.data.text.BaseComponent
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.text.TextComponent
import java.io.PrintStream
import java.io.PrintWriter
import java.io.StringWriter
import java.text.SimpleDateFormat
import java.util.concurrent.LinkedBlockingQueue
object Log {
private val MINOSOFT_START_TIME = System.currentTimeMillis()
private val TIME_FORMAT = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
private val LOG_QUEUE = LinkedBlockingQueue<MessageToSend>()
private val SYSTEM_ERR_STREAM = System.err
private val SYSTEM_OUT_STREAM = System.out
private val ERROR_PRINT_STREAM: PrintStream = LogPrintStream(LogMessageType.OTHER_ERROR)
private val OUT_PRINT_STREAM: PrintStream = LogPrintStream(LogMessageType.OTHER_INFO)
init {
if (StaticConfiguration.REPLACE_SYSTEM_OUT_STREAMS) {
System.setErr(ERROR_PRINT_STREAM)
System.setOut(OUT_PRINT_STREAM)
}
Thread({
while (true) {
val messageToSend = LOG_QUEUE.take()
try {
val message = BaseComponent()
message.parts.add(TextComponent("[${TIME_FORMAT.format(messageToSend.time)}] "))
message.parts.add(TextComponent("[${messageToSend.thread.name}] "))
message.parts.add(TextComponent("[${messageToSend.logMessageType}] "))
messageToSend.additionalPrefix?.let {
message.parts.add(it)
}
message.parts.add(messageToSend.message)
message.applyDefaultColor(messageToSend.logMessageType.color)
val stream = if (messageToSend.logMessageType.error) {
SYSTEM_ERR_STREAM
} else {
SYSTEM_OUT_STREAM
}
stream.println(message.ansiColoredMessage)
} catch (exception: Throwable) {
SYSTEM_ERR_STREAM.println("Can not send log message $messageToSend!")
}
}
}, "Log").start()
}
@DoNotCall
@JvmOverloads
@JvmStatic
fun log(logMessageType: LogMessageType, additionalPrefix: ChatComponent? = null, message: Any, vararg formatting: Any) {
if (Minosoft.config != null && !Minosoft.config.config.general.enabledLogTypes.contains(logMessageType)) {
return
}
val formattedMessage = when (message) {
is ChatComponent -> message
is Throwable -> {
val stringWriter = StringWriter()
message.printStackTrace(PrintWriter(stringWriter))
ChatComponent.valueOf(raw = stringWriter.toString())
}
is String -> ChatComponent.valueOf(raw = message.format(*formatting))
else -> ChatComponent.valueOf(raw = message)
}
LOG_QUEUE.add(
MessageToSend(
message = formattedMessage,
time = System.currentTimeMillis(),
logMessageType = logMessageType,
thread = Thread.currentThread(),
additionalPrefix = additionalPrefix,
)
)
}
@JvmStatic
fun log(logMessageType: LogMessageType, additionalPrefix: ChatComponent? = null, messageBuilder: () -> Any) {
if (!Minosoft.config.config.general.enabledLogTypes.contains(logMessageType)) {
return
}
log(logMessageType, additionalPrefix, messageBuilder.invoke())
}
@JvmStatic
fun log(logMessageType: LogMessageType, messageBuilder: () -> Any) {
log(logMessageType, additionalPrefix = null, messageBuilder = messageBuilder)
}
@Deprecated(message = "Java only", replaceWith = ReplaceWith("log(logMessageType, message = exception)", "de.bixilon.minosoft.util.logging.Log.log"))
@JvmStatic
fun printException(exception: Throwable, logMessageType: LogMessageType) {
log(logMessageType, message = exception)
}
@Deprecated(message = "Java only", replaceWith = ReplaceWith("log(LogMessageType.OTHER_FATAL, message = message, formatting = formatting)", "de.bixilon.minosoft.util.logging.Log.log"))
@JvmStatic
fun fatal(message: Any, vararg formatting: Any) {
log(LogMessageType.OTHER_FATAL, message = message, formatting = formatting)
}
@Deprecated(message = "Java only", replaceWith = ReplaceWith("log(LogMessageType.OTHER_ERROR, message = message, formatting = formatting)", "de.bixilon.minosoft.util.logging.Log.log"))
@JvmStatic
fun error(message: Any, vararg formatting: Any) {
log(LogMessageType.OTHER_ERROR, message = message, formatting = formatting)
}
@Deprecated(message = "Java only", replaceWith = ReplaceWith("log(LogMessageType.OTHER_INFO, message = message, formatting = formatting)", "de.bixilon.minosoft.util.logging.Log.log"))
@JvmStatic
fun info(message: Any, vararg formatting: Any) {
log(LogMessageType.OTHER_INFO, message = message, formatting = formatting)
}
@Deprecated(message = "Java only", replaceWith = ReplaceWith("log(LogMessageType.OTHER_DEBUG, message = message, formatting = formatting)", "de.bixilon.minosoft.util.logging.Log.log"))
@JvmStatic
fun debug(message: Any, vararg formatting: Any) {
log(LogMessageType.OTHER_DEBUG, message = message, formatting = formatting)
}
@Deprecated(message = "Java only", replaceWith = ReplaceWith("log(LogMessageType.OTHER_DEBUG, message = message, formatting = formatting)", "de.bixilon.minosoft.util.logging.Log.log"))
@JvmStatic
fun verbose(message: Any, vararg formatting: Any) {
log(LogMessageType.OTHER_DEBUG, message = message, formatting = formatting)
}
@Deprecated(message = "Java only", replaceWith = ReplaceWith("log(LogMessageType.NETWORK_PACKETS_IN, message = message, formatting = formatting)", "de.bixilon.minosoft.util.logging.Log.log"))
@JvmStatic
fun protocol(message: Any, vararg formatting: Any) {
log(LogMessageType.NETWORK_PACKETS_IN, message = message, formatting = formatting)
}
@Deprecated(message = "Java only", replaceWith = ReplaceWith("log(LogMessageType.OTHER_ERROR, message = message, formatting = formatting)", "de.bixilon.minosoft.util.logging.Log.log"))
@JvmStatic
fun warn(message: Any, vararg formatting: Any) {
log(LogMessageType.OTHER_ERROR, message = message, formatting = formatting)
}
@Deprecated(message = "Java only", replaceWith = ReplaceWith("log(LogMessageType.OTHER_INFO, message = message, formatting = formatting)", "de.bixilon.minosoft.util.logging.Log.log"))
@JvmStatic
fun game(message: Any, vararg formatting: Any) {
log(LogMessageType.OTHER_INFO, message = message, formatting = formatting)
}
@Deprecated(message = "Java only", replaceWith = ReplaceWith("log(LogMessageType.OTHER_INFO, message = message, formatting = formatting)", "de.bixilon.minosoft.util.logging.Log.log"))
@JvmStatic
fun mojang(message: Any, vararg formatting: Any) {
log(LogMessageType.OTHER_INFO, message = message, formatting = formatting)
}
}

View File

@ -0,0 +1,64 @@
/*
* 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.util.logging
import de.bixilon.minosoft.data.text.ChatColors
import de.bixilon.minosoft.data.text.RGBColor
import de.bixilon.minosoft.util.KUtil
import de.bixilon.minosoft.util.enum.ValuesEnum
enum class LogMessageType(
val color: RGBColor,
val enabledDefault: Boolean = true,
val error: Boolean = false,
) {
GENERAL(ChatColors.WHITE),
MOD_LOADING(ChatColors.GOLD),
JAVAFX(ChatColors.DARK_GRAY),
VERSION_LOADING(ChatColors.YELLOW),
NETWORK_RESOLVING(ChatColors.DARK_GREEN),
NETWORK_STATUS(ChatColors.DARK_GREEN, enabledDefault = false),
NETWORK_PACKETS_IN(ChatColors.BLUE, enabledDefault = false),
NETWORK_PACKETS_IN_ERROR(ChatColors.RED, error = true),
NETWORK_PACKETS_OUT(ChatColors.DARK_AQUA, enabledDefault = false),
RENDERING_GENERAL(ChatColors.GREEN),
RENDERING_LOADING(ChatColors.GREEN),
CHAT_IN(ChatColors.LIGHT_PURPLE),
CHAT_OUT(ChatColors.LIGHT_PURPLE),
OTHER_INFO(ChatColors.WHITE),
OTHER_DEBUG(ChatColors.YELLOW),
OTHER_ERROR(ChatColors.RED, error = true),
OTHER_FATAL(ChatColors.DARK_RED, error = true),
;
companion object : ValuesEnum<LogMessageType> {
override val VALUES: Array<LogMessageType> = values()
override val NAME_MAP: Map<String, LogMessageType> = KUtil.getEnumValues(VALUES)
val DEFAULT_LOG_MESSAGE_TYPES = let {
val ret: MutableSet<LogMessageType> = mutableSetOf()
for (value in VALUES) {
if (value.enabledDefault) {
ret += value
}
}
ret.toSet()
}
}
}

View File

@ -10,16 +10,13 @@
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.util.logging
package de.bixilon.minosoft.util.logging;
import java.io.PrintStream
public enum LogLevels {
FATAL,
INFO,
MOJANG,
WARNING,
GAME,
DEBUG,
VERBOSE,
PROTOCOL
class LogPrintStream(private val level: LogMessageType) : PrintStream(nullOutputStream()) {
override fun print(string: String) {
Log.log(message = string, logMessageType = level)
}
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
* Copyright (C) 2021 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.
*
@ -11,22 +11,14 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.util.logging;
package de.bixilon.minosoft.util.logging
import java.io.OutputStream;
import java.io.PrintStream;
import de.bixilon.minosoft.data.text.ChatComponent
public class LogPrintStream extends PrintStream {
private final LogLevels level;
public LogPrintStream(LogLevels level) {
super(OutputStream.nullOutputStream());
this.level = level;
}
@Override
public void print(String s) {
Log.log(this.level, s);
}
}
data class MessageToSend(
val message: ChatComponent,
val time: Long,
val logMessageType: LogMessageType,
val thread: Thread,
val additionalPrefix: ChatComponent? = null,
)

View File

@ -21,7 +21,7 @@ import de.bixilon.minosoft.data.accounts.MojangAccount;
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition;
import de.bixilon.minosoft.util.HTTP;
import de.bixilon.minosoft.util.logging.Log;
import de.bixilon.minosoft.util.logging.LogLevels;
import de.bixilon.minosoft.util.logging.LogMessageType;
import de.bixilon.minosoft.util.mojang.api.exceptions.AuthenticationException;
import de.bixilon.minosoft.util.mojang.api.exceptions.MojangJoinServerErrorException;
import de.bixilon.minosoft.util.mojang.api.exceptions.NoNetworkConnectionException;
@ -51,7 +51,7 @@ public final class MojangAuthentication {
try {
response = HTTP.postJson(ProtocolDefinition.MOJANG_URL_LOGIN, payload);
} catch (IOException | InterruptedException e) {
Log.printException(e, LogLevels.DEBUG);
Log.printException(e, LogMessageType.OTHER_INFO);
throw new NoNetworkConnectionException(e);
}
if (response == null) {

View File

@ -11,9 +11,7 @@
~
~ This software is not affiliated with Mojang AB, the original developer of Minecraft.
-->
<?import com.jfoenix.controls.JFXComboBox?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.*?>
@ -32,8 +30,6 @@
<RowConstraints />
<RowConstraints />
</rowConstraints>
<Label fx:id="generalLogLevelLabel" text="-Log level-" />
<JFXComboBox fx:id="generalLogLevel" prefWidth="150.0" GridPane.columnIndex="1"/>
</GridPane>
</Tab>
<Tab disable="true" fx:id="download" text="Download">