View difference between Paste ID: 1FTZKQcG and CH6Uu9pQ
SHOW: | | - or go back to the newest paste.
1
package net.centroom.api.utils;
2
3
import java.lang.reflect.InvocationTargetException;
4
import java.util.Arrays;
5
import java.util.HashMap;
6
import java.util.List;
7
import java.util.Map;
8
import java.util.Optional;
9
import java.util.UUID;
10
import java.util.concurrent.ConcurrentHashMap;
11
import java.util.stream.IntStream;
12
13
import org.bukkit.Bukkit;
14
import org.bukkit.ChatColor;
15
import org.bukkit.Location;
16
import org.bukkit.Material;
17
import org.bukkit.entity.Player;
18
import org.bukkit.plugin.Plugin;
19
20
import com.comphenix.protocol.PacketType;
21
import com.comphenix.protocol.ProtocolLibrary;
22
import com.comphenix.protocol.events.PacketAdapter;
23
import com.comphenix.protocol.events.PacketContainer;
24
import com.comphenix.protocol.events.PacketEvent;
25
import com.comphenix.protocol.wrappers.BlockPosition;
26
import com.comphenix.protocol.wrappers.WrappedBlockData;
27
import com.comphenix.protocol.wrappers.WrappedChatComponent;
28
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
29
30
/*
31
*
32
*   Sign Menu v1.1
33
*
34
*   Developed by: FrostedSnowman
35
*   Inspired by: nisovin (https://bukkit.org/threads/sign-gui-use-the-sign-interface-to-get-user-input.177030/)
36
*
37
*
38
* FIXED: Sign block showing up next to the client
39
*
40
* */
41
42
public class SignMenu {
43
44
	private final Plugin plugin;
45
46
	private final Map<UUID, InputReceiver> inputReceivers;
47
48
	private final Map<BlockPosition, UUID> playersPlaces;
49
50
	public SignMenu(Plugin plugin) {
51
		this.plugin = plugin;
52
		this.inputReceivers = new ConcurrentHashMap<>();
53
		this.playersPlaces = new HashMap<>();
54
		this.listen();
55
	}
56
57
	public void open(UUID uuid, String[] text, InputReceiver inputReceiver) {
58
		this.inputReceivers.putIfAbsent(uuid, this.display(uuid, inputReceiver,
59
				Arrays.stream(Arrays.copyOf(text, 4))
60
						.map(s -> ChatColor.translateAlternateColorCodes('&', Optional.ofNullable(s).orElse("")))
61
						.toArray(String[]::new)));
62
	}
63
64
	public void open(UUID uuid, List<String> text, InputReceiver inputReceiver) {
65
		open(uuid, text.toArray(new String[text.size()]), inputReceiver);
66
	}
67
68
	public void open(Player player, String[] text, InputReceiver inputReceiver) {
69
		open(player.getUniqueId(), text, inputReceiver);
70
	}
71
72
	public void open(Player player, List<String> text, InputReceiver inputReceiver) {
73
		open(player.getUniqueId(), text, inputReceiver);
74
	}
75
76
	private void listen() {
77
		ProtocolLibrary.getProtocolManager()
78
				.addPacketListener(new PacketAdapter(this.plugin, PacketType.Play.Client.UPDATE_SIGN) {
79
80
					@Override
81
					public void onPacketReceiving(PacketEvent event) {
82
						PacketContainer packet = event.getPacket();
83
						Player player = event.getPlayer();
84
						WrappedChatComponent[] text = packet.getChatComponentArrays().read(0);
85
						if (!inputReceivers.containsKey(player.getUniqueId())) {
86
							return;
87
						}
88
						event.setCancelled(true);
89
						inputReceivers.remove(player.getUniqueId()).receive(player, text);
90
					}
91
				});
92
93
		/*PacketListenerAPI.addPacketHandler(new PacketHandler() {
94
95
			@Override
96
			public void onSend(SentPacket packet) {
97
			}
98
99
			@Override
100
			public void onReceive(ReceivedPacket packet) {
101
				if (!packet.getPacketName().equals("PacketPlayInUpdateSign"))
102
					return;
103
104
				PacketPlayInUpdateSign p = ((PacketPlayInUpdateSign) packet.getPacket());
105
				System.out.println("tets p " + p.a());
106
				System.out.println("test 2 " + p.a().getX() + " " + p.a().getZ());
107
				UUID uuid = playersPlaces.get(new BlockPosition(p.a().getX(), 0, p.a().getZ()));
108
				if (uuid == null)
109
					return;
110
111
				//inputReceivers.remove(uuid).receive(uuid, p.b());
112
			}
113
114
		});*/
115
	}
116
117
	private InputReceiver display(UUID uuid, InputReceiver inputReceiver, String... text) {
118
		Player player = Bukkit.getPlayer(uuid);
119
		Location location = player.getLocation();
120
		BlockPosition blockPosition = new BlockPosition(location.getBlockX(), 0, location.getBlockZ());
121
		playersPlaces.put(blockPosition, uuid);
122
123
		PacketContainer fakeSign = ProtocolLibrary.getProtocolManager()
124
				.createPacket(PacketType.Play.Server.BLOCK_CHANGE);
125
		PacketContainer openSign = ProtocolLibrary.getProtocolManager()
126
				.createPacket(PacketType.Play.Server.OPEN_SIGN_EDITOR);
127
		PacketContainer signData = ProtocolLibrary.getProtocolManager()
128
				.createPacket(PacketType.Play.Server.TILE_ENTITY_DATA);
129
130
		fakeSign.getBlockPositionModifier().write(0, blockPosition);
131
		fakeSign.getBlockData().write(0, WrappedBlockData.createData(Material.SIGN_POST));
132
133
		openSign.getBlockPositionModifier().write(0, blockPosition);
134
135
		NbtCompound signNBT = (NbtCompound) signData.getNbtModifier().read(0);
136
		IntStream.range(0, text.length).forEach(
137
				v -> signNBT.put("Text" + (v + 1), "{\"extra\":[{\"text\":\"" + text[v] + "\"}],\"text\":\"\"}"));
138
139
		signData.getBlockPositionModifier().write(0, blockPosition);
140
		signData.getIntegers().write(0, 9);
141
		signData.getNbtModifier().write(0, signNBT);
142
143
		try {
144
			ProtocolLibrary.getProtocolManager().sendServerPacket(player, fakeSign);
145
			ProtocolLibrary.getProtocolManager().sendServerPacket(player, openSign);
146
			ProtocolLibrary.getProtocolManager().sendServerPacket(player, signData);
147
		} catch (InvocationTargetException exception) {
148
			exception.printStackTrace();
149
		}
150
		return inputReceiver;
151
	}
152
153
	public interface InputReceiver {
154
155
		void receive(Player player, WrappedChatComponent[] text);
156
	}
157
}