rendering: wip: save key binding in config file

* Config changes
* Important: This breaks all previous config files
This commit is contained in:
Bixilon 2021-02-17 19:51:28 +01:00
parent cd8c7beacc
commit 14de7ff6e5
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
10 changed files with 588 additions and 52 deletions

View File

@ -15,10 +15,12 @@ package de.bixilon.minosoft.config;
import com.google.common.collect.HashBiMap;
import com.google.gson.*;
import de.bixilon.minosoft.config.key.KeyBinding;
import de.bixilon.minosoft.data.accounts.Account;
import de.bixilon.minosoft.data.accounts.MicrosoftAccount;
import de.bixilon.minosoft.data.accounts.MojangAccount;
import de.bixilon.minosoft.data.accounts.OfflineAccount;
import de.bixilon.minosoft.data.mappings.ModIdentifier;
import de.bixilon.minosoft.gui.main.Server;
import de.bixilon.minosoft.util.Util;
import de.bixilon.minosoft.util.logging.Log;
@ -35,6 +37,7 @@ public class Configuration {
private final HashMap<ConfigurationPaths.ConfigurationPath, Object> config = new HashMap<>();
private final HashBiMap<String, Account> accountList = HashBiMap.create();
private final HashBiMap<Integer, Server> serverList = HashBiMap.create();
private final HashBiMap<ModIdentifier, KeyBinding> keyBindings = HashBiMap.create();
private final Object lock = new Object();
public Configuration() throws IOException, ConfigMigrationException {
@ -84,6 +87,12 @@ public class Configuration {
this.accountList.put(account.getId(), account);
}
// key bindings
for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject("game").getAsJsonObject("key_bindings").entrySet()) {
final var identifier = ModIdentifier.getIdentifier(entry.getKey());
this.keyBindings.put(identifier, KeyBinding.Companion.deserialize(identifier, entry.getValue().getAsJsonObject()));
}
final File finalFile = file;
new Thread(() -> {
while (true) {
@ -119,6 +128,12 @@ public class Configuration {
accountsEntriesJson.add(entry.getKey(), entry.getValue().serialize());
}
// key combinations
JsonObject keyBindingsJson = jsonObject.getAsJsonObject("game").getAsJsonObject("key_bindings");
for (Map.Entry<ModIdentifier, KeyBinding> entry : this.keyBindings.entrySet()) {
keyBindingsJson.add(entry.getKey().getFullIdentifier(), entry.getValue().serialize());
}
// rest of data
for (ConfigurationPaths.ConfigurationPath path : ConfigurationPaths.ALL_PATHS) {
saveData(jsonObject, path, this.config.get(path));
@ -209,6 +224,10 @@ public class Configuration {
return this.accountList;
}
public HashBiMap<ModIdentifier, KeyBinding> getKeyBindings() {
return this.keyBindings;
}
private void migrateConfiguration() throws ConfigMigrationException {
int configVersion = getInt(ConfigurationPaths.IntegerPaths.GENERAL_CONFIG_VERSION);
Log.info(String.format("Migrating config from version %d to %d", configVersion, LATEST_CONFIG_VERSION));
@ -231,9 +250,9 @@ public class Configuration {
private Object getData(JsonObject json, ConfigurationPaths.ConfigurationPath path) {
if (path instanceof ConfigurationPaths.BooleanPaths booleanPath) {
return switch (booleanPath) {
case NETWORK_FAKE_CLIENT_BRAND -> json.getAsJsonObject("network").get("fake-network-brand").getAsBoolean();
case NETWORK_SHOW_LAN_SERVERS -> json.getAsJsonObject("network").get("show-lan-servers").getAsBoolean();
case DEBUG_VERIFY_ASSETS -> json.getAsJsonObject("debug").get("verify-assets").getAsBoolean();
case NETWORK_FAKE_CLIENT_BRAND -> json.getAsJsonObject("network").get("fake_network_brand").getAsBoolean();
case NETWORK_SHOW_LAN_SERVERS -> json.getAsJsonObject("network").get("show_lan_servers").getAsBoolean();
case DEBUG_VERIFY_ASSETS -> json.getAsJsonObject("debug").get("verify_assets").getAsBoolean();
case CHAT_COLORED -> json.getAsJsonObject("chat").get("colored").getAsBoolean();
case CHAT_OBFUSCATED -> json.getAsJsonObject("chat").get("obfuscated").getAsBoolean();
};
@ -241,16 +260,16 @@ public class Configuration {
if (path instanceof ConfigurationPaths.IntegerPaths integerPath) {
return switch (integerPath) {
case GENERAL_CONFIG_VERSION -> json.getAsJsonObject("general").get("version").getAsInt();
case GAME_RENDER_DISTANCE -> json.getAsJsonObject("game").get("render-distance").getAsInt();
case GAME_RENDER_DISTANCE -> json.getAsJsonObject("game").get("render_distance").getAsInt();
};
}
if (path instanceof ConfigurationPaths.StringPaths stringPath) {
return switch (stringPath) {
case ACCOUNT_SELECTED -> json.getAsJsonObject("accounts").get("selected").getAsString();
case GENERAL_LOG_LEVEL -> json.getAsJsonObject("general").get("log-level").getAsString();
case GENERAL_LOG_LEVEL -> json.getAsJsonObject("general").get("log_level").getAsString();
case GENERAL_LANGUAGE -> json.getAsJsonObject("general").get("language").getAsString();
case RESOURCES_URL -> json.getAsJsonObject("download").getAsJsonObject("urls").get("resources").getAsString();
case CLIENT_TOKEN -> json.getAsJsonObject("accounts").get("client-token").getAsString();
case CLIENT_TOKEN -> json.getAsJsonObject("accounts").get("client_token").getAsString();
};
}
throw new IllegalArgumentException();
@ -259,24 +278,24 @@ public class Configuration {
private void saveData(JsonObject input, ConfigurationPaths.ConfigurationPath path, Object data) {
if (data instanceof Boolean bool) {
switch ((ConfigurationPaths.BooleanPaths) path) {
case NETWORK_FAKE_CLIENT_BRAND -> input.getAsJsonObject("network").addProperty("fake-network-brand", bool);
case NETWORK_SHOW_LAN_SERVERS -> input.getAsJsonObject("network").addProperty("show-lan-servers", bool);
case DEBUG_VERIFY_ASSETS -> input.getAsJsonObject("debug").addProperty("verify-assets", bool);
case NETWORK_FAKE_CLIENT_BRAND -> input.getAsJsonObject("network").addProperty("fake_network_brand", bool);
case NETWORK_SHOW_LAN_SERVERS -> input.getAsJsonObject("network").addProperty("show_lan_servers", bool);
case DEBUG_VERIFY_ASSETS -> input.getAsJsonObject("debug").addProperty("verify_assets", bool);
case CHAT_COLORED -> input.getAsJsonObject("chat").addProperty("colored", bool);
case CHAT_OBFUSCATED -> input.getAsJsonObject("chat").addProperty("obfuscated", bool);
}
} else if (data instanceof Integer integer) {
switch ((ConfigurationPaths.IntegerPaths) path) {
case GENERAL_CONFIG_VERSION -> input.getAsJsonObject("general").addProperty("version", integer);
case GAME_RENDER_DISTANCE -> input.getAsJsonObject("game").addProperty("render-distance", integer);
case GAME_RENDER_DISTANCE -> input.getAsJsonObject("game").addProperty("render_distance", integer);
}
} else if (data instanceof String string) {
switch ((ConfigurationPaths.StringPaths) path) {
case ACCOUNT_SELECTED -> input.getAsJsonObject("accounts").addProperty("selected", string);
case GENERAL_LOG_LEVEL -> input.getAsJsonObject("general").addProperty("log-level", string);
case GENERAL_LOG_LEVEL -> input.getAsJsonObject("general").addProperty("log_level", string);
case GENERAL_LANGUAGE -> input.getAsJsonObject("general").addProperty("language", string);
case RESOURCES_URL -> input.getAsJsonObject("download").getAsJsonObject("urls").addProperty("resources", string);
case CLIENT_TOKEN -> input.getAsJsonObject("accounts").addProperty("client-token", string);
case CLIENT_TOKEN -> input.getAsJsonObject("accounts").addProperty("client_token", string);
}
} else {
throw new IllegalArgumentException();

View File

@ -0,0 +1,75 @@
package de.bixilon.minosoft.config.key
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import de.bixilon.minosoft.data.mappings.ModIdentifier
class KeyBinding(
val identifier: ModIdentifier,
val action: MutableMap<KeyAction, MutableSet<KeyCodes>>,
val `when`: MutableSet<MutableSet<ModIdentifier>>,
) {
fun serialize(): JsonObject {
val ret = JsonObject()
for ((keyEvent, keyCodes) in action) {
val keyEventArray = JsonArray()
for (keyCode in keyCodes) {
keyEventArray.add(keyCode.keyName.toUpperCase().replace(' ', '_'))
}
ret.add(keyEvent.name.toLowerCase(), keyEventArray)
}
val `when` = JsonArray()
for (whenIdentifierSet in this.`when`) {
val whenIdentifierArray = JsonArray()
for (whenIdentifier in whenIdentifierSet) {
whenIdentifierArray.add(whenIdentifier.fullIdentifier)
}
`when`.add(whenIdentifierArray)
}
ret.add("when", `when`)
return ret
}
companion object {
fun deserialize(identifier: ModIdentifier, json: JsonObject): KeyBinding {
val action: MutableMap<KeyAction, MutableSet<KeyCodes>> = mutableMapOf()
for (keyAction in KeyAction.VALUES) {
json[keyAction.name.toLowerCase()]?.asJsonArray?.let {
val keyCodes: MutableSet<KeyCodes> = mutableSetOf()
for (keyCode in it) {
keyCodes.add(KeyCodes.KEY_CODE_MAP[keyCode.asString.toUpperCase()]!!)
}
action[keyAction] = keyCodes
}
}
val `when`: MutableSet<MutableSet<ModIdentifier>> = mutableSetOf()
json["when"]?.asJsonArray?.let {
val currentWhenIdentifierSet: MutableSet<ModIdentifier> = mutableSetOf()
for (whenIdentifierJsonElementArray in it) {
val whenIdentifierArray = whenIdentifierJsonElementArray.asJsonArray
for (whenIdentifier in whenIdentifierArray) {
currentWhenIdentifierSet.add(ModIdentifier.getIdentifier(whenIdentifier.asString))
}
}
`when`.add(currentWhenIdentifierSet)
}
return KeyBinding(identifier, action, `when`)
}
}
enum class KeyAction {
MODIFIER,
CHANGE,
PRESS,
RELEASE,
DOUBLE_CLICK,
TOGGLE,
;
companion object {
val VALUES = values()
}
}
}

View File

@ -0,0 +1,168 @@
package de.bixilon.minosoft.config.key
import org.lwjgl.glfw.GLFW.*
enum class KeyCodes(val glfwKeyId: Int) {
KEY_UNKNOWN(GLFW_KEY_UNKNOWN),
KEY_SPACE(GLFW_KEY_SPACE),
KEY_APOSTROPHE(GLFW_KEY_APOSTROPHE),
KEY_COMMA(GLFW_KEY_COMMA),
KEY_MINUS(GLFW_KEY_MINUS),
KEY_PERIOD(GLFW_KEY_PERIOD),
KEY_SLASH(GLFW_KEY_SLASH),
KEY_0(GLFW_KEY_0),
KEY_1(GLFW_KEY_1),
KEY_2(GLFW_KEY_2),
KEY_3(GLFW_KEY_3),
KEY_4(GLFW_KEY_4),
KEY_5(GLFW_KEY_5),
KEY_6(GLFW_KEY_6),
KEY_7(GLFW_KEY_7),
KEY_8(GLFW_KEY_8),
KEY_9(GLFW_KEY_9),
KEY_SEMICOLON(GLFW_KEY_SEMICOLON),
KEY_EQUAL(GLFW_KEY_EQUAL),
KEY_A(GLFW_KEY_A),
KEY_B(GLFW_KEY_B),
KEY_C(GLFW_KEY_C),
KEY_D(GLFW_KEY_D),
KEY_E(GLFW_KEY_E),
KEY_F(GLFW_KEY_F),
KEY_G(GLFW_KEY_G),
KEY_H(GLFW_KEY_H),
KEY_I(GLFW_KEY_I),
KEY_J(GLFW_KEY_J),
KEY_K(GLFW_KEY_K),
KEY_L(GLFW_KEY_L),
KEY_M(GLFW_KEY_M),
KEY_N(GLFW_KEY_N),
KEY_O(GLFW_KEY_O),
KEY_P(GLFW_KEY_P),
KEY_Q(GLFW_KEY_Q),
KEY_R(GLFW_KEY_R),
KEY_S(GLFW_KEY_S),
KEY_T(GLFW_KEY_T),
KEY_U(GLFW_KEY_U),
KEY_V(GLFW_KEY_V),
KEY_W(GLFW_KEY_W),
KEY_X(GLFW_KEY_X),
KEY_Y(GLFW_KEY_Y),
KEY_Z(GLFW_KEY_Z),
KEY_LEFT_BRACKET(GLFW_KEY_LEFT_BRACKET),
KEY_BACKSLASH(GLFW_KEY_BACKSLASH),
KEY_RIGHT_BRACKET(GLFW_KEY_RIGHT_BRACKET),
KEY_GRAVE_ACCENT(GLFW_KEY_GRAVE_ACCENT),
KEY_WORLD_1(GLFW_KEY_WORLD_1),
KEY_WORLD_2(GLFW_KEY_WORLD_2),
KEY_ESCAPE(GLFW_KEY_ESCAPE),
KEY_ENTER(GLFW_KEY_ENTER),
KEY_TAB(GLFW_KEY_TAB),
KEY_BACKSPACE(GLFW_KEY_BACKSPACE),
KEY_INSERT(GLFW_KEY_INSERT),
KEY_DELETE(GLFW_KEY_DELETE),
KEY_RIGHT(GLFW_KEY_RIGHT),
KEY_LEFT(GLFW_KEY_LEFT),
KEY_DOWN(GLFW_KEY_DOWN),
KEY_UP(GLFW_KEY_UP),
KEY_PAGE_UP(GLFW_KEY_PAGE_UP),
KEY_PAGE_DOWN(GLFW_KEY_PAGE_DOWN),
KEY_HOME(GLFW_KEY_HOME),
KEY_END(GLFW_KEY_END),
KEY_CAPS_LOCK(GLFW_KEY_CAPS_LOCK),
KEY_SCROLL_LOCK(GLFW_KEY_SCROLL_LOCK),
KEY_NUM_LOCK(GLFW_KEY_NUM_LOCK),
KEY_PRINT_SCREEN(GLFW_KEY_PRINT_SCREEN),
KEY_PAUSE(GLFW_KEY_PAUSE),
KEY_F1(GLFW_KEY_F1),
KEY_F2(GLFW_KEY_F2),
KEY_F3(GLFW_KEY_F3),
KEY_F4(GLFW_KEY_F4),
KEY_F5(GLFW_KEY_F5),
KEY_F6(GLFW_KEY_F6),
KEY_F7(GLFW_KEY_F7),
KEY_F8(GLFW_KEY_F8),
KEY_F9(GLFW_KEY_F9),
KEY_F10(GLFW_KEY_F10),
KEY_F11(GLFW_KEY_F11),
KEY_F12(GLFW_KEY_F12),
KEY_F13(GLFW_KEY_F13),
KEY_F14(GLFW_KEY_F14),
KEY_F15(GLFW_KEY_F15),
KEY_F16(GLFW_KEY_F16),
KEY_F17(GLFW_KEY_F17),
KEY_F18(GLFW_KEY_F18),
KEY_F19(GLFW_KEY_F19),
KEY_F20(GLFW_KEY_F20),
KEY_F21(GLFW_KEY_F21),
KEY_F22(GLFW_KEY_F22),
KEY_F23(GLFW_KEY_F23),
KEY_F24(GLFW_KEY_F24),
KEY_F25(GLFW_KEY_F25),
KEY_KP_0(GLFW_KEY_KP_0),
KEY_KP_1(GLFW_KEY_KP_1),
KEY_KP_2(GLFW_KEY_KP_2),
KEY_KP_3(GLFW_KEY_KP_3),
KEY_KP_4(GLFW_KEY_KP_4),
KEY_KP_5(GLFW_KEY_KP_5),
KEY_KP_6(GLFW_KEY_KP_6),
KEY_KP_7(GLFW_KEY_KP_7),
KEY_KP_8(GLFW_KEY_KP_8),
KEY_KP_9(GLFW_KEY_KP_9),
KEY_KP_DECIMAL(GLFW_KEY_KP_DECIMAL),
KEY_KP_DIVIDE(GLFW_KEY_KP_DIVIDE),
KEY_KP_MULTIPLY(GLFW_KEY_KP_MULTIPLY),
KEY_KP_SUBTRACT(GLFW_KEY_KP_SUBTRACT),
KEY_KP_ADD(GLFW_KEY_KP_ADD),
KEY_KP_ENTER(GLFW_KEY_KP_ENTER),
KEY_KP_EQUAL(GLFW_KEY_KP_EQUAL),
KEY_LEFT_SHIFT(GLFW_KEY_LEFT_SHIFT),
KEY_LEFT_CONTROL(GLFW_KEY_LEFT_CONTROL),
KEY_LEFT_ALT(GLFW_KEY_LEFT_ALT),
KEY_LEFT_SUPER(GLFW_KEY_LEFT_SUPER),
KEY_RIGHT_SHIFT(GLFW_KEY_RIGHT_SHIFT),
KEY_RIGHT_CONTROL(GLFW_KEY_RIGHT_CONTROL),
KEY_RIGHT_ALT(GLFW_KEY_RIGHT_ALT),
KEY_RIGHT_SUPER(GLFW_KEY_RIGHT_SUPER),
KEY_MENU(GLFW_KEY_MENU),
KEY_LAST(GLFW_KEY_LAST),
MOUSE_BUTTON_1(GLFW_MOUSE_BUTTON_1),
MOUSE_BUTTON_2(GLFW_MOUSE_BUTTON_2),
MOUSE_BUTTON_3(GLFW_MOUSE_BUTTON_3),
MOUSE_BUTTON_4(GLFW_MOUSE_BUTTON_4),
MOUSE_BUTTON_5(GLFW_MOUSE_BUTTON_5),
MOUSE_BUTTON_6(GLFW_MOUSE_BUTTON_6),
MOUSE_BUTTON_7(GLFW_MOUSE_BUTTON_7),
MOUSE_BUTTON_8(GLFW_MOUSE_BUTTON_8),
MOUSE_BUTTON_LAST(GLFW_MOUSE_BUTTON_LAST),
MOUSE_BUTTON_LEFT(GLFW_MOUSE_BUTTON_LEFT),
MOUSE_BUTTON_RIGHT(GLFW_MOUSE_BUTTON_RIGHT),
MOUSE_BUTTON_MIDDLE(GLFW_MOUSE_BUTTON_MIDDLE),
;
val keyName = name.toUpperCase().removePrefix("KEY_")
companion object {
val VALUES = values()
val KEY_CODE_MAP: Map<String, KeyCodes>
val KEY_CODE_GLFW_ID_MAP: Map<Int, KeyCodes>
init {
val keyCodeMap: MutableMap<String, KeyCodes> = mutableMapOf()
val keyCodeGLFWIdMap: MutableMap<Int, KeyCodes> = mutableMapOf()
for (keyCode in VALUES) {
keyCodeMap[keyCode.keyName.toUpperCase().replace(' ', '_')] = keyCode
keyCodeGLFWIdMap[keyCode.glfwKeyId] = keyCode
}
KEY_CODE_MAP = keyCodeMap.toMap()
KEY_CODE_GLFW_ID_MAP = keyCodeGLFWIdMap.toMap()
}
}
}

View File

@ -23,6 +23,7 @@ import de.bixilon.minosoft.config.StaticConfiguration;
import de.bixilon.minosoft.data.mappings.ModIdentifier;
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition;
import de.bixilon.minosoft.util.CountUpAndDownLatch;
import de.bixilon.minosoft.util.GitInfo;
import de.bixilon.minosoft.util.Util;
import de.bixilon.minosoft.util.logging.Log;
@ -30,6 +31,7 @@ import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
@ -247,7 +249,13 @@ public class AssetsManager {
private void downloadAsset(AssetsSource source, String hash) throws IOException {
switch (source) {
case MINECRAFT -> downloadAsset(String.format(ProtocolDefinition.MINECRAFT_URL_RESOURCES, hash.substring(0, 2), hash), hash);
case MINOSOFT_GIT -> downloadAsset(String.format(Minosoft.getConfig().getString(ConfigurationPaths.StringPaths.RESOURCES_URL), hash.substring(0, 2), hash), hash, false);
case MINOSOFT_GIT -> downloadAsset(Util.formatString(
Minosoft.getConfig().getString(ConfigurationPaths.StringPaths.RESOURCES_URL),
Map.of(
"branch", GitInfo.INSTANCE.getGIT_BRANCH(),
"hashPrefix", hash.substring(0, 2),
"fullHash", hash)
), hash, false);
}
}

View File

@ -1,7 +1,10 @@
package de.bixilon.minosoft.gui.rendering
import de.bixilon.minosoft.config.key.KeyBinding
import de.bixilon.minosoft.config.key.KeyCodes
import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.data.entities.Location
import de.bixilon.minosoft.data.mappings.ModIdentifier
import de.bixilon.minosoft.gui.rendering.shader.Shader
import de.bixilon.minosoft.protocol.network.Connection
import de.bixilon.minosoft.protocol.packets.serverbound.play.PacketPlayerPositionAndRotationSending
@ -34,6 +37,14 @@ class Camera(private val connection: Connection, private var fov: Float, private
private var screenWidth = 0
private val shaders: MutableList<Shader> = mutableListOf()
private var keyForwardDown = false
private var keyLeftDown = false
private var keyRightDown = false
private var keyBackDown = false
private var keyFlyUp = false
private var keyFlyDown = false
private var keySprintDown = false
fun mouseCallback(xPos: Double, yPos: Double) {
var xOffset = xPos - this.lastMouseX
var yOffset = this.lastMouseY - yPos // reversed since y-coordinates go from bottom to top
@ -59,31 +70,55 @@ class Camera(private val connection: Connection, private var fov: Float, private
setRotation(yaw, pitch)
}
fun init(renderWindow: RenderWindow) {
renderWindow.registerKeyCallback(ModIdentifier("minosoft:move_forward")) { keyCodes: KeyCodes, keyAction: KeyBinding.KeyAction ->
keyForwardDown = keyAction == KeyBinding.KeyAction.PRESS
}
renderWindow.registerKeyCallback(ModIdentifier("minosoft:move_left")) { keyCodes: KeyCodes, keyAction: KeyBinding.KeyAction ->
keyLeftDown = keyAction == KeyBinding.KeyAction.PRESS
}
renderWindow.registerKeyCallback(ModIdentifier("minosoft:move_back")) { keyCodes: KeyCodes, keyAction: KeyBinding.KeyAction ->
keyBackDown = keyAction == KeyBinding.KeyAction.PRESS
}
renderWindow.registerKeyCallback(ModIdentifier("minosoft:move_right")) { keyCodes: KeyCodes, keyAction: KeyBinding.KeyAction ->
keyRightDown = keyAction == KeyBinding.KeyAction.PRESS
}
renderWindow.registerKeyCallback(ModIdentifier("minosoft:fly_up")) { keyCodes: KeyCodes, keyAction: KeyBinding.KeyAction ->
keyFlyUp = keyAction == KeyBinding.KeyAction.PRESS
}
renderWindow.registerKeyCallback(ModIdentifier("minosoft:fly_down")) { keyCodes: KeyCodes, keyAction: KeyBinding.KeyAction ->
keyFlyDown = keyAction == KeyBinding.KeyAction.PRESS
}
renderWindow.registerKeyCallback(ModIdentifier("minosoft:sprint")) { keyCodes: KeyCodes, keyAction: KeyBinding.KeyAction ->
keySprintDown = keyAction == KeyBinding.KeyAction.PRESS
}
}
fun handleInput(deltaTime: Double) {
var cameraSpeed = movementSpeed * deltaTime
if (glfwGetKey(windowId, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) {
if (keySprintDown) {
cameraSpeed *= 5
}
val lastPosition = cameraPosition
val currentY = cameraPosition.y
if (glfwGetKey(windowId, GLFW_KEY_W) == GLFW_PRESS) {
if (keyForwardDown) {
cameraPosition = cameraPosition + cameraFront * cameraSpeed
}
if (glfwGetKey(windowId, GLFW_KEY_S) == GLFW_PRESS) {
if (keyBackDown) {
cameraPosition = cameraPosition - cameraFront * cameraSpeed
}
if (glfwGetKey(windowId, GLFW_KEY_A) == GLFW_PRESS) {
if (keyLeftDown) {
cameraPosition = cameraPosition - cameraRight * cameraSpeed
}
if (glfwGetKey(windowId, GLFW_KEY_D) == GLFW_PRESS) {
if (keyRightDown) {
cameraPosition = cameraPosition + cameraRight * cameraSpeed
}
this.cameraPosition.y = currentY // stay on xz line when moving (aka. no clip): ToDo: make movement not slower when you look up
if (glfwGetKey(windowId, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) {
if (keyFlyDown) {
cameraPosition = cameraPosition - CAMERA_UP_VEC3 * cameraSpeed
}
if (glfwGetKey(windowId, GLFW_KEY_SPACE) == GLFW_PRESS) {
if (keyFlyUp) {
cameraPosition = cameraPosition + CAMERA_UP_VEC3 * cameraSpeed
}
if (lastPosition != cameraPosition) {

View File

@ -1,5 +1,10 @@
package de.bixilon.minosoft.gui.rendering
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.config.StaticConfiguration
import de.bixilon.minosoft.config.key.KeyBinding
import de.bixilon.minosoft.config.key.KeyCodes
import de.bixilon.minosoft.data.mappings.ModIdentifier
import de.bixilon.minosoft.gui.rendering.chunk.ChunkRenderer
import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer
import de.bixilon.minosoft.gui.rendering.hud.elements.RenderStats
@ -20,10 +25,12 @@ import org.lwjgl.system.MemoryUtil
import java.util.concurrent.ConcurrentLinkedQueue
class RenderWindow(private val connection: Connection, val rendering: Rendering) {
private val keyBindingCallbacks: MutableMap<ModIdentifier, Pair<KeyBinding, MutableSet<((keyCode: KeyCodes, keyEvent: KeyBinding.KeyAction) -> Unit)>>> = mutableMapOf()
private val keysDown: MutableSet<KeyCodes> = mutableSetOf()
private val keyBindingDown: MutableSet<KeyBinding> = mutableSetOf()
val renderStats = RenderStats()
var screenWidth = 900
var screenHeight = 500
private var polygonEnabled = false
private var windowId: Long = 0
private var deltaTime = 0.0 // time between current frame and last frame
@ -33,6 +40,9 @@ class RenderWindow(private val connection: Connection, val rendering: Rendering)
private var renderingStatus = RenderingStates.RUNNING
private var polygonEnabled = false
private var mouseCatch = !StaticConfiguration.DEBUG_MODE
// all renderers
val chunkRenderer: ChunkRenderer = ChunkRenderer(connection, connection.player.world, this)
val hudRenderer: HUDRenderer = HUDRenderer(connection, this)
@ -86,25 +96,84 @@ class RenderWindow(private val connection: Connection, val rendering: Rendering)
throw RuntimeException("Failed to create the GLFW window")
}
camera = Camera(connection, 60f, windowId)
camera.init(this)
glfwSetKeyCallback(this.windowId) { _: Long, key: Int, _: Int, action: Int, _: Int ->
run {
if (action != GLFW_RELEASE) {
return@run
}
when (key) {
GLFW_KEY_ESCAPE -> {
glfwSetWindowShouldClose(this.windowId, true)
val keyCode = KeyCodes.KEY_CODE_GLFW_ID_MAP[key] ?: KeyCodes.KEY_UNKNOWN
val keyAction = when (action) {
GLFW_PRESS -> KeyBinding.KeyAction.PRESS
GLFW_RELEASE -> KeyBinding.KeyAction.RELEASE
// ToDo: Double, Hold
else -> return@glfwSetKeyCallback
}
if (keyAction == KeyBinding.KeyAction.PRESS) {
keysDown.add(keyCode)
} else if (keyAction == KeyBinding.KeyAction.RELEASE) {
keysDown.remove(keyCode)
}
Log.verbose("Keycode $keyCode: $keyAction")
for ((identifier, keyCallbackPair) in keyBindingCallbacks) {
run {
val keyBinding = keyCallbackPair.first
val keyCallbacks = keyCallbackPair.second
var anyCheckRun = false
keyBinding.action[KeyBinding.KeyAction.MODIFIER]?.let {
val previousKeysDown = if (keyAction == KeyBinding.KeyAction.RELEASE) {
val previousKeysDown = keysDown.toMutableList()
previousKeysDown.add(keyCode)
previousKeysDown
} else {
keysDown
}
if (!previousKeysDown.containsAll(it)) {
return@run
}
anyCheckRun = true
}
GLFW_KEY_P -> {
switchPolygonMode()
keyBinding.action[KeyBinding.KeyAction.CHANGE]?.let {
if (!it.contains(keyCode)) {
return@run
}
anyCheckRun = true
}
// release or press
if (keyBinding.action[KeyBinding.KeyAction.CHANGE] == null) {
keyBinding.action[keyAction].let {
if (it == null) {
return@run
}
if (!it.contains(keyCode)) {
return@run
}
anyCheckRun = true
}
}
if (!anyCheckRun) {
return@run
}
Log.debug("Keycode ($identifier) -> $keyCode: $keyAction")
if (keyAction == KeyBinding.KeyAction.PRESS) {
keyBindingDown.add(keyBinding)
} else if (keyAction == KeyBinding.KeyAction.RELEASE) {
keyBindingDown.remove(keyBinding)
}
for (keyCallback in keyCallbacks) {
keyCallback.invoke(keyCode, keyAction)
}
}
}
}
glfwSetInputMode(windowId, GLFW_CURSOR, GLFW_CURSOR_DISABLED)
if (mouseCatch) {
glfwSetInputMode(windowId, GLFW_CURSOR, GLFW_CURSOR_DISABLED)
}
glfwSetCursorPosCallback(windowId) { _: Long, xPos: Double, yPos: Double -> camera.mouseCallback(xPos, yPos) }
MemoryStack.stackPush().let { stack ->
val pWidth = stack.mallocInt(1)
@ -169,6 +238,25 @@ class RenderWindow(private val connection: Connection, val rendering: Rendering)
}
})
registerKeyCallback(ModIdentifier("minosoft:debug_polygen")) { _: KeyCodes, _: KeyBinding.KeyAction ->
polygonEnabled = !polygonEnabled
glPolygonMode(GL_FRONT_AND_BACK, if (polygonEnabled) {
GL_LINE
} else {
GL_FILL
})
}
registerKeyCallback(ModIdentifier("minosoft:debug_mouse_catch")) { _: KeyCodes, _: KeyBinding.KeyAction ->
mouseCatch = !mouseCatch
if (mouseCatch) {
glfwSetInputMode(windowId, GLFW_CURSOR, GLFW_CURSOR_DISABLED)
} else {
glfwSetInputMode(windowId, GLFW_CURSOR, GLFW_CURSOR_NORMAL)
}
}
registerKeyCallback(ModIdentifier("minosoft:quit")) { _: KeyCodes, _: KeyBinding.KeyAction ->
glfwSetWindowShouldClose(windowId, true)
}
hudRenderer.screenChangeResizeCallback(screenWidth, screenHeight)
@ -242,15 +330,6 @@ class RenderWindow(private val connection: Connection, val rendering: Rendering)
connection.disconnect()
}
private fun switchPolygonMode() {
glPolygonMode(GL_FRONT_AND_BACK, if (polygonEnabled) {
GL_LINE
} else {
GL_FILL
})
polygonEnabled = !polygonEnabled
}
private fun setRenderStatus(renderingStatus: RenderingStates) {
if (renderingStatus == this.renderingStatus) {
return
@ -261,4 +340,14 @@ class RenderWindow(private val connection: Connection, val rendering: Rendering)
}
this.renderingStatus = renderingStatus
}
fun registerKeyCallback(identifier: ModIdentifier, callback: ((keyCode: KeyCodes, keyEvent: KeyBinding.KeyAction) -> Unit)) {
var identifierCallbacks = keyBindingCallbacks[identifier]?.second
if (identifierCallbacks == null) {
identifierCallbacks = mutableSetOf()
val keyBinding = Minosoft.getConfig().keyBindings[identifier] ?: return
keyBindingCallbacks[identifier] = Pair(keyBinding, identifierCallbacks)
}
identifierCallbacks.add(callback)
}
}

View File

@ -1,6 +1,10 @@
package de.bixilon.minosoft.gui.rendering.hud.elements.text
import de.bixilon.minosoft.config.StaticConfiguration
import de.bixilon.minosoft.config.key.KeyBinding
import de.bixilon.minosoft.config.key.KeyCodes
import de.bixilon.minosoft.data.entities.Location
import de.bixilon.minosoft.data.mappings.ModIdentifier
import de.bixilon.minosoft.data.world.BlockPosition
import de.bixilon.minosoft.data.world.ChunkLocation
import de.bixilon.minosoft.data.world.InChunkSectionLocation
@ -31,7 +35,12 @@ class HUDDebugScreenElement(private val hudTextElement: HUDTextElement) : HUDTex
private var sectionHeight: Int = 0
private lateinit var inChunkSectionLocation: InChunkSectionLocation
private var debugScreenEnabled = StaticConfiguration.DEBUG_MODE
override fun prepare(chatComponents: Map<FontBindings, MutableList<Any>>) {
if (!debugScreenEnabled) {
return
}
calculateDynamicValues()
chatComponents[FontBindings.LEFT_UP]!!.addAll(listOf(
@ -67,6 +76,10 @@ class HUDDebugScreenElement(private val hudTextElement: HUDTextElement) : HUDTex
override fun init() {
gpuText = glGetString(GL_RENDERER) ?: "unknown"
gpuVersionText = glGetString(GL_VERSION) ?: "unknown"
hudTextElement.renderWindow.registerKeyCallback(ModIdentifier("minosoft:debug_screen")) { _: KeyCodes, _: KeyBinding.KeyAction ->
debugScreenEnabled = !debugScreenEnabled
}
}
private fun nanoToMillis1d(nanos: Long): String {

View File

@ -7,7 +7,7 @@ import java.text.SimpleDateFormat
object GitInfo {
var GIT_BRANCH: String = ""
var GIT_BRANCH: String = "master"
private set
var GIT_BUILD_HOST_BRANCH: String = ""
private set

View File

@ -43,13 +43,11 @@ public final class Util {
public static final Pattern UUID_FIX_PATTERN = Pattern.compile("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})"); // thanks https://www.spigotmc.org/threads/free-code-easily-convert-between-trimmed-and-full-uuids.165615
public static final char[] RANDOM_STRING_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();
public static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static final Gson GSON = new Gson();
private static final Random THREAD_LOCAL_RANDOM = ThreadLocalRandom.current();
private static final Field JSON_READER_POS_FIELD;
private static final Field JSON_READER_LINE_START_FIELD;
public static final Gson GSON = new Gson();
static {
new JsonReader(new StringReader(""));
Class<?> jsonReadClass = JsonReader.class;
@ -372,4 +370,12 @@ public final class Util {
}
return headerList.toArray(new String[]{});
}
public static String formatString(String string, Map<String, Object> format) {
String output = string;
for (var entry : format.entrySet()) {
output = output.replace("${" + entry.getKey() + "}", entry.getValue().toString());
}
return output;
}
}

View File

@ -1,23 +1,146 @@
{
"general": {
"version": 1,
"log-level": "WARNING",
"log_level": "WARNING",
"language": "en_US"
},
"game": {
"render-distance": 12
"render_distance": 10,
"key_bindings": {
"minosoft:move_forward": {
"change": [
"W"
],
"when": [
[
"minosoft:in_game"
]
]
},
"minosoft:move_left": {
"change": [
"A"
],
"when": [
[
"minosoft:in_game"
]
]
},
"minosoft:move_back": {
"change": [
"S"
],
"when": [
[
"minosoft:in_game"
]
]
},
"minosoft:move_right": {
"change": [
"D"
],
"when": [
[
"minosoft:in_game"
]
]
},
"minosoft:sprint": {
"change": [
"LEFT_CONTROL"
],
"when": [
[
"minosoft:in_game"
]
]
},
"minosoft:fly_up": {
"change": [
"SPACE"
],
"when": [
[
"minosoft:in_game"
]
]
},
"minosoft:fly_down": {
"change": [
"LEFT_SHIFT"
],
"when": [
[
"minosoft:in_game"
]
]
},
"minosoft:debug_screen": {
"release": [
"F3"
],
"when": [
[
"minosoft:in_game"
]
]
},
"minosoft:debug_polygen": {
"modifier": [
"F4"
],
"release": [
"P"
],
"when": [
[
"minosoft:in_game"
]
]
},
"minosoft:debug_mouse_catch": {
"modifier": [
"F4"
],
"release": [
"M"
]
},
"minosoft:screenshot": {
"press": [
"F2"
]
},
"minosoft:quit": {
"release": [
"ESCAPE"
],
"when": [
[
"minosoft:in_game"
]
]
},
"minosoft:dummy_send_chat_message": {
"double_click": [
"K"
]
}
}
},
"chat": {
"colored": true,
"obfuscated": true
},
"network": {
"fake-network-brand": false,
"show-lan-servers": true
"fake_network_brand": false,
"show_lan_servers": true
},
"accounts": {
"selected": "",
"client-token": "",
"client_token": "",
"entries": {}
},
"servers": {
@ -25,10 +148,10 @@
},
"download": {
"urls": {
"resources": "https://gitlab.com/Bixilon/minosoft/-/raw/development/data/resources/%s/%s.tar.gz?inline=false"
"resources": "https://gitlab.com/Bixilon/minosoft/-/raw/${branch}/data/resources/${hashPrefix}/${fullHash}.tar.gz?inline=false"
}
},
"debug": {
"verify-assets": true
"verify_assets": true
}
}