Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-03 14:50:19 +01:00
Merge branch 'master' into inventory
Dieser Commit ist enthalten in:
Commit
4b001593fc
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normale Datei
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normale Datei
@ -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.
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -37,6 +37,10 @@ public class FormButton {
|
|||||||
@Getter
|
@Getter
|
||||||
private FormImage image;
|
private FormImage image;
|
||||||
|
|
||||||
|
public FormButton(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
public FormButton(String text, FormImage image) {
|
public FormButton(String text, FormImage image) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
|
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -28,7 +28,9 @@ package org.geysermc.connector;
|
|||||||
import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
|
import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
|
||||||
import com.nukkitx.protocol.bedrock.BedrockServer;
|
import com.nukkitx.protocol.bedrock.BedrockServer;
|
||||||
import com.nukkitx.protocol.bedrock.v390.Bedrock_v390;
|
import com.nukkitx.protocol.bedrock.v390.Bedrock_v390;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import org.geysermc.common.AuthType;
|
import org.geysermc.common.AuthType;
|
||||||
import org.geysermc.common.IGeyserConfiguration;
|
import org.geysermc.common.IGeyserConfiguration;
|
||||||
import org.geysermc.common.PlatformType;
|
import org.geysermc.common.PlatformType;
|
||||||
|
@ -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 + ")");
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -85,7 +85,7 @@ public enum EntityType {
|
|||||||
NPC(PlayerEntity.class, 51, 1.8f, 0.6f, 0.6f, 1.62f),
|
NPC(PlayerEntity.class, 51, 1.8f, 0.6f, 0.6f, 1.62f),
|
||||||
WITHER(MonsterEntity.class, 52, 3.5f, 0.9f),
|
WITHER(MonsterEntity.class, 52, 3.5f, 0.9f),
|
||||||
ENDER_DRAGON(EnderDragonEntity.class, 53, 4f, 13f),
|
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),
|
ENDERMITE(MonsterEntity.class, 55, 0.3f, 0.4f),
|
||||||
AGENT(Entity.class, 56, 0f),
|
AGENT(Entity.class, 56, 0f),
|
||||||
VINDICATOR(AbstractIllagerEntity.class, 57, 1.8f, 0.6f, 0.6f, 1.62f),
|
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),
|
TURTLE(AnimalEntity.class, 74, 0.4f, 1.2f),
|
||||||
CAT(CatEntity.class, 75, 0.35f, 0.3f),
|
CAT(CatEntity.class, 75, 0.35f, 0.3f),
|
||||||
SHULKER_BULLET(Entity.class, 76, 0f),
|
SHULKER_BULLET(Entity.class, 76, 0f),
|
||||||
FISHING_BOBBER(Entity.class, 77, 0f),
|
FISHING_BOBBER(FishingHookEntity.class, 77, 0f),
|
||||||
CHALKBOARD(Entity.class, 78, 0f),
|
CHALKBOARD(Entity.class, 78, 0f),
|
||||||
DRAGON_FIREBALL(ItemedFireballEntity.class, 79, 0f),
|
DRAGON_FIREBALL(ItemedFireballEntity.class, 79, 0f),
|
||||||
ARROW(ArrowEntity.class, 80, 0.25f, 0.25f),
|
ARROW(ArrowEntity.class, 80, 0.25f, 0.25f),
|
||||||
|
@ -86,7 +86,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(ModalFormResponsePacket packet) {
|
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) {
|
private boolean couldLoginUserByName(String bedrockUsername) {
|
||||||
|
@ -314,7 +314,7 @@ public class GeyserSession implements CommandSender {
|
|||||||
|
|
||||||
downstream.getSession().connect();
|
downstream.getSession().connect();
|
||||||
connector.addPlayer(this);
|
connector.addPlayer(this);
|
||||||
} catch (InvalidCredentialsException e) {
|
} catch (InvalidCredentialsException | IllegalArgumentException e) {
|
||||||
connector.getLogger().info("User '" + username + "' entered invalid login info, kicking.");
|
connector.getLogger().info("User '" + username + "' entered invalid login info, kicking.");
|
||||||
disconnect("Invalid/incorrect login info");
|
disconnect("Invalid/incorrect login info");
|
||||||
} catch (RequestException ex) {
|
} catch (RequestException ex) {
|
||||||
|
@ -40,6 +40,11 @@ public class BedrockAnimateTranslator extends PacketTranslator<AnimatePacket> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translate(AnimatePacket packet, GeyserSession session) {
|
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()) {
|
switch (packet.getAction()) {
|
||||||
case SWING_ARM:
|
case SWING_ARM:
|
||||||
// Delay so entity damage can be processed first
|
// Delay so entity damage can be processed first
|
||||||
|
@ -34,6 +34,7 @@ import org.geysermc.connector.network.translators.Translator;
|
|||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.CommandRequestPacket;
|
import com.nukkitx.protocol.bedrock.packet.CommandRequestPacket;
|
||||||
|
import org.geysermc.connector.utils.MessageUtils;
|
||||||
|
|
||||||
@Translator(packet = CommandRequestPacket.class)
|
@Translator(packet = CommandRequestPacket.class)
|
||||||
public class BedrockCommandRequestTranslator extends PacketTranslator<CommandRequestPacket> {
|
public class BedrockCommandRequestTranslator extends PacketTranslator<CommandRequestPacket> {
|
||||||
@ -45,7 +46,13 @@ public class BedrockCommandRequestTranslator extends PacketTranslator<CommandReq
|
|||||||
if (session.getConnector().getPlatformType() == PlatformType.STANDALONE && command.startsWith("geyser ") && commandMap.getCommands().containsKey(command.split(" ")[1])) {
|
if (session.getConnector().getPlatformType() == PlatformType.STANDALONE && command.startsWith("geyser ") && commandMap.getCommands().containsKey(command.split(" ")[1])) {
|
||||||
commandMap.runCommand(session, command);
|
commandMap.runCommand(session, command);
|
||||||
} else {
|
} else {
|
||||||
ClientChatPacket chatPacket = new ClientChatPacket(packet.getCommand());
|
String message = packet.getCommand().trim();
|
||||||
|
|
||||||
|
if (MessageUtils.isTooLong(message, session)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientChatPacket chatPacket = new ClientChatPacket(message);
|
||||||
session.getDownstream().getSession().send(chatPacket);
|
session.getDownstream().getSession().send(chatPacket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import org.geysermc.connector.network.translators.Translator;
|
|||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.TextPacket;
|
import com.nukkitx.protocol.bedrock.packet.TextPacket;
|
||||||
|
import org.geysermc.connector.utils.MessageUtils;
|
||||||
|
|
||||||
@Translator(packet = TextPacket.class)
|
@Translator(packet = TextPacket.class)
|
||||||
public class BedrockTextTranslator extends PacketTranslator<TextPacket> {
|
public class BedrockTextTranslator extends PacketTranslator<TextPacket> {
|
||||||
@ -38,12 +39,24 @@ public class BedrockTextTranslator extends PacketTranslator<TextPacket> {
|
|||||||
@Override
|
@Override
|
||||||
public void translate(TextPacket packet, GeyserSession session) {
|
public void translate(TextPacket packet, GeyserSession session) {
|
||||||
if (packet.getMessage().charAt(0) == '.') {
|
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);
|
session.getDownstream().getSession().send(chatPacket);
|
||||||
return;
|
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);
|
session.getDownstream().getSession().send(chatPacket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.client.ClientPluginMessagePacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerPluginMessagePacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerPluginMessagePacket;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
@Translator(packet = ServerPluginMessagePacket.class)
|
@Translator(packet = ServerPluginMessagePacket.class)
|
||||||
public class JavaPluginMessageTranslator extends PacketTranslator<ServerPluginMessagePacket> {
|
public class JavaPluginMessageTranslator extends PacketTranslator<ServerPluginMessagePacket> {
|
||||||
|
|
||||||
|
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
|
@Override
|
||||||
public void translate(ServerPluginMessagePacket packet, GeyserSession session) {
|
public void translate(ServerPluginMessagePacket packet, GeyserSession session) {
|
||||||
if (packet.getChannel().equals("minecraft:brand")) {
|
if (packet.getChannel().equals("minecraft:brand")) {
|
||||||
session.getDownstream().getSession().send(
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,9 @@
|
|||||||
|
|
||||||
package org.geysermc.connector.network.translators.java;
|
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.Entity;
|
||||||
import org.geysermc.connector.entity.attribute.AttributeType;
|
import org.geysermc.connector.entity.attribute.AttributeType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
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.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket;
|
import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket;
|
||||||
|
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
@Translator(packet = ServerRespawnPacket.class)
|
@Translator(packet = ServerRespawnPacket.class)
|
||||||
public class JavaRespawnTranslator extends PacketTranslator<ServerRespawnPacket> {
|
public class JavaRespawnTranslator extends PacketTranslator<ServerRespawnPacket> {
|
||||||
|
|
||||||
@ -55,6 +60,12 @@ public class JavaRespawnTranslator extends PacketTranslator<ServerRespawnPacket>
|
|||||||
session.getUpstream().sendPacket(playerGameTypePacket);
|
session.getUpstream().sendPacket(playerGameTypePacket);
|
||||||
session.setGameMode(packet.getGamemode());
|
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())) {
|
if (entity.getDimension() != DimensionUtils.javaToBedrock(packet.getDimension())) {
|
||||||
DimensionUtils.switchDimension(session, packet.getDimension());
|
DimensionUtils.switchDimension(session, packet.getDimension());
|
||||||
} else {
|
} else {
|
||||||
|
@ -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<ServerDeclareCommandsPacket> {
|
||||||
|
@Override
|
||||||
|
public void translate(ServerDeclareCommandsPacket packet, GeyserSession session) {
|
||||||
|
List<CommandData> commandData = new ArrayList<>();
|
||||||
|
Map<Integer, String> commands = new HashMap<>();
|
||||||
|
Map<Integer, List<CommandNode>> 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<CommandData.Flag> 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<CommandParamData[]> 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<ParamInfo> 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<CommandParamData[]> getTree() {
|
||||||
|
List<CommandParamData[]> treeParamData = new ArrayList<>();
|
||||||
|
|
||||||
|
for (ParamInfo child : children) {
|
||||||
|
// Get the tree from the child
|
||||||
|
List<CommandParamData[]> 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<CommandParamData>() {
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -40,9 +40,12 @@ import net.minidev.json.JSONObject;
|
|||||||
import org.geysermc.common.window.CustomFormBuilder;
|
import org.geysermc.common.window.CustomFormBuilder;
|
||||||
import org.geysermc.common.window.CustomFormWindow;
|
import org.geysermc.common.window.CustomFormWindow;
|
||||||
import org.geysermc.common.window.FormWindow;
|
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.InputComponent;
|
||||||
import org.geysermc.common.window.component.LabelComponent;
|
import org.geysermc.common.window.component.LabelComponent;
|
||||||
import org.geysermc.common.window.response.CustomFormResponse;
|
import org.geysermc.common.window.response.CustomFormResponse;
|
||||||
|
import org.geysermc.common.window.response.SimpleFormResponse;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.session.auth.AuthData;
|
import org.geysermc.connector.network.session.auth.AuthData;
|
||||||
@ -152,43 +155,60 @@ public class LoginEncryptionUtils {
|
|||||||
session.getUpstream().sendPacketImmediately(packet);
|
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) {
|
public static void showLoginWindow(GeyserSession session) {
|
||||||
CustomFormWindow window = new CustomFormBuilder("Login")
|
SimpleFormWindow window = new SimpleFormWindow("Login", "You need a Java Edition account to play on this server.");
|
||||||
.addComponent(new LabelComponent("Minecraft: Java Edition account authentication."))
|
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 LabelComponent("Enter the credentials for your Minecraft: Java Edition account below."))
|
||||||
.addComponent(new InputComponent("Email/Username", "account@geysermc.org", ""))
|
.addComponent(new InputComponent("Email/Username", "account@geysermc.org", ""))
|
||||||
.addComponent(new InputComponent("Password", "123456", ""))
|
.addComponent(new InputComponent("Password", "123456", ""))
|
||||||
.build();
|
.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();
|
WindowCache windowCache = session.getWindowCache();
|
||||||
if (!windowCache.getWindows().containsKey(AUTH_FORM_ID))
|
if (!windowCache.getWindows().containsKey(formId))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FormWindow window = windowCache.getWindows().remove(AUTH_FORM_ID);
|
if(formId == AUTH_FORM_ID || formId == AUTH_DETAILS_FORM_ID) {
|
||||||
|
FormWindow window = windowCache.getWindows().remove(formId);
|
||||||
window.setResponse(formData.trim());
|
window.setResponse(formData.trim());
|
||||||
|
|
||||||
if (!session.isLoggedIn()) {
|
if (!session.isLoggedIn()) {
|
||||||
if (window instanceof CustomFormWindow) {
|
if (formId == AUTH_DETAILS_FORM_ID && window instanceof CustomFormWindow) {
|
||||||
CustomFormWindow customFormWindow = (CustomFormWindow) window;
|
CustomFormWindow customFormWindow = (CustomFormWindow) window;
|
||||||
if (!customFormWindow.getTitle().equals("Login"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
CustomFormResponse response = (CustomFormResponse) customFormWindow.getResponse();
|
CustomFormResponse response = (CustomFormResponse) customFormWindow.getResponse();
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
String email = response.getInputResponses().get(2);
|
String email = response.getInputResponses().get(1);
|
||||||
String password = response.getInputResponses().get(3);
|
String password = response.getInputResponses().get(2);
|
||||||
|
|
||||||
session.authenticate(email, password);
|
session.authenticate(email, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear windows so authentication data isn't accidentally cached
|
// Clear windows so authentication data isn't accidentally cached
|
||||||
windowCache.getWindows().clear();
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -32,6 +32,7 @@ import com.google.gson.JsonElement;
|
|||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
import com.google.gson.JsonPrimitive;
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
@ -294,4 +295,14 @@ public class MessageUtils {
|
|||||||
}
|
}
|
||||||
return "";
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren