mirror of https://github.com/LOOHP/Limbo.git
Revision of the Event system
- new direct Event system inspired by FabricMC - all current events adapted to the new system - removed EventManager, Listener, Cancellable and EventHandler in favor of the new thing - Changed the event invocations in ClientSession and Player
This commit is contained in:
parent
b8ea419dfc
commit
0e25e4e960
|
|
@ -1,4 +1,5 @@
|
|||
.idea/
|
||||
target/
|
||||
|
||||
*.iml
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ import org.json.simple.parser.ParseException;
|
|||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.loohp.limbo.events.EventsManager;
|
||||
import com.loohp.limbo.server.ServerConnection;
|
||||
import com.loohp.limbo.server.packets.Packet;
|
||||
import com.loohp.limbo.server.packets.PacketIn;
|
||||
|
|
@ -124,7 +123,6 @@ public class Limbo {
|
|||
private ServerProperties properties;
|
||||
|
||||
private PluginManager pluginManager;
|
||||
private EventsManager eventsManager;
|
||||
private PermissionsManager permissionManager;
|
||||
private File pluginFolder;
|
||||
|
||||
|
|
@ -289,8 +287,6 @@ public class Limbo {
|
|||
permissionManager = new PermissionsManager();
|
||||
permissionManager.loadDefaultPermissionFile(permissionFile);
|
||||
|
||||
eventsManager = new EventsManager();
|
||||
|
||||
pluginFolder = new File("plugins");
|
||||
pluginFolder.mkdirs();
|
||||
|
||||
|
|
@ -353,10 +349,6 @@ public class Limbo {
|
|||
return internalDataFolder;
|
||||
}
|
||||
|
||||
public EventsManager getEventsManager() {
|
||||
return eventsManager;
|
||||
}
|
||||
|
||||
public File getPluginFolder() {
|
||||
return pluginFolder;
|
||||
}
|
||||
|
|
@ -496,7 +488,7 @@ public class Limbo {
|
|||
}
|
||||
|
||||
public String buildLegacyPingResponse(String version, BaseComponent[] motd, int maxPlayers, int playersOnline) {
|
||||
String begin = "§1";
|
||||
String begin = "<EFBFBD>1";
|
||||
return String.join("\00", begin, "127", version, String.join("", Arrays.asList(motd).stream().map(each -> each.toLegacyText()).collect(Collectors.toList())), String.valueOf(playersOnline), String.valueOf(maxPlayers));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
package com.loohp.limbo.events;
|
||||
|
||||
public interface Cancellable {
|
||||
|
||||
public void setCancelled(boolean cancelled);
|
||||
|
||||
public boolean isCancelled();
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
package com.loohp.limbo.events;
|
||||
|
||||
public abstract class Event {
|
||||
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
package com.loohp.limbo.events;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Documented
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface EventHandler {
|
||||
EventPriority priority() default EventPriority.NORMAL;
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
package com.loohp.limbo.events;
|
||||
|
||||
public enum EventPriority {
|
||||
LOWEST(0),
|
||||
LOW(1),
|
||||
NORMAL(2),
|
||||
HIGH(3),
|
||||
HIGHEST(4),
|
||||
MONITOR(5);
|
||||
|
||||
int order;
|
||||
|
||||
EventPriority(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public static EventPriority getByOrder(int order) {
|
||||
for (EventPriority each : EventPriority.values()) {
|
||||
if (each.getOrder() == order) {
|
||||
return each;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static EventPriority[] getPrioritiesInOrder() {
|
||||
EventPriority[] array = new EventPriority[EventPriority.values().length];
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] = EventPriority.getByOrder(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
package com.loohp.limbo.events;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.loohp.limbo.plugins.LimboPlugin;
|
||||
|
||||
public class EventsManager {
|
||||
|
||||
private List<ListenerPair> listeners;
|
||||
|
||||
public EventsManager() {
|
||||
listeners = new ArrayList<>();
|
||||
}
|
||||
|
||||
public <T extends Event> T callEvent(T event) {
|
||||
for (EventPriority priority : EventPriority.getPrioritiesInOrder()) {
|
||||
for (ListenerPair entry : listeners) {
|
||||
Listener listener = entry.listener;
|
||||
for (Method method : listener.getClass().getMethods()) {
|
||||
if (method.isAnnotationPresent(EventHandler.class)) {
|
||||
if (method.getAnnotation(EventHandler.class).priority().equals(priority)) {
|
||||
if (method.getParameterCount() == 1 && method.getParameterTypes()[0].equals(event.getClass())) {
|
||||
try {
|
||||
method.invoke(listener, event);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error while passing " + event.getClass().getCanonicalName() + " to the plugin \"" + entry.plugin.getName() + "\"");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
public void registerEvents(LimboPlugin plugin, Listener listener) {
|
||||
listeners.add(new ListenerPair(plugin, listener));
|
||||
}
|
||||
|
||||
public void unregisterAllListeners(LimboPlugin plugin) {
|
||||
listeners.removeIf(each -> each.plugin.equals(plugin));
|
||||
}
|
||||
|
||||
protected static class ListenerPair {
|
||||
public LimboPlugin plugin;
|
||||
public Listener listener;
|
||||
|
||||
public ListenerPair(LimboPlugin plugin, Listener listener) {
|
||||
this.plugin = plugin;
|
||||
this.listener = listener;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
package com.loohp.limbo.events;
|
||||
|
||||
public interface Listener {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.loohp.limbo.events.api;
|
||||
|
||||
/**
|
||||
* Base class for Event implementations.
|
||||
*
|
||||
* @param <T> The listener type.
|
||||
* @see EventFactory
|
||||
*/
|
||||
public abstract class Event<T> {
|
||||
/**
|
||||
* The invoker field. This should be updated by the implementation to
|
||||
* always refer to an instance containing all code that should be
|
||||
* executed upon event emission.
|
||||
*/
|
||||
protected volatile T invoker;
|
||||
|
||||
/**
|
||||
* Returns the invoker instance.
|
||||
*
|
||||
* <p>An "invoker" is an object which hides multiple registered
|
||||
* listeners of type T under one instance of type T, executing
|
||||
* them and leaving early as necessary.
|
||||
*
|
||||
* @return The invoker instance.
|
||||
*/
|
||||
public final T invoker() {
|
||||
return invoker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a listener to the event.
|
||||
*
|
||||
* @param listener The desired listener.
|
||||
*/
|
||||
public abstract void register(EventPriority eventPriority, T listener);
|
||||
|
||||
public void register(T listener) {
|
||||
this.register(EventPriority.NORMAL, listener);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.loohp.limbo.events.api;
|
||||
|
||||
import com.loohp.limbo.events.impl.EventFactoryImpl;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Helper for creating {@link Event} classes.
|
||||
*/
|
||||
public final class EventFactory {
|
||||
|
||||
private static boolean profilingEnabled = true;
|
||||
|
||||
private EventFactory() { }
|
||||
|
||||
/**
|
||||
* @return True if events are supposed to be profiled.
|
||||
*/
|
||||
public static boolean isProfilingEnabled() {
|
||||
return profilingEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate and re-create all existing "invoker" instances across
|
||||
* events created by this EventFactory. Use this if, for instance,
|
||||
* the profilingEnabled field changes.
|
||||
*/
|
||||
// TODO: Turn this into an event?
|
||||
public static void invalidate() {
|
||||
EventFactoryImpl.invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an "array-backed" Event instance.
|
||||
*
|
||||
* <p>If your factory simply delegates to the listeners without adding custom behavior,
|
||||
* consider using {@linkplain #createArrayBacked(Class, Object, Function) the other overload}
|
||||
* if performance of this event is critical.
|
||||
*
|
||||
* @param type The listener class type.
|
||||
* @param invokerFactory The invoker factory, combining multiple listeners into one instance.
|
||||
* @param <T> The listener type.
|
||||
* @return The Event instance.
|
||||
*/
|
||||
public static <T> Event<T> createArrayBacked(Class<? super T> type, Function<T[], T> invokerFactory) {
|
||||
return EventFactoryImpl.createArrayBacked(type, invokerFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an "array-backed" Event instance with a custom empty invoker,
|
||||
* for an event whose {@code invokerFactory} only delegates to the listeners.
|
||||
* <ul>
|
||||
* <li>If there is no listener, the custom empty invoker will be used.</li>
|
||||
* <li><b>If there is only one listener, that one will be used as the invoker
|
||||
* and the factory will not be called.</b></li>
|
||||
* <li>Only when there are at least two listeners will the factory be used.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>Having a custom empty invoker (of type (...) -> {}) increases performance
|
||||
* relative to iterating over an empty array; however, it only really matters
|
||||
* if the event is executed thousands of times a second.
|
||||
*
|
||||
* @param type The listener class type.
|
||||
* @param emptyInvoker The custom empty invoker.
|
||||
* @param invokerFactory The invoker factory, combining multiple listeners into one instance.
|
||||
* @param <T> The listener type.
|
||||
* @return The Event instance.
|
||||
*/
|
||||
public static <T> Event<T> createArrayBacked(Class<T> type, T emptyInvoker, Function<T[], T> invokerFactory) {
|
||||
return createArrayBacked(type, listeners -> {
|
||||
if (listeners.length == 0) {
|
||||
return emptyInvoker;
|
||||
} else if (listeners.length == 1) {
|
||||
return listeners[0];
|
||||
} else {
|
||||
return invokerFactory.apply(listeners);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the listener object name. This can be used in debugging/profiling
|
||||
* scenarios.
|
||||
*
|
||||
* @param handler The listener object.
|
||||
* @return The listener name.
|
||||
*/
|
||||
public static String getHandlerName(Object handler) {
|
||||
return handler.getClass().getName();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.loohp.limbo.events.api;
|
||||
|
||||
public enum EventPriority {
|
||||
LOWEST,
|
||||
LOW,
|
||||
NORMAL,
|
||||
HIGH,
|
||||
HIGHEST,
|
||||
MONITOR
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.loohp.limbo.events.impl;
|
||||
|
||||
import com.loohp.limbo.events.api.EventPriority;
|
||||
import com.loohp.limbo.events.api.Event;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Function;
|
||||
|
||||
class ArrayBackedEvent<T> extends Event<T>
|
||||
{
|
||||
private final Function<T[], T> invokerFactory;
|
||||
private final Lock lock = new ReentrantLock();
|
||||
private T[] handlers;
|
||||
|
||||
private final Class<? super T> invokerType;
|
||||
private InvokerWrapper<T>[] handlersWrapped;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ArrayBackedEvent(Class<? super T> type, Function<T[], T> invokerFactory) {
|
||||
this.invokerType = type;
|
||||
this.invokerFactory = invokerFactory;
|
||||
this.handlers = (T[]) Array.newInstance(type, 0);
|
||||
this.handlersWrapped = new InvokerWrapper[0];
|
||||
update();
|
||||
}
|
||||
|
||||
void update() {
|
||||
this.invoker = invokerFactory.apply(handlers);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void register(EventPriority eventPriority, T listener) {
|
||||
Objects.requireNonNull(listener, "Tried to register a null listener!");
|
||||
|
||||
lock.lock();
|
||||
|
||||
try {
|
||||
handlersWrapped = Arrays.copyOf(handlersWrapped, handlersWrapped.length + 1);
|
||||
handlersWrapped[handlersWrapped.length - 1] = new InvokerWrapper<>(eventPriority, listener);
|
||||
Arrays.sort(handlersWrapped, Comparator.comparing(wrapper -> wrapper.priority));
|
||||
|
||||
handlers = Arrays.stream(handlersWrapped).map(InvokerWrapper::getInvoker).toArray(size -> (T[]) Array.newInstance(this.invokerType, size));
|
||||
update();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
static class InvokerWrapper<T> {
|
||||
|
||||
public EventPriority priority;
|
||||
public T invoker;
|
||||
|
||||
public InvokerWrapper(EventPriority priority, T invoker) {
|
||||
this.priority = priority;
|
||||
this.invoker = invoker;
|
||||
}
|
||||
|
||||
public T getInvoker() {
|
||||
return this.invoker;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.loohp.limbo.events.impl;
|
||||
|
||||
import com.loohp.limbo.events.api.Event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
||||
// As required by the Apache License, Version 2.0 we are required to
|
||||
// mention that we decided to delete the second method in this class.
|
||||
// It was considered unnecessary code by us and thus remove, (this also influences the imports)
|
||||
public final class EventFactoryImpl {
|
||||
private static final List<ArrayBackedEvent<?>> ARRAY_BACKED_EVENTS = new ArrayList<>();
|
||||
|
||||
private EventFactoryImpl() { }
|
||||
|
||||
public static void invalidate() {
|
||||
ARRAY_BACKED_EVENTS.forEach(ArrayBackedEvent::update);
|
||||
}
|
||||
|
||||
public static <T> Event<T> createArrayBacked(Class<? super T> type, Function<T[], T> invokerFactory) {
|
||||
ArrayBackedEvent<T> event = new ArrayBackedEvent<>(type, invokerFactory);
|
||||
ARRAY_BACKED_EVENTS.add(event);
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +1,51 @@
|
|||
package com.loohp.limbo.events.player;
|
||||
|
||||
import com.loohp.limbo.events.Cancellable;
|
||||
import com.loohp.limbo.events.api.Event;
|
||||
import com.loohp.limbo.events.api.EventFactory;
|
||||
import com.loohp.limbo.player.Player;
|
||||
|
||||
public class PlayerChatEvent extends PlayerEvent implements Cancellable {
|
||||
public class PlayerChatEvent extends PlayerEvent {
|
||||
|
||||
/**
|
||||
* This callback will be invoked every time the server receives a chat message
|
||||
*
|
||||
* Cancelling this event will prevent the chat message from being sent to all connected clients
|
||||
*/
|
||||
public static final Event<PlayerChatEventCallback> PLAYER_CHAT_EVENT = EventFactory.createArrayBacked(PlayerChatEventCallback.class, (_1, cancel) -> cancel, callbacks -> (event, _isCancelled) -> {
|
||||
boolean isCancelled = _isCancelled;
|
||||
for (PlayerChatEventCallback callback : callbacks) {
|
||||
isCancelled = callback.onPlayerChat(event, isCancelled);
|
||||
}
|
||||
return isCancelled;
|
||||
});
|
||||
|
||||
public interface PlayerChatEventCallback {
|
||||
/**
|
||||
* Callback for the {@link PlayerChatEvent}
|
||||
* This will initiate the event as non-cancelled
|
||||
* @param event the chat event
|
||||
* @return true to cancel the event, otherwise return false
|
||||
*/
|
||||
default boolean onPlayerChat(PlayerChatEvent event) {
|
||||
return this.onPlayerChat(event, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the {@link PlayerChatEvent}
|
||||
* @param event the chat event
|
||||
* @param isCancelled whether the event was cancelled before reaching this callback
|
||||
* @return true to cancel the event, otherwise return false
|
||||
*/
|
||||
boolean onPlayerChat(PlayerChatEvent event, boolean isCancelled);
|
||||
}
|
||||
|
||||
private String format;
|
||||
private String message;
|
||||
private boolean cancelled;
|
||||
|
||||
public PlayerChatEvent(Player player, String format, String message, boolean cancelled) {
|
||||
public PlayerChatEvent(Player player, String format, String message) {
|
||||
super(player);
|
||||
this.format = format;
|
||||
this.message = message;
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
public String getFormat() {
|
||||
|
|
@ -32,14 +64,4 @@ public class PlayerChatEvent extends PlayerEvent implements Cancellable {
|
|||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
package com.loohp.limbo.events.player;
|
||||
|
||||
import com.loohp.limbo.events.Event;
|
||||
import com.loohp.limbo.player.Player;
|
||||
|
||||
public class PlayerEvent extends Event {
|
||||
public class PlayerEvent {
|
||||
|
||||
private Player player;
|
||||
private final Player player;
|
||||
|
||||
public PlayerEvent(Player player) {
|
||||
this.player = player;
|
||||
|
|
|
|||
|
|
@ -1,22 +1,24 @@
|
|||
package com.loohp.limbo.events.player;
|
||||
|
||||
import com.loohp.limbo.events.api.Event;
|
||||
import com.loohp.limbo.events.api.EventFactory;
|
||||
import com.loohp.limbo.location.Location;
|
||||
import com.loohp.limbo.player.Player;
|
||||
|
||||
public class PlayerJoinEvent extends PlayerEvent {
|
||||
public interface PlayerJoinEvent {
|
||||
|
||||
private Location spawnLocation;
|
||||
|
||||
public PlayerJoinEvent(Player player, Location spawnLoc) {
|
||||
super(player);
|
||||
spawnLocation = spawnLoc;
|
||||
}
|
||||
|
||||
public Location getSpawnLocation() {
|
||||
/**
|
||||
* Called whenever a player joins the server
|
||||
*
|
||||
* This event can be used to change the spawn location of the player
|
||||
*/
|
||||
Event<PlayerJoinEvent> PLAYER_JOIN_EVENT = EventFactory.createArrayBacked(PlayerJoinEvent.class, (_1, location) -> location, callbacks -> (player, _spawnLocation) -> {
|
||||
Location spawnLocation = _spawnLocation;
|
||||
for (PlayerJoinEvent callback : callbacks) {
|
||||
spawnLocation = callback.onPlayerJoin(player, spawnLocation);
|
||||
}
|
||||
return spawnLocation;
|
||||
}
|
||||
});
|
||||
|
||||
public void setSpawnLocation(Location spawnLocation) {
|
||||
this.spawnLocation = spawnLocation;
|
||||
}
|
||||
Location onPlayerJoin(Player player, Location spawnLocation);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,50 @@
|
|||
package com.loohp.limbo.events.player;
|
||||
|
||||
import com.loohp.limbo.events.Cancellable;
|
||||
import com.loohp.limbo.events.Event;
|
||||
import com.loohp.limbo.events.api.Event;
|
||||
import com.loohp.limbo.events.api.EventFactory;
|
||||
import com.loohp.limbo.server.ClientConnection;
|
||||
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
|
||||
public class PlayerLoginEvent extends Event implements Cancellable {
|
||||
public class PlayerLoginEvent {
|
||||
|
||||
private ClientConnection connection;
|
||||
private boolean cancelled;
|
||||
/**
|
||||
* Called when a player logs into the server (protocol-wise right before the Login Success Packet would be sent)
|
||||
*
|
||||
* Cancelling this event will prevent the player from joining the server
|
||||
*/
|
||||
public static Event<PlayerLoginEventCallback> PLAYER_LOGIN_EVENT = EventFactory.createArrayBacked(PlayerLoginEventCallback.class, (_1, cancel) -> cancel, callbacks -> (event, _isCancelled) -> {
|
||||
boolean isCancelled = _isCancelled;
|
||||
for (PlayerLoginEventCallback callback : callbacks) {
|
||||
isCancelled = callback.onPlayerLoginEvent(event, isCancelled);
|
||||
}
|
||||
return isCancelled;
|
||||
});
|
||||
|
||||
public interface PlayerLoginEventCallback {
|
||||
/**
|
||||
* Callback for the {@link PlayerLoginEvent}
|
||||
* This will initiate the event as non-cancelled
|
||||
* @param event the chat event
|
||||
* @return true to cancel the event, otherwise return false
|
||||
*/
|
||||
default boolean onPlayerLoginEvent(PlayerLoginEvent event) {
|
||||
return this.onPlayerLoginEvent(event, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the {@link PlayerLoginEvent}
|
||||
* @param event the login event
|
||||
* @param isCancelled whether the event was cancelled before reaching this callback
|
||||
* @return true to cancel the event, otherwise return false
|
||||
*/
|
||||
boolean onPlayerLoginEvent(PlayerLoginEvent event, boolean isCancelled);
|
||||
}
|
||||
|
||||
private final ClientConnection connection;
|
||||
private BaseComponent[] cancelReason;
|
||||
|
||||
public PlayerLoginEvent(ClientConnection connection, boolean cancelled, BaseComponent... cancelReason) {
|
||||
public PlayerLoginEvent(ClientConnection connection, BaseComponent... cancelReason) {
|
||||
this.connection = connection;
|
||||
this.cancelled = cancelled;
|
||||
this.cancelReason = cancelReason;
|
||||
}
|
||||
|
||||
|
|
@ -30,14 +60,4 @@ public class PlayerLoginEvent extends Event implements Cancellable {
|
|||
this.cancelReason = cancelReason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,48 @@
|
|||
package com.loohp.limbo.events.player;
|
||||
|
||||
import com.loohp.limbo.events.Cancellable;
|
||||
import com.loohp.limbo.events.api.Event;
|
||||
import com.loohp.limbo.events.api.EventFactory;
|
||||
import com.loohp.limbo.location.Location;
|
||||
import com.loohp.limbo.player.Player;
|
||||
|
||||
/**
|
||||
* Holds information for player movement events
|
||||
*/
|
||||
public class PlayerMoveEvent extends PlayerEvent implements Cancellable {
|
||||
public class PlayerMoveEvent extends PlayerEvent {
|
||||
|
||||
/**
|
||||
* Called when the player sends a movement packet
|
||||
*
|
||||
* Cancelling this event will cause the player to stay in place
|
||||
*/
|
||||
public static final Event<PlayerMoveEventCallback> PLAYER_MOVE_EVENT = EventFactory.createArrayBacked(PlayerMoveEventCallback.class, (_1, cancel) -> cancel, callbacks -> (event, _isCancelled) -> {
|
||||
boolean isCancelled = _isCancelled;
|
||||
for (PlayerMoveEventCallback callback : callbacks) {
|
||||
isCancelled = callback.onPlayerMove(event, isCancelled);
|
||||
}
|
||||
return isCancelled;
|
||||
});
|
||||
|
||||
public interface PlayerMoveEventCallback {
|
||||
/**
|
||||
* Callback for the {@link PlayerMoveEvent}
|
||||
* This will initiate the event as non-cancelled
|
||||
* @param event the move event
|
||||
* @return true to cancel the event, otherwise return false
|
||||
*/
|
||||
default boolean onPlayerMove(PlayerMoveEvent event) {
|
||||
return this.onPlayerMove(event, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the {@link PlayerMoveEvent}
|
||||
* @param event the move event
|
||||
* @param isCancelled whether the event was cancelled before reaching this callback
|
||||
* @return true to cancel the event, otherwise return false
|
||||
*/
|
||||
boolean onPlayerMove(PlayerMoveEvent event, boolean isCancelled);
|
||||
}
|
||||
|
||||
private boolean cancel = false;
|
||||
private Location from;
|
||||
private Location to;
|
||||
|
||||
|
|
@ -19,36 +52,6 @@ public class PlayerMoveEvent extends PlayerEvent implements Cancellable {
|
|||
this.to = to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cancellation state of this event. A cancelled event will not
|
||||
* be executed in the server, but will still pass to other plugins
|
||||
* <p>
|
||||
* If a move or teleport event is cancelled, the player will be moved or
|
||||
* teleported back to the Location as defined by getFrom(). This will not
|
||||
* fire an event
|
||||
*
|
||||
* @return true if this event is cancelled
|
||||
*/
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cancellation state of this event. A cancelled event will not
|
||||
* be executed in the server, but will still pass to other plugins
|
||||
* <p>
|
||||
* If a move or teleport event is cancelled, the player will be moved or
|
||||
* teleported back to the Location as defined by getFrom(). This will not
|
||||
* fire an event
|
||||
*
|
||||
* @param cancel true if you wish to cancel this event
|
||||
*/
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location this player moved from
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,11 +1,20 @@
|
|||
package com.loohp.limbo.events.player;
|
||||
|
||||
import com.loohp.limbo.events.api.Event;
|
||||
import com.loohp.limbo.events.api.EventFactory;
|
||||
import com.loohp.limbo.player.Player;
|
||||
|
||||
public class PlayerQuitEvent extends PlayerEvent {
|
||||
public interface PlayerQuitEvent {
|
||||
|
||||
public PlayerQuitEvent(Player player) {
|
||||
super(player);
|
||||
}
|
||||
/**
|
||||
* Called whenever a player leaves the server
|
||||
*/
|
||||
Event<PlayerQuitEvent> PLAYER_QUIT_EVENT = EventFactory.createArrayBacked(PlayerQuitEvent.class, _player -> {}, callbacks -> player -> {
|
||||
for (PlayerQuitEvent callback : callbacks) {
|
||||
callback.onPlayerQuit(player);
|
||||
}
|
||||
});
|
||||
|
||||
void onPlayerQuit(Player player);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,43 @@
|
|||
package com.loohp.limbo.events.player;
|
||||
|
||||
import com.loohp.limbo.events.Cancellable;
|
||||
import com.loohp.limbo.events.api.Event;
|
||||
import com.loohp.limbo.events.api.EventFactory;
|
||||
import com.loohp.limbo.player.Player;
|
||||
|
||||
public class PlayerSelectedSlotChangeEvent extends PlayerEvent implements Cancellable {
|
||||
public class PlayerSelectedSlotChangeEvent extends PlayerEvent {
|
||||
|
||||
/**
|
||||
* Called when the client sends a Held Item Change Packet
|
||||
*
|
||||
* Cancelling this event will force the player to keep the same slot selected
|
||||
*/
|
||||
public static final Event<PlayerSelectedSlotChangeEventCallback> PLAYER_SELECTED_SLOT_CHANGE_EVENT = EventFactory.createArrayBacked(PlayerSelectedSlotChangeEventCallback.class, (_1, cancel) -> cancel, callbacks -> (event, _isCancelled) -> {
|
||||
boolean isCancelled = _isCancelled;
|
||||
for (PlayerSelectedSlotChangeEventCallback callback : callbacks) {
|
||||
isCancelled = callback.onPlayerSelectedSlotChange(event, isCancelled);
|
||||
}
|
||||
return isCancelled;
|
||||
});
|
||||
|
||||
public interface PlayerSelectedSlotChangeEventCallback {
|
||||
|
||||
/**
|
||||
* Callback for the {@link PlayerSelectedSlotChangeEvent}
|
||||
* This will initiate the event as non-cancelled
|
||||
* @return true to cancel the event, otherwise return false
|
||||
*/
|
||||
default boolean onPlayerSelectedSlotChange(PlayerSelectedSlotChangeEvent event) {
|
||||
return this.onPlayerSelectedSlotChange(event, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the {@link PlayerSelectedSlotChangeEvent}
|
||||
* @param isCancelled whether the event was cancelled before reaching this callback
|
||||
* @return true to cancel the event, otherwise return false
|
||||
*/
|
||||
boolean onPlayerSelectedSlotChange(PlayerSelectedSlotChangeEvent event, boolean isCancelled);
|
||||
}
|
||||
|
||||
private boolean cancel = false;
|
||||
private byte slot;
|
||||
|
||||
public PlayerSelectedSlotChangeEvent(Player player, byte slot) {
|
||||
|
|
@ -13,16 +45,6 @@ public class PlayerSelectedSlotChangeEvent extends PlayerEvent implements Cancel
|
|||
this.slot = slot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancel = cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancel;
|
||||
}
|
||||
|
||||
public byte getSlot() {
|
||||
return slot;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,43 @@
|
|||
package com.loohp.limbo.events.player;
|
||||
|
||||
import com.loohp.limbo.events.api.Event;
|
||||
import com.loohp.limbo.events.api.EventFactory;
|
||||
import com.loohp.limbo.location.Location;
|
||||
import com.loohp.limbo.player.Player;
|
||||
|
||||
public class PlayerTeleportEvent extends PlayerMoveEvent {
|
||||
|
||||
/**
|
||||
* Called when the player is about to teleport
|
||||
*
|
||||
* Cancelling this event will prevent the player from being teleported
|
||||
*/
|
||||
public static final Event<PlayerTeleportEventCallback> PLAYER_TELEPORT_EVENT = EventFactory.createArrayBacked(PlayerTeleportEventCallback.class, (_1, cancel) -> cancel, callbacks -> (event, _isCancelled) -> {
|
||||
boolean isCancelled = _isCancelled;
|
||||
for (PlayerTeleportEventCallback callback : callbacks) {
|
||||
isCancelled = callback.onPlayerTeleport(event, isCancelled);
|
||||
}
|
||||
return isCancelled;
|
||||
});
|
||||
|
||||
public interface PlayerTeleportEventCallback {
|
||||
/**
|
||||
* Callback for {@link PlayerTeleportEvent}
|
||||
* This will initiate the event as non-cancelled
|
||||
* @return true to cancel the event, otherwise return false
|
||||
*/
|
||||
default boolean onPlayerTeleport(PlayerTeleportEvent event) {
|
||||
return this.onPlayerTeleport(event, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for {@link PlayerTeleportEvent}
|
||||
* @param isCancelled whether the event was cancelled before reaching this callback
|
||||
* @return true to cancel the event, otherwise return false
|
||||
*/
|
||||
boolean onPlayerTeleport(PlayerTeleportEvent event, boolean isCancelled);
|
||||
}
|
||||
|
||||
public PlayerTeleportEvent(Player player, Location from, Location to) {
|
||||
super(player, from, to);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,35 @@
|
|||
package com.loohp.limbo.events.status;
|
||||
|
||||
import com.loohp.limbo.events.api.Event;
|
||||
import com.loohp.limbo.events.api.EventFactory;
|
||||
import com.loohp.limbo.server.ClientConnection;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import com.loohp.limbo.events.Event;
|
||||
import com.loohp.limbo.server.ClientConnection;
|
||||
public class StatusPingEvent {
|
||||
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
/**
|
||||
* Called when the ping request is being constructed
|
||||
*
|
||||
* Can be used to alter the status information
|
||||
*/
|
||||
public static final Event<StatusPingEventCallback> STATUS_PING_EVENT = EventFactory.createArrayBacked(StatusPingEventCallback.class, event -> {}, callbacks -> statusPingEvent -> {
|
||||
for (StatusPingEventCallback callback : callbacks) {
|
||||
callback.onStatusPing(statusPingEvent);
|
||||
}
|
||||
});
|
||||
|
||||
public class StatusPingEvent extends Event {
|
||||
public interface StatusPingEventCallback {
|
||||
|
||||
private ClientConnection connection;
|
||||
/**
|
||||
* Callback for the {@link StatusPingEvent}
|
||||
* @return the (modified) event that will be used to construct a response
|
||||
*/
|
||||
void onStatusPing(StatusPingEvent statusData);
|
||||
}
|
||||
|
||||
private final ClientConnection connection;
|
||||
private String version;
|
||||
private int protocol;
|
||||
private BaseComponent[] motd;
|
||||
|
|
|
|||
|
|
@ -1,30 +1,25 @@
|
|||
package com.loohp.limbo.player;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.loohp.limbo.Limbo;
|
||||
import com.loohp.limbo.events.player.PlayerChatEvent;
|
||||
import com.loohp.limbo.events.player.PlayerTeleportEvent;
|
||||
import com.loohp.limbo.server.ClientConnection;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutChat;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutGameState;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutHeldItemChange;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutPositionAndLook;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutRespawn;
|
||||
import com.loohp.limbo.commands.CommandSender;
|
||||
import com.loohp.limbo.entity.DataWatcher;
|
||||
import com.loohp.limbo.entity.EntityType;
|
||||
import com.loohp.limbo.entity.LivingEntity;
|
||||
import com.loohp.limbo.entity.DataWatcher.WatchableField;
|
||||
import com.loohp.limbo.entity.DataWatcher.WatchableObjectType;
|
||||
import com.loohp.limbo.entity.EntityType;
|
||||
import com.loohp.limbo.entity.LivingEntity;
|
||||
import com.loohp.limbo.events.player.PlayerChatEvent;
|
||||
import com.loohp.limbo.events.player.PlayerTeleportEvent;
|
||||
import com.loohp.limbo.location.Location;
|
||||
import com.loohp.limbo.server.ClientConnection;
|
||||
import com.loohp.limbo.server.packets.*;
|
||||
import com.loohp.limbo.utils.GameMode;
|
||||
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
public class Player extends LivingEntity implements CommandSender {
|
||||
|
||||
public final ClientConnection clientConnection;
|
||||
|
|
@ -173,8 +168,8 @@ public class Player extends LivingEntity implements CommandSender {
|
|||
|
||||
@Override
|
||||
public void teleport(Location location) {
|
||||
PlayerTeleportEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerTeleportEvent(this, getLocation(), location));
|
||||
if (!event.isCancelled()) {
|
||||
PlayerTeleportEvent event = new PlayerTeleportEvent(this, getLocation(), location);
|
||||
if (!PlayerTeleportEvent.PLAYER_TELEPORT_EVENT.invoker().onPlayerTeleport(event)) {
|
||||
location = event.getTo();
|
||||
super.teleport(location);
|
||||
try {
|
||||
|
|
@ -248,8 +243,8 @@ public class Player extends LivingEntity implements CommandSender {
|
|||
|
||||
public void chat(String message) {
|
||||
String format = "<%name%> %message%";
|
||||
PlayerChatEvent event = (PlayerChatEvent) Limbo.getInstance().getEventsManager().callEvent(new PlayerChatEvent(this, format, message, false));
|
||||
if (!event.isCancelled()) {
|
||||
PlayerChatEvent event = new PlayerChatEvent(this, format, message);
|
||||
if (!PlayerChatEvent.PLAYER_CHAT_EVENT.invoker().onPlayerChat(event)) {
|
||||
String chat = event.getFormat().replace("%name%", username).replace("%message%", event.getMessage());
|
||||
Limbo.getInstance().getConsole().sendMessage(chat);
|
||||
for (Player each : Limbo.getInstance().getPlayers()) {
|
||||
|
|
|
|||
|
|
@ -1,81 +1,38 @@
|
|||
package com.loohp.limbo.server;
|
||||
|
||||
import com.loohp.limbo.Limbo;
|
||||
import com.loohp.limbo.events.player.*;
|
||||
import com.loohp.limbo.events.status.StatusPingEvent;
|
||||
import com.loohp.limbo.file.ServerProperties;
|
||||
import com.loohp.limbo.location.Location;
|
||||
import com.loohp.limbo.player.Player;
|
||||
import com.loohp.limbo.player.PlayerInteractManager;
|
||||
import com.loohp.limbo.server.packets.*;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutPlayerAbilities.PlayerAbilityFlags;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutPlayerInfo.PlayerInfoAction;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutPlayerInfo.PlayerInfoData;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutPlayerInfo.PlayerInfoData.PlayerInfoDataAddPlayer.PlayerSkinProperty;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutTabComplete.TabCompleteMatches;
|
||||
import com.loohp.limbo.utils.*;
|
||||
import com.loohp.limbo.utils.MojangAPIUtils.SkinResponse;
|
||||
import com.loohp.limbo.world.BlockPosition;
|
||||
import com.loohp.limbo.world.World;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.loohp.limbo.Limbo;
|
||||
import com.loohp.limbo.events.player.PlayerJoinEvent;
|
||||
import com.loohp.limbo.events.player.PlayerLoginEvent;
|
||||
import com.loohp.limbo.events.player.PlayerMoveEvent;
|
||||
import com.loohp.limbo.events.player.PlayerQuitEvent;
|
||||
import com.loohp.limbo.events.player.PlayerSelectedSlotChangeEvent;
|
||||
import com.loohp.limbo.events.status.StatusPingEvent;
|
||||
import com.loohp.limbo.file.ServerProperties;
|
||||
import com.loohp.limbo.location.Location;
|
||||
import com.loohp.limbo.player.Player;
|
||||
import com.loohp.limbo.player.PlayerInteractManager;
|
||||
import com.loohp.limbo.server.packets.Packet;
|
||||
import com.loohp.limbo.server.packets.PacketHandshakingIn;
|
||||
import com.loohp.limbo.server.packets.PacketLoginInLoginStart;
|
||||
import com.loohp.limbo.server.packets.PacketLoginOutDisconnect;
|
||||
import com.loohp.limbo.server.packets.PacketLoginOutLoginSuccess;
|
||||
import com.loohp.limbo.server.packets.PacketOut;
|
||||
import com.loohp.limbo.server.packets.PacketPlayInChat;
|
||||
import com.loohp.limbo.server.packets.PacketPlayInHeldItemChange;
|
||||
import com.loohp.limbo.server.packets.PacketPlayInKeepAlive;
|
||||
import com.loohp.limbo.server.packets.PacketPlayInPosition;
|
||||
import com.loohp.limbo.server.packets.PacketPlayInPositionAndLook;
|
||||
import com.loohp.limbo.server.packets.PacketPlayInRotation;
|
||||
import com.loohp.limbo.server.packets.PacketPlayInTabComplete;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutDeclareCommands;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutDisconnect;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutEntityMetadata;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutGameState;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutHeldItemChange;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutLogin;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutPlayerAbilities;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutPlayerAbilities.PlayerAbilityFlags;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutPlayerInfo;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutPlayerInfo.PlayerInfoAction;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutPlayerInfo.PlayerInfoData;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutPlayerInfo.PlayerInfoData.PlayerInfoDataAddPlayer.PlayerSkinProperty;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutPositionAndLook;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutSpawnPosition;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutTabComplete;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutTabComplete.TabCompleteMatches;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutUpdateViewPosition;
|
||||
import com.loohp.limbo.server.packets.PacketStatusInPing;
|
||||
import com.loohp.limbo.server.packets.PacketStatusInRequest;
|
||||
import com.loohp.limbo.server.packets.PacketStatusOutPong;
|
||||
import com.loohp.limbo.server.packets.PacketStatusOutResponse;
|
||||
import com.loohp.limbo.utils.CustomStringUtils;
|
||||
import com.loohp.limbo.utils.DataTypeIO;
|
||||
import com.loohp.limbo.utils.DeclareCommands;
|
||||
import com.loohp.limbo.utils.GameMode;
|
||||
import com.loohp.limbo.utils.MojangAPIUtils;
|
||||
import com.loohp.limbo.utils.MojangAPIUtils.SkinResponse;
|
||||
import com.loohp.limbo.utils.NamespacedKey;
|
||||
import com.loohp.limbo.world.BlockPosition;
|
||||
import com.loohp.limbo.world.World;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
|
||||
public class ClientConnection extends Thread {
|
||||
|
||||
public static enum ClientState {
|
||||
|
|
@ -186,7 +143,8 @@ public class ClientConnection extends Thread {
|
|||
String str = inetAddress.getHostName() + ":" + client_socket.getPort();
|
||||
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Legacy Status has pinged");
|
||||
ServerProperties p = Limbo.getInstance().getServerProperties();
|
||||
StatusPingEvent event = Limbo.getInstance().getEventsManager().callEvent(new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), ComponentSerializer.parse(p.getMotdJson()), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null)));
|
||||
StatusPingEvent event = new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), ComponentSerializer.parse(p.getMotdJson()), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null));
|
||||
StatusPingEvent.STATUS_PING_EVENT.invoker().onStatusPing(event);
|
||||
String response = Limbo.getInstance().buildLegacyPingResponse(event.getVersion(), event.getMotd(), event.getMaxPlayers(), event.getPlayersOnline());
|
||||
byte[] bytes = response.getBytes(StandardCharsets.UTF_16BE);
|
||||
output.writeShort(response.length());
|
||||
|
|
@ -222,7 +180,8 @@ public class ClientConnection extends Thread {
|
|||
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Handshake Status has pinged");
|
||||
}
|
||||
ServerProperties p = Limbo.getInstance().getServerProperties();
|
||||
StatusPingEvent event = Limbo.getInstance().getEventsManager().callEvent(new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), ComponentSerializer.parse(p.getMotdJson()), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null)));
|
||||
StatusPingEvent event = new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), ComponentSerializer.parse(p.getMotdJson()), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null));
|
||||
StatusPingEvent.STATUS_PING_EVENT.invoker().onStatusPing(event);
|
||||
PacketStatusOutResponse packet = new PacketStatusOutResponse(Limbo.getInstance().buildServerListResponseJson(event.getVersion(), event.getProtocol(), event.getMotd(), event.getMaxPlayers(), event.getPlayersOnline(), event.getFavicon()));
|
||||
sendPacket(packet);
|
||||
} else if (packetType.equals(PacketStatusInPing.class)) {
|
||||
|
|
@ -270,6 +229,12 @@ public class ClientConnection extends Thread {
|
|||
String username = start.getUsername();
|
||||
UUID uuid = isBungeecord ? bungeeUUID : UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
PlayerLoginEvent event = new PlayerLoginEvent(this);
|
||||
if (PlayerLoginEvent.PLAYER_LOGIN_EVENT.invoker().onPlayerLoginEvent(event)) {
|
||||
disconnectDuringLogin(event.getCancelReason());
|
||||
break;
|
||||
}
|
||||
|
||||
PacketLoginOutLoginSuccess success = new PacketLoginOutLoginSuccess(uuid, username);
|
||||
sendPacket(success);
|
||||
|
||||
|
|
@ -285,11 +250,6 @@ public class ClientConnection extends Thread {
|
|||
}
|
||||
}
|
||||
|
||||
PlayerLoginEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerLoginEvent(this, false));
|
||||
if (event.isCancelled()) {
|
||||
disconnectDuringLogin(event.getCancelReason());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
|
@ -304,8 +264,7 @@ public class ClientConnection extends Thread {
|
|||
ServerProperties properties = Limbo.getInstance().getServerProperties();
|
||||
Location worldSpawn = properties.getWorldSpawn();
|
||||
|
||||
PlayerJoinEvent joinEvent = Limbo.getInstance().getEventsManager().callEvent(new PlayerJoinEvent(player, worldSpawn));
|
||||
worldSpawn = joinEvent.getSpawnLocation();
|
||||
worldSpawn = PlayerJoinEvent.PLAYER_JOIN_EVENT.invoker().onPlayerJoin(player, worldSpawn);
|
||||
World world = worldSpawn.getWorld();
|
||||
|
||||
PacketPlayOutLogin join = new PacketPlayOutLogin(player.getEntityId(), false, properties.getDefaultGamemode(), Limbo.getInstance().getWorlds().stream().map(each -> new NamespacedKey(each.getName()).toString()).collect(Collectors.toList()).toArray(new String[Limbo.getInstance().getWorlds().size()]), Limbo.getInstance().getDimensionRegistry().getCodec(), world, 0, (byte) properties.getMaxPlayers(), 8, properties.isReducedDebugInfo(), true, false, true);
|
||||
|
|
@ -363,7 +322,7 @@ public class ClientConnection extends Thread {
|
|||
//Limbo.getInstance().getConsole().sendMessage(packetId + " -> " + packetType);
|
||||
CheckedConsumer<PlayerMoveEvent, IOException> processMoveEvent = event -> {
|
||||
Location originalTo = event.getTo().clone();
|
||||
if (event.isCancelled()) {
|
||||
if (PlayerMoveEvent.PLAYER_MOVE_EVENT.invoker().onPlayerMove(event)) {
|
||||
Location returnTo = event.getFrom();
|
||||
PacketPlayOutPositionAndLook cancel = new PacketPlayOutPositionAndLook(returnTo.getX(), returnTo.getY(), returnTo.getZ(), returnTo.getYaw(), returnTo.getPitch(), 1, false);
|
||||
sendPacket(cancel);
|
||||
|
|
@ -386,21 +345,21 @@ public class ClientConnection extends Thread {
|
|||
Location from = player.getLocation();
|
||||
Location to = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ(), pos.getYaw(), pos.getPitch());
|
||||
|
||||
PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to));
|
||||
PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
|
||||
processMoveEvent.consume(event);
|
||||
} else if (packetType.equals(PacketPlayInPosition.class)) {
|
||||
PacketPlayInPosition pos = new PacketPlayInPosition(input);
|
||||
Location from = player.getLocation();
|
||||
Location to = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ(), player.getLocation().getYaw(), player.getLocation().getPitch());
|
||||
|
||||
PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to));
|
||||
PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
|
||||
processMoveEvent.consume(event);
|
||||
} else if (packetType.equals(PacketPlayInRotation.class)) {
|
||||
PacketPlayInRotation pos = new PacketPlayInRotation(input);
|
||||
Location from = player.getLocation();
|
||||
Location to = new Location(player.getWorld(), player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), pos.getYaw(), pos.getPitch());
|
||||
|
||||
PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to));
|
||||
PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
|
||||
processMoveEvent.consume(event);
|
||||
} else if (packetType.equals(PacketPlayInKeepAlive.class)) {
|
||||
PacketPlayInKeepAlive alive = new PacketPlayInKeepAlive(input);
|
||||
|
|
@ -430,8 +389,8 @@ public class ClientConnection extends Thread {
|
|||
}
|
||||
} else if (packetType.equals(PacketPlayInHeldItemChange.class)) {
|
||||
PacketPlayInHeldItemChange change = new PacketPlayInHeldItemChange(input);
|
||||
PlayerSelectedSlotChangeEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerSelectedSlotChangeEvent(player, (byte) change.getSlot()));
|
||||
if (event.isCancelled()) {
|
||||
PlayerSelectedSlotChangeEvent event = new PlayerSelectedSlotChangeEvent(player, (byte) change.getSlot());
|
||||
if (PlayerSelectedSlotChangeEvent.PLAYER_SELECTED_SLOT_CHANGE_EVENT.invoker().onPlayerSelectedSlotChange(event)) {
|
||||
PacketPlayOutHeldItemChange cancelPacket = new PacketPlayOutHeldItemChange(player.getSelectedSlot());
|
||||
sendPacket(cancelPacket);
|
||||
} else if (change.getSlot() != event.getSlot()) {
|
||||
|
|
@ -450,7 +409,7 @@ public class ClientConnection extends Thread {
|
|||
}
|
||||
}
|
||||
|
||||
Limbo.getInstance().getEventsManager().callEvent(new PlayerQuitEvent(player));
|
||||
PlayerQuitEvent.PLAYER_QUIT_EVENT.invoker().onPlayerQuit(player);
|
||||
|
||||
str = inetAddress.getHostName() + ":" + client_socket.getPort() + "|" + player.getName();
|
||||
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Player had disconnected!");
|
||||
|
|
|
|||
Loading…
Reference in New Issue