diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..92085a35 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: GeyserMC Discord + url: http://discord.geysermc.org/ + about: If your issue seems like it could possibly be an easy fix due to configuration, please hop on our Discord. diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java index 1ddda652..5b8842b4 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitLogger.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitLogger.java index 05fd2c6c..454ec9f6 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitLogger.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitLogger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java index 3c7ae839..8b0883ef 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeConfiguration.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeConfiguration.java index 420f8347..e0f6a6ef 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeConfiguration.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeLogger.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeLogger.java index 2ebc069b..7aba88bc 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeLogger.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeLogger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java index d6974daf..959c78d9 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeConfiguration.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeConfiguration.java index 7b6a89f1..be4923e2 100644 --- a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeConfiguration.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeLogger.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeLogger.java index 1df7fbf9..758ac98d 100644 --- a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeLogger.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeLogger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java index a2074b15..bc264589 100644 --- a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserBootstrap.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserBootstrap.java index 284d9407..1bdce0bd 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserBootstrap.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserBootstrap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserConfiguration.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserConfiguration.java index a1362c7a..afd6179e 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserConfiguration.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/ChatColor.java b/common/src/main/java/org/geysermc/common/ChatColor.java index 20632770..e60012e7 100644 --- a/common/src/main/java/org/geysermc/common/ChatColor.java +++ b/common/src/main/java/org/geysermc/common/ChatColor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/IGeyserConfiguration.java b/common/src/main/java/org/geysermc/common/IGeyserConfiguration.java index 41534457..774e3394 100644 --- a/common/src/main/java/org/geysermc/common/IGeyserConfiguration.java +++ b/common/src/main/java/org/geysermc/common/IGeyserConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/bootstrap/IGeyserBootstrap.java b/common/src/main/java/org/geysermc/common/bootstrap/IGeyserBootstrap.java index cf4b3991..9a9d9c2b 100644 --- a/common/src/main/java/org/geysermc/common/bootstrap/IGeyserBootstrap.java +++ b/common/src/main/java/org/geysermc/common/bootstrap/IGeyserBootstrap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/logger/IGeyserLogger.java b/common/src/main/java/org/geysermc/common/logger/IGeyserLogger.java index b4d143e4..ad571ebb 100644 --- a/common/src/main/java/org/geysermc/common/logger/IGeyserLogger.java +++ b/common/src/main/java/org/geysermc/common/logger/IGeyserLogger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/CustomFormBuilder.java b/common/src/main/java/org/geysermc/common/window/CustomFormBuilder.java index fb679412..004b00a9 100644 --- a/common/src/main/java/org/geysermc/common/window/CustomFormBuilder.java +++ b/common/src/main/java/org/geysermc/common/window/CustomFormBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/CustomFormWindow.java b/common/src/main/java/org/geysermc/common/window/CustomFormWindow.java index a6bc7278..8d48fcfa 100644 --- a/common/src/main/java/org/geysermc/common/window/CustomFormWindow.java +++ b/common/src/main/java/org/geysermc/common/window/CustomFormWindow.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/FormWindow.java b/common/src/main/java/org/geysermc/common/window/FormWindow.java index 968d9349..3cfaee43 100644 --- a/common/src/main/java/org/geysermc/common/window/FormWindow.java +++ b/common/src/main/java/org/geysermc/common/window/FormWindow.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/ModalFormWindow.java b/common/src/main/java/org/geysermc/common/window/ModalFormWindow.java index 93466039..66dda0b5 100644 --- a/common/src/main/java/org/geysermc/common/window/ModalFormWindow.java +++ b/common/src/main/java/org/geysermc/common/window/ModalFormWindow.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/SimpleFormWindow.java b/common/src/main/java/org/geysermc/common/window/SimpleFormWindow.java index cc31f061..381cef39 100644 --- a/common/src/main/java/org/geysermc/common/window/SimpleFormWindow.java +++ b/common/src/main/java/org/geysermc/common/window/SimpleFormWindow.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/button/FormButton.java b/common/src/main/java/org/geysermc/common/window/button/FormButton.java index 4f710d48..6daa2fea 100644 --- a/common/src/main/java/org/geysermc/common/window/button/FormButton.java +++ b/common/src/main/java/org/geysermc/common/window/button/FormButton.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -37,6 +37,10 @@ public class FormButton { @Getter private FormImage image; + public FormButton(String text) { + this.text = text; + } + public FormButton(String text, FormImage image) { this.text = text; diff --git a/common/src/main/java/org/geysermc/common/window/button/FormImage.java b/common/src/main/java/org/geysermc/common/window/button/FormImage.java index a3f83a0c..b700b046 100644 --- a/common/src/main/java/org/geysermc/common/window/button/FormImage.java +++ b/common/src/main/java/org/geysermc/common/window/button/FormImage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/component/DropdownComponent.java b/common/src/main/java/org/geysermc/common/window/component/DropdownComponent.java index 8abe72ff..4dac6b04 100644 --- a/common/src/main/java/org/geysermc/common/window/component/DropdownComponent.java +++ b/common/src/main/java/org/geysermc/common/window/component/DropdownComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/component/FormComponent.java b/common/src/main/java/org/geysermc/common/window/component/FormComponent.java index fb5b9d18..5a56ae0c 100644 --- a/common/src/main/java/org/geysermc/common/window/component/FormComponent.java +++ b/common/src/main/java/org/geysermc/common/window/component/FormComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/component/InputComponent.java b/common/src/main/java/org/geysermc/common/window/component/InputComponent.java index 53ec2b5e..fad6a0fe 100644 --- a/common/src/main/java/org/geysermc/common/window/component/InputComponent.java +++ b/common/src/main/java/org/geysermc/common/window/component/InputComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/component/LabelComponent.java b/common/src/main/java/org/geysermc/common/window/component/LabelComponent.java index 7d2aaa42..a76b313f 100644 --- a/common/src/main/java/org/geysermc/common/window/component/LabelComponent.java +++ b/common/src/main/java/org/geysermc/common/window/component/LabelComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/component/SliderComponent.java b/common/src/main/java/org/geysermc/common/window/component/SliderComponent.java index fd82b3e2..a7a78362 100644 --- a/common/src/main/java/org/geysermc/common/window/component/SliderComponent.java +++ b/common/src/main/java/org/geysermc/common/window/component/SliderComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/component/StepSliderComponent.java b/common/src/main/java/org/geysermc/common/window/component/StepSliderComponent.java index b61e416d..8f128d1a 100644 --- a/common/src/main/java/org/geysermc/common/window/component/StepSliderComponent.java +++ b/common/src/main/java/org/geysermc/common/window/component/StepSliderComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/component/ToggleComponent.java b/common/src/main/java/org/geysermc/common/window/component/ToggleComponent.java index 614ecf8f..50a5c631 100644 --- a/common/src/main/java/org/geysermc/common/window/component/ToggleComponent.java +++ b/common/src/main/java/org/geysermc/common/window/component/ToggleComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/response/CustomFormResponse.java b/common/src/main/java/org/geysermc/common/window/response/CustomFormResponse.java index 36b2922f..6cdd7097 100644 --- a/common/src/main/java/org/geysermc/common/window/response/CustomFormResponse.java +++ b/common/src/main/java/org/geysermc/common/window/response/CustomFormResponse.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/response/FormResponse.java b/common/src/main/java/org/geysermc/common/window/response/FormResponse.java index 58c8c8e8..2be64683 100644 --- a/common/src/main/java/org/geysermc/common/window/response/FormResponse.java +++ b/common/src/main/java/org/geysermc/common/window/response/FormResponse.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/response/FormResponseData.java b/common/src/main/java/org/geysermc/common/window/response/FormResponseData.java index 826aba20..fd40be0f 100644 --- a/common/src/main/java/org/geysermc/common/window/response/FormResponseData.java +++ b/common/src/main/java/org/geysermc/common/window/response/FormResponseData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/response/ModalFormResponse.java b/common/src/main/java/org/geysermc/common/window/response/ModalFormResponse.java index 844c9a5b..e1a14039 100644 --- a/common/src/main/java/org/geysermc/common/window/response/ModalFormResponse.java +++ b/common/src/main/java/org/geysermc/common/window/response/ModalFormResponse.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/common/src/main/java/org/geysermc/common/window/response/SimpleFormResponse.java b/common/src/main/java/org/geysermc/common/window/response/SimpleFormResponse.java index 5a53d042..e80d58e7 100644 --- a/common/src/main/java/org/geysermc/common/window/response/SimpleFormResponse.java +++ b/common/src/main/java/org/geysermc/common/window/response/SimpleFormResponse.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index 81f3ea53..fb219002 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -28,7 +28,9 @@ package org.geysermc.connector; import com.nukkitx.protocol.bedrock.BedrockPacketCodec; import com.nukkitx.protocol.bedrock.BedrockServer; import com.nukkitx.protocol.bedrock.v390.Bedrock_v390; + import lombok.Getter; + import org.geysermc.common.AuthType; import org.geysermc.common.IGeyserConfiguration; import org.geysermc.common.PlatformType; diff --git a/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java b/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java new file mode 100644 index 00000000..3a77292f --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.entity; + +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.packet.AddEntityPacket; +import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; + +public class FishingHookEntity extends Entity { + public FishingHookEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + super(entityId, geyserId, entityType, position, motion, rotation); + } + + @Override + public void spawnEntity(GeyserSession session) { + AddEntityPacket addEntityPacket = new AddEntityPacket(); + // Different ID in Bedrock + addEntityPacket.setIdentifier("minecraft:fishing_hook"); + addEntityPacket.setRuntimeEntityId(geyserId); + addEntityPacket.setUniqueEntityId(geyserId); + addEntityPacket.setPosition(position); + addEntityPacket.setMotion(motion); + addEntityPacket.setRotation(getBedrockRotation()); + addEntityPacket.setEntityType(entityType.getType()); + addEntityPacket.getMetadata().putAll(metadata); + + valid = true; + session.getUpstream().sendPacket(addEntityPacket); + + session.getConnector().getLogger().debug("Spawned entity " + entityType + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")"); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/ShulkerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ShulkerEntity.java new file mode 100644 index 00000000..a3a175b8 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ShulkerEntity.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.entity.living.monster; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; +import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace; +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.math.vector.Vector3i; +import com.nukkitx.protocol.bedrock.data.EntityData; +import org.geysermc.connector.entity.living.GolemEntity; +import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; + +public class ShulkerEntity extends GolemEntity { + + public ShulkerEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + super(entityId, geyserId, entityType, position, motion, rotation); + } + + @Override + public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { + if (entityMetadata.getId() == 15) { + BlockFace blockFace = (BlockFace) entityMetadata.getValue(); + metadata.put(EntityData.SHULKER_ATTACH_FACE, (byte) blockFace.ordinal()); + } + if (entityMetadata.getId() == 16) { + Position position = (Position) entityMetadata.getValue(); + metadata.put(EntityData.SHULKER_ATTACH_POS, Vector3i.from(position.getX(), position.getY(), position.getZ())); + } + //TODO Outdated metadata flag SHULKER_PEAK_HEIGHT +// if (entityMetadata.getId() == 17) { +// int height = (byte) entityMetadata.getValue(); +// metadata.put(EntityData.SHULKER_PEAK_HEIGHT, height); +// } + if (entityMetadata.getId() == 18) { + int color = Math.abs((byte) entityMetadata.getValue() - 15); + metadata.put(EntityData.VARIANT, color); + } + super.updateBedrockMetadata(entityMetadata, session); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java b/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java index c50f05db..8ea3240c 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java +++ b/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java @@ -85,7 +85,7 @@ public enum EntityType { NPC(PlayerEntity.class, 51, 1.8f, 0.6f, 0.6f, 1.62f), WITHER(MonsterEntity.class, 52, 3.5f, 0.9f), ENDER_DRAGON(EnderDragonEntity.class, 53, 4f, 13f), - SHULKER(GolemEntity.class, 54, 1f, 1f), + SHULKER(ShulkerEntity.class, 54, 1f, 1f), ENDERMITE(MonsterEntity.class, 55, 0.3f, 0.4f), AGENT(Entity.class, 56, 0f), VINDICATOR(AbstractIllagerEntity.class, 57, 1.8f, 0.6f, 0.6f, 1.62f), @@ -110,7 +110,7 @@ public enum EntityType { TURTLE(AnimalEntity.class, 74, 0.4f, 1.2f), CAT(CatEntity.class, 75, 0.35f, 0.3f), SHULKER_BULLET(Entity.class, 76, 0f), - FISHING_BOBBER(Entity.class, 77, 0f), + FISHING_BOBBER(FishingHookEntity.class, 77, 0f), CHALKBOARD(Entity.class, 78, 0f), DRAGON_FIREBALL(ItemedFireballEntity.class, 79, 0f), ARROW(ArrowEntity.class, 80, 0.25f, 0.25f), diff --git a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java index cf6c2ee2..2ccb3723 100644 --- a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java @@ -86,7 +86,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { @Override public boolean handle(ModalFormResponsePacket packet) { - return LoginEncryptionUtils.authenticateFromForm(session, connector, packet.getFormData()); + return LoginEncryptionUtils.authenticateFromForm(session, connector, packet.getFormId(), packet.getFormData()); } private boolean couldLoginUserByName(String bedrockUsername) { diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index 60b07bb6..12ae39bf 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -314,7 +314,7 @@ public class GeyserSession implements CommandSender { downstream.getSession().connect(); connector.addPlayer(this); - } catch (InvalidCredentialsException e) { + } catch (InvalidCredentialsException | IllegalArgumentException e) { connector.getLogger().info("User '" + username + "' entered invalid login info, kicking."); disconnect("Invalid/incorrect login info"); } catch (RequestException ex) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAnimateTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAnimateTranslator.java index 7ccb2426..af41c9e0 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAnimateTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAnimateTranslator.java @@ -40,6 +40,11 @@ public class BedrockAnimateTranslator extends PacketTranslator { @Override public void translate(AnimatePacket packet, GeyserSession session) { + // Stop the player sending animations before they have fully spawned into the server + if (!session.isSpawned()) { + return; + } + switch (packet.getAction()) { case SWING_ARM: // Delay so entity damage can be processed first diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java index 28cbf4c4..e7d4c748 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java @@ -34,6 +34,7 @@ import org.geysermc.connector.network.translators.Translator; import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket; import com.nukkitx.protocol.bedrock.packet.CommandRequestPacket; +import org.geysermc.connector.utils.MessageUtils; @Translator(packet = CommandRequestPacket.class) public class BedrockCommandRequestTranslator extends PacketTranslator { @@ -45,7 +46,13 @@ public class BedrockCommandRequestTranslator extends PacketTranslator { @@ -38,12 +39,24 @@ public class BedrockTextTranslator extends PacketTranslator { @Override public void translate(TextPacket packet, GeyserSession session) { if (packet.getMessage().charAt(0) == '.') { - ClientChatPacket chatPacket = new ClientChatPacket(packet.getMessage().replace(".", "/")); + String message = packet.getMessage().replace(".", "/").trim(); + + if (MessageUtils.isTooLong(message, session)) { + return; + } + + ClientChatPacket chatPacket = new ClientChatPacket(message); session.getDownstream().getSession().send(chatPacket); return; } - ClientChatPacket chatPacket = new ClientChatPacket(packet.getMessage()); + String message = packet.getMessage().trim(); + + if (MessageUtils.isTooLong(message, session)) { + return; + } + + ClientChatPacket chatPacket = new ClientChatPacket(message); session.getDownstream().getSession().send(chatPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaPluginMessageTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaPluginMessageTranslator.java index 60227aa4..cd0161db 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaPluginMessageTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaPluginMessageTranslator.java @@ -33,14 +33,56 @@ import org.geysermc.connector.network.translators.Translator; import com.github.steveice10.mc.protocol.packet.ingame.client.ClientPluginMessagePacket; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerPluginMessagePacket; +import java.nio.charset.StandardCharsets; + @Translator(packet = ServerPluginMessagePacket.class) public class JavaPluginMessageTranslator extends PacketTranslator { + + private static byte[] brandData; + + static { + byte[] data = GeyserConnector.NAME.getBytes(StandardCharsets.UTF_8); + byte[] varInt = writeVarInt(data.length); + brandData = new byte[varInt.length + data.length]; + System.arraycopy(varInt, 0, brandData, 0, varInt.length); + System.arraycopy(data, 0, brandData, varInt.length, data.length); + } + + @Override public void translate(ServerPluginMessagePacket packet, GeyserSession session) { if (packet.getChannel().equals("minecraft:brand")) { session.getDownstream().getSession().send( - new ClientPluginMessagePacket(packet.getChannel(), GeyserConnector.NAME.getBytes()) + new ClientPluginMessagePacket(packet.getChannel(), brandData) ); } } + + private static byte[] writeVarInt(int value) { + byte[] data = new byte[getVarIntLength(value)]; + int index = 0; + do { + byte temp = (byte)(value & 0b01111111); + value >>>= 7; + if (value != 0) { + temp |= 0b10000000; + } + data[index] = temp; + index++; + } while (value != 0); + return data; + } + + private static int getVarIntLength(int number) { + if ((number & 0xFFFFFF80) == 0) { + return 1; + } else if ((number & 0xFFFFC000) == 0) { + return 2; + } else if ((number & 0xFFE00000) == 0) { + return 3; + } else if ((number & 0xF0000000) == 0) { + return 4; + } + return 5; + } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaRespawnTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaRespawnTranslator.java index 189d96c6..cc2c540f 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaRespawnTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaRespawnTranslator.java @@ -25,6 +25,9 @@ package org.geysermc.connector.network.translators.java; +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.LevelEventType; +import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.network.session.GeyserSession; @@ -35,6 +38,8 @@ import org.geysermc.connector.utils.DimensionUtils; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket; import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket; +import java.util.concurrent.ThreadLocalRandom; + @Translator(packet = ServerRespawnPacket.class) public class JavaRespawnTranslator extends PacketTranslator { @@ -55,6 +60,12 @@ public class JavaRespawnTranslator extends PacketTranslator session.getUpstream().sendPacket(playerGameTypePacket); session.setGameMode(packet.getGamemode()); + LevelEventPacket stopRainPacket = new LevelEventPacket(); + stopRainPacket.setType(LevelEventType.STOP_RAIN); + stopRainPacket.setData(ThreadLocalRandom.current().nextInt(50000) + 10000); + stopRainPacket.setPosition(Vector3f.ZERO); + session.getUpstream().sendPacket(stopRainPacket); + if (entity.getDimension() != DimensionUtils.javaToBedrock(packet.getDimension())) { DimensionUtils.switchDimension(session, packet.getDimension()); } else { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java new file mode 100644 index 00000000..391f0a61 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.java; + +import com.github.steveice10.mc.protocol.data.game.command.CommandNode; +import com.github.steveice10.mc.protocol.data.game.command.CommandParser; +import com.github.steveice10.mc.protocol.packet.ingame.server.ServerDeclareCommandsPacket; +import com.nukkitx.protocol.bedrock.data.CommandData; +import com.nukkitx.protocol.bedrock.data.CommandEnumData; +import com.nukkitx.protocol.bedrock.data.CommandParamData; +import com.nukkitx.protocol.bedrock.packet.AvailableCommandsPacket; +import lombok.Getter; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.PacketTranslator; +import org.geysermc.connector.network.translators.Translator; + +import java.util.*; + +@Translator(packet = ServerDeclareCommandsPacket.class) +public class JavaServerDeclareCommandsTranslator extends PacketTranslator { + @Override + public void translate(ServerDeclareCommandsPacket packet, GeyserSession session) { + List commandData = new ArrayList<>(); + Map commands = new HashMap<>(); + Map> commandArgs = new HashMap<>(); + + // Get the first node, it should be a root node + CommandNode rootNode = packet.getNodes()[packet.getFirstNodeIndex()]; + + // Loop through the root nodes to get all commands + for (int nodeIndex : rootNode.getChildIndices()) { + CommandNode node = packet.getNodes()[nodeIndex]; + + // Make sure we dont have duplicated commands (happens if there is more than 1 root node) + if (commands.containsKey(nodeIndex)) { continue; } + + // Get and update the commandArgs list with the found arguments + if (node.getChildIndices().length >= 1) { + for (int childIndex : node.getChildIndices()) { + commandArgs.putIfAbsent(nodeIndex, new ArrayList<>()); + commandArgs.get(nodeIndex).add(packet.getNodes()[childIndex]); + } + } + + // Insert the command name into the list + commands.put(nodeIndex, node.getName()); + } + + // The command flags, not sure what these do apart from break things + List flags = new ArrayList<>(); + + // Loop through all the found commands + for (int commandID : commands.keySet()) { + String commandName = commands.get(commandID); + + // Create a basic alias + CommandEnumData aliases = new CommandEnumData( commandName + "Aliases", new String[] { commandName.toLowerCase() }, false); + + // Get and parse all params + CommandParamData[][] params = getParams(commandID, packet.getNodes()[commandID], packet.getNodes()); + + // Build the completed command and add it to the final list + CommandData data = new CommandData(commandName, "A Java server command", flags, (byte) 0, aliases, params); + commandData.add(data); + } + + // Add our commands to the AvailableCommandsPacket for the bedrock client + AvailableCommandsPacket availableCommandsPacket = new AvailableCommandsPacket(); + for (CommandData data : commandData) { + availableCommandsPacket.getCommands().add(data); + } + + GeyserConnector.getInstance().getLogger().debug("Sending command packet of " + commandData.size() + " commands"); + + // Finally, send the commands to the client + session.getUpstream().sendPacket(availableCommandsPacket); + } + + private CommandParamData[][] getParams(int commandID, CommandNode commandNode, CommandNode[] allNodes) { + // Check if the command is an alias and redirect it + if (commandNode.getRedirectIndex() != -1) { + GeyserConnector.getInstance().getLogger().debug("Redirecting command " + commandNode.getName() + " to " + allNodes[commandNode.getRedirectIndex()].getName()); + commandNode = allNodes[commandNode.getRedirectIndex()]; + } + + if (commandNode.getChildIndices().length >= 1) { + // Create the root param node and build all the children + ParamInfo rootParam = new ParamInfo(commandNode, null); + rootParam.buildChildren(allNodes); + + List treeData = rootParam.getTree(); + CommandParamData[][] params = new CommandParamData[treeData.size()][]; + + // Fill the nested params array + int i = 0; + for (CommandParamData[] tree : treeData) { + params[i] = tree; + i++; + } + + return params; + } + + return new CommandParamData[0][0]; + } + + private CommandParamData.Type mapCommandType(CommandParser parser) { + if (parser == null) { return CommandParamData.Type.STRING; } + + switch (parser) { + case FLOAT: + return CommandParamData.Type.FLOAT; + + case INTEGER: + return CommandParamData.Type.INT; + + case ENTITY: + case GAME_PROFILE: + return CommandParamData.Type.TARGET; + + case BLOCK_POS: + return CommandParamData.Type.BLOCK_POSITION; + + case COLUMN_POS: + case VEC3: + return CommandParamData.Type.POSITION; + + case MESSAGE: + return CommandParamData.Type.MESSAGE; + + case NBT: + case NBT_COMPOUND_TAG: + case NBT_TAG: + case NBT_PATH: + return CommandParamData.Type.JSON; + + case RESOURCE_LOCATION: + return CommandParamData.Type.FILE_PATH; + + case INT_RANGE: + return CommandParamData.Type.INT_RANGE; + + case BOOL: + case DOUBLE: + case STRING: + case VEC2: + case BLOCK_STATE: + case BLOCK_PREDICATE: + case ITEM_STACK: + case ITEM_PREDICATE: + case COLOR: + case COMPONENT: + case OBJECTIVE: + case OBJECTIVE_CRITERIA: + case OPERATION: // Possibly OPERATOR + case PARTICLE: + case ROTATION: + case SCOREBOARD_SLOT: + case SCORE_HOLDER: + case SWIZZLE: + case TEAM: + case ITEM_SLOT: + case MOB_EFFECT: + case FUNCTION: + case ENTITY_ANCHOR: + case RANGE: + case FLOAT_RANGE: + case ITEM_ENCHANTMENT: + case ENTITY_SUMMON: + case DIMENSION: + case TIME: + default: + return CommandParamData.Type.STRING; + } + } + + @Getter + private class ParamInfo { + private CommandNode paramNode; + private CommandParamData paramData; + private List children; + + public ParamInfo(CommandNode paramNode, CommandParamData paramData) { + this.paramNode = paramNode; + this.paramData = paramData; + this.children = new ArrayList<>(); + } + + public void buildChildren(CommandNode[] allNodes) { + int enumIndex = -1; + + for (int paramID : paramNode.getChildIndices()) { + CommandNode paramNode = allNodes[paramID]; + + if (paramNode.getParser() == null) { + if (enumIndex == -1) { + enumIndex = children.size(); + + // Create the new enum command + CommandEnumData enumData = new CommandEnumData(paramNode.getName(), new String[] { paramNode.getName() }, false); + children.add(new ParamInfo(paramNode, new CommandParamData(paramNode.getName(), false, enumData, mapCommandType(paramNode.getParser()), null, Collections.emptyList()))); + } else { + // Get the existing enum + ParamInfo enumParamInfo = children.get(enumIndex); + + // Extend the current list of enum values + String[] enumOptions = Arrays.copyOf(enumParamInfo.getParamData().getEnumData().getValues(), enumParamInfo.getParamData().getEnumData().getValues().length + 1); + enumOptions[enumOptions.length - 1] = paramNode.getName(); + + // Re-create the command using the updated values + CommandEnumData enumData = new CommandEnumData(enumParamInfo.getParamData().getEnumData().getName(), enumOptions, false); + children.set(enumIndex, new ParamInfo(enumParamInfo.getParamNode(), new CommandParamData(enumParamInfo.getParamData().getName(), false, enumData, enumParamInfo.getParamData().getType(), null, Collections.emptyList()))); + } + }else{ + // Put the non-enum param into the list + children.add(new ParamInfo(paramNode, new CommandParamData(paramNode.getName(), false, null, mapCommandType(paramNode.getParser()), null, Collections.emptyList()))); + } + } + + // Recursively build all child options + for (ParamInfo child : children) { + child.buildChildren(allNodes); + } + } + + public List getTree() { + List treeParamData = new ArrayList<>(); + + for (ParamInfo child : children) { + // Get the tree from the child + List childTree = child.getTree(); + + // Un-pack the tree append the child node to it and push into the list + for (CommandParamData[] subchild : childTree) { + CommandParamData[] tmpTree = new ArrayList() { + { + add(child.getParamData()); + addAll(Arrays.asList(subchild)); + } + }.toArray(new CommandParamData[0]); + + treeParamData.add(tmpTree); + } + + // If we have no more child parameters just the child + if (childTree.size() == 0) { + treeParamData.add(new CommandParamData[] { child.getParamData() }); + } + } + + return treeParamData; + } + } +} diff --git a/connector/src/main/java/org/geysermc/connector/utils/LoginEncryptionUtils.java b/connector/src/main/java/org/geysermc/connector/utils/LoginEncryptionUtils.java index 7f6c8eda..300294a2 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/LoginEncryptionUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/LoginEncryptionUtils.java @@ -40,9 +40,12 @@ import net.minidev.json.JSONObject; import org.geysermc.common.window.CustomFormBuilder; import org.geysermc.common.window.CustomFormWindow; import org.geysermc.common.window.FormWindow; +import org.geysermc.common.window.SimpleFormWindow; +import org.geysermc.common.window.button.FormButton; import org.geysermc.common.window.component.InputComponent; import org.geysermc.common.window.component.LabelComponent; import org.geysermc.common.window.response.CustomFormResponse; +import org.geysermc.common.window.response.SimpleFormResponse; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.auth.AuthData; @@ -152,43 +155,60 @@ public class LoginEncryptionUtils { session.getUpstream().sendPacketImmediately(packet); } - private static int AUTH_FORM_ID = 1337; + private static int AUTH_FORM_ID = 1336; + private static int AUTH_DETAILS_FORM_ID = 1337; public static void showLoginWindow(GeyserSession session) { - CustomFormWindow window = new CustomFormBuilder("Login") - .addComponent(new LabelComponent("Minecraft: Java Edition account authentication.")) + SimpleFormWindow window = new SimpleFormWindow("Login", "You need a Java Edition account to play on this server."); + window.getButtons().add(new FormButton("Login with Minecraft")); + window.getButtons().add(new FormButton("Disconnect")); + + session.sendForm(window, AUTH_FORM_ID); + } + + public static void showLoginDetailsWindow(GeyserSession session) { + CustomFormWindow window = new CustomFormBuilder("Login Details") .addComponent(new LabelComponent("Enter the credentials for your Minecraft: Java Edition account below.")) .addComponent(new InputComponent("Email/Username", "account@geysermc.org", "")) .addComponent(new InputComponent("Password", "123456", "")) .build(); - session.sendForm(window, AUTH_FORM_ID); + session.sendForm(window, AUTH_DETAILS_FORM_ID); } - public static boolean authenticateFromForm(GeyserSession session, GeyserConnector connector, String formData) { + public static boolean authenticateFromForm(GeyserSession session, GeyserConnector connector, int formId, String formData) { WindowCache windowCache = session.getWindowCache(); - if (!windowCache.getWindows().containsKey(AUTH_FORM_ID)) + if (!windowCache.getWindows().containsKey(formId)) return false; - FormWindow window = windowCache.getWindows().remove(AUTH_FORM_ID); - window.setResponse(formData.trim()); + if(formId == AUTH_FORM_ID || formId == AUTH_DETAILS_FORM_ID) { + FormWindow window = windowCache.getWindows().remove(formId); + window.setResponse(formData.trim()); - if (!session.isLoggedIn()) { - if (window instanceof CustomFormWindow) { - CustomFormWindow customFormWindow = (CustomFormWindow) window; - if (!customFormWindow.getTitle().equals("Login")) - return false; + if (!session.isLoggedIn()) { + if (formId == AUTH_DETAILS_FORM_ID && window instanceof CustomFormWindow) { + CustomFormWindow customFormWindow = (CustomFormWindow) window; - CustomFormResponse response = (CustomFormResponse) customFormWindow.getResponse(); - if (response != null) { - String email = response.getInputResponses().get(2); - String password = response.getInputResponses().get(3); + CustomFormResponse response = (CustomFormResponse) customFormWindow.getResponse(); + if (response != null) { + String email = response.getInputResponses().get(1); + String password = response.getInputResponses().get(2); - session.authenticate(email, password); + session.authenticate(email, password); + } + + // Clear windows so authentication data isn't accidentally cached + windowCache.getWindows().clear(); + } else if (formId == AUTH_FORM_ID && window instanceof SimpleFormWindow) { + SimpleFormResponse response = (SimpleFormResponse) window.getResponse(); + if(response != null) { + if(response.getClickedButtonId() == 0) { + showLoginDetailsWindow(session); + } else if(response.getClickedButtonId() == 1) { + session.disconnect("Login is required"); + } + } } - - // Clear windows so authentication data isn't accidentally cached - windowCache.getWindows().clear(); } } return true; diff --git a/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java b/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java index b47e86ee..5be8eab1 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java @@ -32,6 +32,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; +import org.geysermc.connector.network.session.GeyserSession; import java.util.*; import java.util.regex.Matcher; @@ -294,4 +295,14 @@ public class MessageUtils { } return ""; } + + public static boolean isTooLong(String message, GeyserSession session) { + if (message.length() > 256) { + // TODO: Add Geyser localization and translate this based on language + session.sendMessage("Your message is bigger than 256 characters (" + message.length() + ") so it has not been sent."); + return true; + } + + return false; + } }