mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 10:25:06 -04:00
lower java version requirement to 14
This commit is contained in:
parent
024beb36b5
commit
85d88d4578
@ -28,7 +28,7 @@ Minosoft is an open source minecraft client, written from scratch in kotlin (and
|
|||||||
- RAM: ~500Mib. With overhead, etc 2Gib recommended
|
- RAM: ~500Mib. With overhead, etc 2Gib recommended
|
||||||
- Disk space: Minosoft itself is pretty small (2-3 Mib), the libraries are a bit bigger. You also need to have the "normal" minecraft assets (~ 300 MB for one version).
|
- Disk space: Minosoft itself is pretty small (2-3 Mib), the libraries are a bit bigger. You also need to have the "normal" minecraft assets (~ 300 MB for one version).
|
||||||
- GPU: OpenGL 3.3+. Every moden GPU works and is recommended.
|
- GPU: OpenGL 3.3+. Every moden GPU works and is recommended.
|
||||||
- Java 16 (This is really important, we use features that are only available in this version. Java 8 is currently **not** supported).
|
- Java 14+, 16 recommended (This is really important, we use features that are only available in this version. Java 8 is currently **not** supported).
|
||||||
|
|
||||||
## Rendering
|
## Rendering
|
||||||
|
|
||||||
|
@ -116,13 +116,13 @@ public abstract class CommandNode {
|
|||||||
if (stringReader.getRemainingLength() == 0) {
|
if (stringReader.getRemainingLength() == 0) {
|
||||||
if (this.isExecutable) {
|
if (this.isExecutable) {
|
||||||
if (this.executor != null) {
|
if (this.executor != null) {
|
||||||
if (this.executor instanceof CommandExecutor commandExecutor) {
|
if (this.executor instanceof CommandExecutor) {
|
||||||
commandExecutor.execute(stack);
|
((CommandExecutor) this.executor).execute(stack);
|
||||||
} else if (this.executor instanceof CommandConnectionExecutor commandConnectionExecutor) {
|
} else if (this.executor instanceof CommandConnectionExecutor) {
|
||||||
if (connection == null) {
|
if (connection == null) {
|
||||||
throw new NoConnectionCommandParseException(stringReader, stringReader.getString());
|
throw new NoConnectionCommandParseException(stringReader, stringReader.getString());
|
||||||
}
|
}
|
||||||
commandConnectionExecutor.execute(connection, stack);
|
((CommandConnectionExecutor) this.executor).execute(connection, stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,11 +171,12 @@ public abstract class CommandNode {
|
|||||||
|
|
||||||
public CommandNode addChildren(Set<CommandNode> children) {
|
public CommandNode addChildren(Set<CommandNode> children) {
|
||||||
for (CommandNode child : children) {
|
for (CommandNode child : children) {
|
||||||
if (child instanceof CommandArgumentNode argumentNode) {
|
if (child instanceof CommandArgumentNode) {
|
||||||
this.argumentsChildren.add(argumentNode);
|
this.argumentsChildren.add(((CommandArgumentNode) child));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (child instanceof CommandLiteralNode literalNode) {
|
if (child instanceof CommandLiteralNode) {
|
||||||
|
CommandLiteralNode literalNode = (CommandLiteralNode) child;
|
||||||
this.literalChildren.put(literalNode.getName(), literalNode);
|
this.literalChildren.put(literalNode.getName(), literalNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,36 +10,25 @@
|
|||||||
*
|
*
|
||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
package de.bixilon.minosoft.data.mappings
|
||||||
|
|
||||||
package de.bixilon.minosoft.data.mappings;
|
class LegacyResourceLocation(resourceLocation: String) : ResourceLocation("", resourceLocation) {
|
||||||
|
override val full: String = path
|
||||||
|
|
||||||
public class LegacyResourceLocation extends ResourceLocation {
|
override fun hashCode(): Int {
|
||||||
|
return this.path.hashCode()
|
||||||
public LegacyResourceLocation(String resourceLocation) {
|
|
||||||
super(null, resourceLocation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun equals(other: Any?): Boolean {
|
||||||
public String getFull() {
|
if (other === this) {
|
||||||
return getPath();
|
return true
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return this.path.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (super.equals(obj)) {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
if (hashCode() != obj.hashCode()) {
|
if (hashCode() != other.hashCode()) {
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
if (obj instanceof ResourceLocation legacyResourceLocation) {
|
if (other !is ResourceLocation) {
|
||||||
return getPath().equals(legacyResourceLocation.getPath());
|
return false
|
||||||
}
|
}
|
||||||
return false;
|
return path == other.path
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,107 +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.data.mappings;
|
|
||||||
|
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition;
|
|
||||||
import de.bixilon.minosoft.util.Util;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class ResourceLocation implements Comparable<ResourceLocation> {
|
|
||||||
public final String full;
|
|
||||||
protected final String namespace;
|
|
||||||
protected final String path;
|
|
||||||
|
|
||||||
public ResourceLocation(String namespace, String path) {
|
|
||||||
this.namespace = namespace;
|
|
||||||
this.path = path;
|
|
||||||
this.full = namespace + ":" + path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResourceLocation(String full) {
|
|
||||||
String[] split = full.split(":");
|
|
||||||
if (split.length == 1) {
|
|
||||||
this.namespace = ProtocolDefinition.DEFAULT_NAMESPACE;
|
|
||||||
this.path = full;
|
|
||||||
} else {
|
|
||||||
this.namespace = split[0];
|
|
||||||
this.path = split[1];
|
|
||||||
}
|
|
||||||
this.full = this.namespace + ":" + this.path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ResourceLocation getResourceLocation(String resourceLocation) throws IllegalArgumentException {
|
|
||||||
// if (!ProtocolDefinition.RESOURCE_LOCATION_PATTERN.matcher(resourceLocation).matches()) {
|
|
||||||
// throw new IllegalArgumentException(String.format("%s in not a valid resource location!", resourceLocation));
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (Util.doesStringContainsUppercaseLetters(resourceLocation)) {
|
|
||||||
// just a string but wrapped into a resourceLocation (like old plugin channels MC|BRAND or ...)
|
|
||||||
return new LegacyResourceLocation(resourceLocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ResourceLocation(resourceLocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ResourceLocation getPathResourceLocation(String resourceLocation) {
|
|
||||||
if (resourceLocation.contains(":")) {
|
|
||||||
return new ResourceLocation(resourceLocation);
|
|
||||||
}
|
|
||||||
String[] split = resourceLocation.split("/", 2);
|
|
||||||
return new ResourceLocation(split[0], split[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNamespace() {
|
|
||||||
return this.namespace;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPath() {
|
|
||||||
return this.path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFull() {
|
|
||||||
return this.full;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(this.namespace, this.path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (super.equals(obj)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (hashCode() != obj.hashCode()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (obj instanceof LegacyResourceLocation legacyModIdentifier) {
|
|
||||||
return getPath().equals(legacyModIdentifier.getPath());
|
|
||||||
}
|
|
||||||
ResourceLocation their = (ResourceLocation) obj;
|
|
||||||
return getPath().equals(their.getPath()) && getNamespace().equals(their.getNamespace());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return getFull();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(@NotNull ResourceLocation resourceLocation) {
|
|
||||||
return resourceLocation.hashCode() - this.hashCode();
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* 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.data.mappings
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
|
import de.bixilon.minosoft.util.Util
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
open class ResourceLocation(
|
||||||
|
val namespace: String = ProtocolDefinition.DEFAULT_NAMESPACE,
|
||||||
|
val path: String,
|
||||||
|
) : Comparable<ResourceLocation> { // compare is for moshi
|
||||||
|
open val full: String = "$namespace:$path"
|
||||||
|
|
||||||
|
constructor(full: String) : this(full.namespace, full.path)
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return Objects.hash(namespace, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (other === this) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (hashCode() != other.hashCode()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (other is LegacyResourceLocation) {
|
||||||
|
return path == other.path
|
||||||
|
}
|
||||||
|
if (other !is ResourceLocation) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return path == other.path && namespace == other.namespace
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return full
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val String.namespace: String
|
||||||
|
get() {
|
||||||
|
val split = this.split(':', limit = 2)
|
||||||
|
if (split.size == 1) {
|
||||||
|
return ProtocolDefinition.DEFAULT_NAMESPACE
|
||||||
|
}
|
||||||
|
return split[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
val String.path: String
|
||||||
|
get() {
|
||||||
|
val split = this.split(':', limit = 2)
|
||||||
|
if (split.size == 1) {
|
||||||
|
return split[0]
|
||||||
|
}
|
||||||
|
return split[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getResourceLocation(resourceLocation: String): ResourceLocation {
|
||||||
|
// if (!ProtocolDefinition.RESOURCE_LOCATION_PATTERN.matcher(resourceLocation).matches()) {
|
||||||
|
// throw new IllegalArgumentException(String.format("%s in not a valid resource location!", resourceLocation));
|
||||||
|
// }
|
||||||
|
return if (Util.doesStringContainsUppercaseLetters(resourceLocation)) {
|
||||||
|
// just a string but wrapped into a resourceLocation (like old plugin channels MC|BRAND or ...)
|
||||||
|
LegacyResourceLocation(resourceLocation)
|
||||||
|
} else ResourceLocation(resourceLocation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPathResourceLocation(resourceLocation: String): ResourceLocation {
|
||||||
|
if (resourceLocation.contains(":")) {
|
||||||
|
return ResourceLocation(resourceLocation)
|
||||||
|
}
|
||||||
|
val split = resourceLocation.split("/".toRegex(), 2).toTypedArray()
|
||||||
|
return ResourceLocation(split[0], split[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun compareTo(other: ResourceLocation): Int {
|
||||||
|
return hashCode() - other.hashCode()
|
||||||
|
}
|
||||||
|
}
|
@ -62,7 +62,16 @@ public class HoverEvent {
|
|||||||
SHOW_ACHIEVEMENT
|
SHOW_ACHIEVEMENT
|
||||||
}
|
}
|
||||||
|
|
||||||
public static record EntityHoverData(UUID uuid, ResourceLocation resourceLocation, ChatComponent name) {
|
public static final class EntityHoverData {
|
||||||
|
private final UUID uuid;
|
||||||
|
private final ResourceLocation resourceLocation;
|
||||||
|
private final ChatComponent name;
|
||||||
|
|
||||||
|
public EntityHoverData(UUID uuid, ResourceLocation resourceLocation, ChatComponent name) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.resourceLocation = resourceLocation;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
public static EntityHoverData deserialize(JsonElement data) {
|
public static EntityHoverData deserialize(JsonElement data) {
|
||||||
JsonObject json;
|
JsonObject json;
|
||||||
@ -81,5 +90,17 @@ public class HoverEvent {
|
|||||||
}
|
}
|
||||||
return new EntityHoverData(Util.getUUIDFromString(json.get("id").getAsString()), type, ChatComponent.Companion.of(json.get("name")));
|
return new EntityHoverData(Util.getUUIDFromString(json.get("id").getAsString()), type, ChatComponent.Companion.of(json.get("name")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UUID uuid() {
|
||||||
|
return this.uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceLocation resourceLocation() {
|
||||||
|
return this.resourceLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChatComponent name() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,8 +75,8 @@ public class GUITools {
|
|||||||
|
|
||||||
public static Scene initializeScene(Scene scene) {
|
public static Scene initializeScene(Scene scene) {
|
||||||
scene.getStylesheets().add("/assets/minosoft/layout/style.css"); // ToDo: Migrate to minosoft assets manager
|
scene.getStylesheets().add("/assets/minosoft/layout/style.css"); // ToDo: Migrate to minosoft assets manager
|
||||||
if (scene.getWindow() instanceof Stage stage) {
|
if (scene.getWindow() instanceof Stage) {
|
||||||
stage.getIcons().add(MINOSOFT_LOGO);
|
((Stage) scene.getWindow()).getIcons().add(MINOSOFT_LOGO);
|
||||||
}
|
}
|
||||||
return scene;
|
return scene;
|
||||||
}
|
}
|
||||||
@ -93,7 +93,8 @@ public class GUITools {
|
|||||||
stage.initModality(modality);
|
stage.initModality(modality);
|
||||||
double width = 600;
|
double width = 600;
|
||||||
double height = 400;
|
double height = 400;
|
||||||
if (root instanceof Pane pane) {
|
if (root instanceof Pane) {
|
||||||
|
Pane pane = (Pane) root;
|
||||||
width = pane.getPrefWidth();
|
width = pane.getPrefWidth();
|
||||||
height = pane.getPrefHeight();
|
height = pane.getPrefHeight();
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import de.bixilon.minosoft.data.mappings.particle.data.ParticleData
|
|||||||
import de.bixilon.minosoft.gui.rendering.particle.ParticleFactory
|
import de.bixilon.minosoft.gui.rendering.particle.ParticleFactory
|
||||||
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
|
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.ExplosionParticle
|
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.ExplosionParticle
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
|
||||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||||
import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
@ -33,11 +34,8 @@ class ExplosionEmitterParticle(connection: PlayConnection, particleRenderer: Par
|
|||||||
override fun realTick() {
|
override fun realTick() {
|
||||||
super.realTick()
|
super.realTick()
|
||||||
for (i in 0 until 6) {
|
for (i in 0 until 6) {
|
||||||
val position = Vec3(
|
val position = position + { (random.nextFloat() - random.nextFloat()) * 4.0f }
|
||||||
x = position.x + (random.nextFloat() - random.nextFloat()) * 4.0f,
|
|
||||||
y = position.y + (random.nextFloat() - random.nextFloat()) * 4.0f,
|
|
||||||
z = position.z + (random.nextFloat() - random.nextFloat()) * 4.0f
|
|
||||||
)
|
|
||||||
particleRenderer.add(ExplosionParticle(connection, particleRenderer, position, explosionParticleType.simple(), (tickAge.toFloat() / maxTickAge)))
|
particleRenderer.add(ExplosionParticle(connection, particleRenderer, position, explosionParticleType.simple(), (tickAge.toFloat() / maxTickAge)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,14 @@ object VecUtil {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
infix operator fun Vec3.plus(lambda: () -> Float): Vec3 {
|
||||||
|
return Vec3(
|
||||||
|
x = x + lambda(),
|
||||||
|
y = y + lambda(),
|
||||||
|
z = z + lambda(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun getRotatedValues(x: Float, y: Float, sin: Float, cos: Float, rescale: Boolean): Vec2 {
|
fun getRotatedValues(x: Float, y: Float, sin: Float, cos: Float, rescale: Boolean): Vec2 {
|
||||||
val result = Vec2(x * cos - y * sin, x * sin + y * cos)
|
val result = Vec2(x * cos - y * sin, x * sin + y * cos)
|
||||||
if (rescale) {
|
if (rescale) {
|
||||||
|
@ -199,9 +199,9 @@ public class BlockingSocketNetwork extends Network {
|
|||||||
|
|
||||||
this.outputStream.write(prepareC2SPacket(packet));
|
this.outputStream.write(prepareC2SPacket(packet));
|
||||||
this.outputStream.flush();
|
this.outputStream.flush();
|
||||||
if (packet instanceof EncryptionResponseC2SP packetEncryptionResponse) {
|
if (packet instanceof EncryptionResponseC2SP) {
|
||||||
// enable encryption
|
// enable encryption
|
||||||
enableEncryption(packetEncryptionResponse.getSecretKey());
|
enableEncryption(((EncryptionResponseC2SP) packet).getSecretKey());
|
||||||
// wake up other thread
|
// wake up other thread
|
||||||
this.socketReceiveThread.interrupt();
|
this.socketReceiveThread.interrupt();
|
||||||
}
|
}
|
||||||
|
@ -89,9 +89,9 @@ public class NonBlockingSocketNetwork extends Network {
|
|||||||
this.socketChannel.write(sendBuffer);
|
this.socketChannel.write(sendBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet instanceof EncryptionResponseC2SP packetEncryptionResponse) {
|
if (packet instanceof EncryptionResponseC2SP) {
|
||||||
// enable encryption
|
// enable encryption
|
||||||
enableEncryption(packetEncryptionResponse.getSecretKey());
|
enableEncryption(((EncryptionResponseC2SP) packet).getSecretKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user