("mavenJava") {
68 | groupId = "${project.group}"
69 | artifactId = "${rootProject.name}-${project.name}"
70 | version = "${project.version}"
71 | from(components["java"])
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/Guithium.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api;
2 |
3 | import net.pl3x.guithium.api.action.ActionRegistry;
4 | import net.pl3x.guithium.api.gui.texture.TextureManager;
5 | import net.pl3x.guithium.api.network.NetworkHandler;
6 | import net.pl3x.guithium.api.player.PlayerManager;
7 | import org.apache.commons.lang3.StringUtils;
8 | import org.jetbrains.annotations.NotNull;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | /**
13 | * The Guithium API.
14 | */
15 | public interface Guithium {
16 | /**
17 | * The identifier for this mod.
18 | */
19 | String MOD_ID = "guithium";
20 |
21 | /**
22 | * The protocol version.
23 | *
24 | * This is used to ensure client and server can correctly talk to each other.
25 | */
26 | int PROTOCOL = 1;
27 |
28 | /**
29 | * bStats ID number for Guithium.
30 | */
31 | int BSTATS_ID = 25813;
32 |
33 | /**
34 | * Guithium's internal logger.
35 | *
36 | * For internal use . Please use your own logger.
37 | */
38 | Logger logger = LoggerFactory.getLogger(StringUtils.capitalize(Guithium.MOD_ID));
39 |
40 | /**
41 | * Get the Guithium API instance.
42 | *
43 | * @return Instance of Guithium API
44 | */
45 | @NotNull
46 | static Guithium api() {
47 | return Provider.api();
48 | }
49 |
50 | /**
51 | * Get the Guithium's version.
52 | *
53 | * @return Guithium's version
54 | */
55 | @NotNull
56 | String getVersion();
57 |
58 | /**
59 | * Get the action registry instance.
60 | *
61 | * @return Action registry
62 | */
63 | @NotNull
64 | ActionRegistry getActionRegistry();
65 |
66 | /**
67 | * Get the network handler instance.
68 | *
69 | * @return Network handler
70 | */
71 | @NotNull
72 | NetworkHandler getNetworkHandler();
73 |
74 | /**
75 | * Get the player manager instance.
76 | *
77 | * @return Player manager
78 | */
79 | @NotNull
80 | PlayerManager getPlayerManager();
81 |
82 | /**
83 | * Get the texture manager instance.
84 | *
85 | * @return Texture manager
86 | */
87 | @NotNull
88 | TextureManager getTextureManager();
89 |
90 | /**
91 | * The Guithium instance provider.
92 | *
93 | * For internal use .
94 | */
95 | final class Provider {
96 | static Guithium api;
97 |
98 | private Provider() {
99 | // Empty constructor to pacify javadoc lint
100 | }
101 |
102 | @NotNull
103 | private static Guithium api() {
104 | return Provider.api;
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/Unsafe.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.ElementType;
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 | import java.lang.annotation.Target;
8 | import org.jetbrains.annotations.NonNls;
9 |
10 | /**
11 | * Unsafe utils
12 | */
13 | public abstract class Unsafe {
14 | private Unsafe() {
15 | // Empty constructor to pacify javadoc lint
16 | }
17 |
18 | /**
19 | * Cast object to T
20 | *
21 | * @param obj Object to cast
22 | * @param Type to cast to
23 | * @return Object as T
24 | */
25 | @UnknownNullability
26 | @SuppressWarnings("unchecked")
27 | public static T cast(@UnknownNullability Object obj) {
28 | return (T) obj;
29 | }
30 |
31 | /**
32 | * An element annotated with {@code UnknownNullability} claims that no specific nullability
33 | * should be assumed by static analyzer. The unconditional dereference of the annotated value
34 | * should not trigger a static analysis warning by default (though static analysis tool may have
35 | * an option to perform stricter analysis and issue warnings for {@code @UnknownNullability} as well).
36 | * It's mainly useful at method return types to mark methods that may occasionally
37 | * return {@code null} but in many cases, user knows that in this particular code path
38 | * {@code null} is not possible, so producing a warning would be annoying.
39 | *
40 | * @since 21.0.0
41 | */
42 | @Documented
43 | @Retention(RetentionPolicy.CLASS)
44 | @Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})
45 | public @interface UnknownNullability {
46 | /**
47 | * Human-readable description of the circumstances, in which the type is nullable.
48 | *
49 | * @return textual reason when the annotated value could be null, for documentation purposes.
50 | */
51 | @NonNls String value() default "";
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/action/ActionListener.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.action;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Simple interface for tagging all action listeners.
10 | */
11 | public interface ActionListener {
12 | /**
13 | * An annotation to mark methods as being action handler methods.
14 | */
15 | @Target(ElementType.METHOD)
16 | @Retention(RetentionPolicy.RUNTIME)
17 | @interface ActionHandler {
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/action/ActionRegistry.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.action;
2 |
3 | import java.lang.reflect.Field;
4 | import java.lang.reflect.Method;
5 | import java.util.List;
6 | import net.pl3x.guithium.api.Guithium;
7 | import net.pl3x.guithium.api.action.actions.Action;
8 | import org.jetbrains.annotations.NotNull;
9 |
10 | /**
11 | * The action registry.
12 | */
13 | public class ActionRegistry {
14 | /**
15 | * Create a new action registry
16 | */
17 | public ActionRegistry() {
18 | // Empty constructor to pacify javadoc lint
19 | }
20 |
21 | /**
22 | * Call an action for plugins to listen to.
23 | *
24 | * @param action The action to call
25 | */
26 | public void callAction(@NotNull Action action) {
27 | for (RegisteredHandler handler : action.getHandlers()) {
28 | try {
29 | handler.execute(action);
30 | } catch (Throwable t) {
31 | Guithium.logger.error(t.getMessage(), t);
32 | }
33 | }
34 | }
35 |
36 | /**
37 | * Registers all the actions in the given listener class.
38 | *
39 | * @param listener Action listener to register
40 | */
41 | public void register(@NotNull ActionListener listener) {
42 | for (Method method : listener.getClass().getMethods()) {
43 | if (method.getDeclaredAnnotation(ActionListener.ActionHandler.class) == null) {
44 | continue;
45 | }
46 | Class>[] params = method.getParameterTypes();
47 | if (params.length == 0) {
48 | continue;
49 | }
50 | Class> action = params[0];
51 | if (!Action.class.isAssignableFrom(action)) {
52 | continue;
53 | }
54 | try {
55 | Field handlers = action.getDeclaredField("handlers");
56 | handlers.setAccessible(true);
57 |
58 | @SuppressWarnings("unchecked")
59 | List list = (List) handlers.get(action);
60 |
61 | RegisteredHandler handler = new RegisteredHandler(listener, method);
62 | list.add(handler);
63 | } catch (NoSuchFieldException | IllegalAccessException e) {
64 | throw new RuntimeException(e);
65 | }
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/action/RegisteredHandler.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.action;
2 |
3 | import java.lang.reflect.InvocationTargetException;
4 | import java.lang.reflect.Method;
5 | import net.pl3x.guithium.api.action.actions.Action;
6 | import org.jetbrains.annotations.NotNull;
7 |
8 | /**
9 | * Represents a registered action handler.
10 | */
11 | public class RegisteredHandler {
12 | private final ActionListener listener;
13 | private Method method;
14 |
15 | /**
16 | * Create a new registered action handler.
17 | *
18 | * @param listener Action listener being registered
19 | * @param method Method being registered
20 | */
21 | public RegisteredHandler(@NotNull ActionListener listener, @NotNull Method method) {
22 | this.listener = listener;
23 | setMethod(method);
24 | }
25 |
26 | /**
27 | * Gets the registered action listener.
28 | *
29 | * @return Action listener
30 | */
31 | @NotNull
32 | public ActionListener getListener() {
33 | return this.listener;
34 | }
35 |
36 | /**
37 | * Gets the registered method.
38 | *
39 | * @return Action method
40 | */
41 | @NotNull
42 | public Method getMethod() {
43 | return this.method;
44 | }
45 |
46 | private void setMethod(@NotNull Method method) {
47 | method.setAccessible(true);
48 | this.method = method;
49 | }
50 |
51 | /**
52 | * Execute the method for the given action.
53 | *
54 | * @param action Action to call method on
55 | * @throws InvocationTargetException if the method throws an exception
56 | * @throws IllegalAccessException if this Method object is enforcing Java language access
57 | * control and the underlying method is inaccessible
58 | */
59 | public void execute(@NotNull Action action) throws InvocationTargetException, IllegalAccessException {
60 | getMethod().invoke(getListener(), action);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/action/actions/Action.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.action.actions;
2 |
3 | import java.util.List;
4 | import net.pl3x.guithium.api.action.RegisteredHandler;
5 | import org.jetbrains.annotations.NotNull;
6 |
7 | /**
8 | * Represents an action. This is similar to Bukkit events.
9 | */
10 | public abstract class Action {
11 | /**
12 | * Create a new action.
13 | */
14 | public Action() {
15 | // Empty constructor to pacify javadoc lint
16 | }
17 |
18 | /**
19 | * Get a list of all the registered handlers for this action.
20 | *
21 | * For internal use.
22 | *
23 | * @return List of registered handlers
24 | */
25 | @NotNull
26 | public abstract List getHandlers();
27 | }
28 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/action/actions/Cancellable.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.action.actions;
2 |
3 | /**
4 | * Represents a cancellable state.
5 | */
6 | public interface Cancellable {
7 | /**
8 | * Gets the cancellation state of this action. A cancelled action will not
9 | * be executed in the server, but will still pass to other plugins.
10 | *
11 | * @return True if this action is cancelled
12 | */
13 | boolean isCancelled();
14 |
15 | /**
16 | * Sets the cancellation state of this action. A cancelled action will not
17 | * be executed in the server, but will still pass to other plugins.
18 | *
19 | * @param cancelled True if you wish to cancel this action
20 | */
21 | void setCancelled(boolean cancelled);
22 | }
23 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/action/actions/player/PlayerAction.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.action.actions.player;
2 |
3 | import com.google.common.base.Preconditions;
4 | import net.pl3x.guithium.api.action.actions.Action;
5 | import net.pl3x.guithium.api.player.WrappedPlayer;
6 | import org.jetbrains.annotations.NotNull;
7 |
8 | /**
9 | * Action that fires when a player performs an action.
10 | */
11 | public abstract class PlayerAction extends Action {
12 | private final WrappedPlayer player;
13 |
14 | /**
15 | * Create a new action for when a player performs an action.
16 | *
17 | * @param player Player that performed the action
18 | */
19 | public PlayerAction(@NotNull WrappedPlayer player) {
20 | Preconditions.checkNotNull(player, "Player cannot be null.");
21 | this.player = player;
22 | }
23 |
24 | /**
25 | * Get the player that performed this action.
26 | *
27 | * @return Player
28 | */
29 | @NotNull
30 | public WrappedPlayer getPlayer() {
31 | return this.player;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/action/actions/player/PlayerJoinedAction.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.action.actions.player;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import net.pl3x.guithium.api.action.RegisteredHandler;
6 | import net.pl3x.guithium.api.network.packet.HelloPacket;
7 | import net.pl3x.guithium.api.player.WrappedPlayer;
8 | import org.jetbrains.annotations.NotNull;
9 |
10 | /**
11 | * Action that fires when a player joins the server and responds to the {@link HelloPacket}.
12 | *
13 | * This is different from Bukkit's PlayerJoinEvent because with this action
14 | * the player is guaranteed to be ready to receive packets from the server.
15 | */
16 | public class PlayerJoinedAction extends PlayerAction {
17 | private static final List handlers = new ArrayList<>();
18 |
19 | /**
20 | * Create a new action for when a player responds to the {@link HelloPacket}.
21 | *
22 | * @param player Player that performed the action
23 | */
24 | public PlayerJoinedAction(@NotNull WrappedPlayer player) {
25 | super(player);
26 | }
27 |
28 | @Override
29 | @NotNull
30 | public List getHandlers() {
31 | return handlers;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/action/actions/player/screen/ScreenAction.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.action.actions.player.screen;
2 |
3 | import net.pl3x.guithium.api.action.actions.player.PlayerAction;
4 | import net.pl3x.guithium.api.gui.Screen;
5 | import net.pl3x.guithium.api.player.WrappedPlayer;
6 | import org.jetbrains.annotations.NotNull;
7 |
8 | /**
9 | * Action that fires when a screen action is performed.
10 | */
11 | public abstract class ScreenAction extends PlayerAction {
12 | private final Screen screen;
13 |
14 | /**
15 | * Create a new action for when a screen action is performed.
16 | *
17 | * @param player Player that performed the action
18 | * @param screen Screen action was performed on
19 | */
20 | public ScreenAction(@NotNull WrappedPlayer player, @NotNull Screen screen) {
21 | super(player);
22 | this.screen = screen;
23 | }
24 |
25 | /**
26 | * Get the screen involved in this action.
27 | *
28 | * @return Screen
29 | */
30 | @NotNull
31 | public Screen getScreen() {
32 | return this.screen;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/action/actions/player/screen/ScreenClosedAction.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.action.actions.player.screen;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import net.pl3x.guithium.api.action.RegisteredHandler;
6 | import net.pl3x.guithium.api.gui.Screen;
7 | import net.pl3x.guithium.api.player.WrappedPlayer;
8 | import org.jetbrains.annotations.NotNull;
9 |
10 | /**
11 | * Action that fires when a screen is closed.
12 | */
13 | public class ScreenClosedAction extends ScreenAction {
14 | private static final List handlers = new ArrayList<>();
15 |
16 | /**
17 | * Create a new action for when a screen is closed.
18 | *
19 | * @param player Player that performed the action
20 | * @param screen Screen action was performed on
21 | */
22 | public ScreenClosedAction(@NotNull WrappedPlayer player, @NotNull Screen screen) {
23 | super(player, screen);
24 | }
25 |
26 | @Override
27 | @NotNull
28 | public List getHandlers() {
29 | return handlers;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/action/actions/player/screen/ScreenOpenedAction.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.action.actions.player.screen;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import net.pl3x.guithium.api.action.RegisteredHandler;
6 | import net.pl3x.guithium.api.gui.Screen;
7 | import net.pl3x.guithium.api.player.WrappedPlayer;
8 | import org.jetbrains.annotations.NotNull;
9 |
10 | /**
11 | * Action that fires when a screen is opened.
12 | */
13 | public class ScreenOpenedAction extends ScreenAction {
14 | private static final List handlers = new ArrayList<>();
15 |
16 | /**
17 | * Create a new action for when a screen is opened.
18 | *
19 | * @param player Player that performed the action
20 | * @param screen Screen action was performed on
21 | */
22 | public ScreenOpenedAction(@NotNull WrappedPlayer player, @NotNull Screen screen) {
23 | super(player, screen);
24 | }
25 |
26 | @Override
27 | @NotNull
28 | public List getHandlers() {
29 | return handlers;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/action/actions/player/screen/element/ElementAction.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.action.actions.player.screen.element;
2 |
3 | import net.pl3x.guithium.api.action.actions.player.screen.ScreenAction;
4 | import net.pl3x.guithium.api.gui.Screen;
5 | import net.pl3x.guithium.api.gui.element.Element;
6 | import net.pl3x.guithium.api.player.WrappedPlayer;
7 | import org.jetbrains.annotations.NotNull;
8 |
9 | /**
10 | * Action that fires when an element action is performed.
11 | *
12 | * @param Type of element
13 | */
14 | public abstract class ElementAction extends ScreenAction {
15 | private final T element;
16 |
17 | /**
18 | * Create a new action for when an element action is performed.
19 | *
20 | * @param player Player that performed the action
21 | * @param screen Screen action was performed on
22 | * @param element Element action was performed on
23 | */
24 | public ElementAction(@NotNull WrappedPlayer player, @NotNull Screen screen, @NotNull T element) {
25 | super(player, screen);
26 | this.element = element;
27 | }
28 |
29 | /**
30 | * Get the element involved in this action.
31 | *
32 | * @return Element
33 | */
34 | @NotNull
35 | public T getElement() {
36 | return this.element;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/action/actions/player/screen/element/ElementClickedAction.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.action.actions.player.screen.element;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import net.pl3x.guithium.api.action.RegisteredHandler;
6 | import net.pl3x.guithium.api.action.actions.Cancellable;
7 | import net.pl3x.guithium.api.gui.Screen;
8 | import net.pl3x.guithium.api.gui.element.Element;
9 | import net.pl3x.guithium.api.player.WrappedPlayer;
10 | import org.jetbrains.annotations.NotNull;
11 |
12 | /**
13 | * Action that fires when a clickable element is clicked.
14 | *
15 | * @param Type of element
16 | */
17 | public class ElementClickedAction extends ElementAction implements Cancellable {
18 | private static final List handlers = new ArrayList<>();
19 |
20 | private boolean cancelled;
21 |
22 | /**
23 | * Create a new action for when a clickable element is clicked.
24 | *
25 | * @param player Player that performed the action
26 | * @param screen Screen action was performed on
27 | * @param element Element action was performed on
28 | */
29 | public ElementClickedAction(@NotNull WrappedPlayer player, @NotNull Screen screen, @NotNull T element) {
30 | super(player, screen, element);
31 | }
32 |
33 | @Override
34 | public boolean isCancelled() {
35 | return this.cancelled;
36 | }
37 |
38 | @Override
39 | public void setCancelled(boolean cancelled) {
40 | this.cancelled = cancelled;
41 | }
42 |
43 | @Override
44 | @NotNull
45 | public List getHandlers() {
46 | return handlers;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/action/actions/player/screen/element/ElementToggledAction.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.action.actions.player.screen.element;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import net.pl3x.guithium.api.action.RegisteredHandler;
6 | import net.pl3x.guithium.api.action.actions.Cancellable;
7 | import net.pl3x.guithium.api.gui.Screen;
8 | import net.pl3x.guithium.api.gui.element.Element;
9 | import net.pl3x.guithium.api.player.WrappedPlayer;
10 | import org.jetbrains.annotations.NotNull;
11 |
12 | /**
13 | * Action that fires when a checkbox is toggled.
14 | *
15 | * @param Type of element
16 | */
17 | public class ElementToggledAction extends ElementClickedAction implements Cancellable {
18 | private static final List handlers = new ArrayList<>();
19 |
20 | private boolean selected;
21 |
22 | /**
23 | * Create a new action for when a togglable element is toggled.
24 | *
25 | * @param player Player that performed the action
26 | * @param screen Screen action was performed on
27 | * @param element Element action was performed on
28 | * @param selected New selected state of element
29 | */
30 | public ElementToggledAction(@NotNull WrappedPlayer player, @NotNull Screen screen, @NotNull T element, boolean selected) {
31 | super(player, screen, element);
32 | this.selected = selected;
33 | }
34 |
35 | /**
36 | * Get the new selected state of this element.
37 | *
38 | * @return New element selected state
39 | */
40 | public boolean isSelected() {
41 | return this.selected;
42 | }
43 |
44 | /**
45 | * Set the new selected state of this element.
46 | *
47 | * @param selected New element selected state
48 | */
49 | public void setSelected(boolean selected) {
50 | this.selected = selected;
51 | }
52 |
53 | @Override
54 | @NotNull
55 | public List getHandlers() {
56 | return handlers;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/action/actions/player/screen/element/ElementValueChangedAction.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.action.actions.player.screen.element;
2 |
3 | import com.google.common.base.Preconditions;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 | import net.pl3x.guithium.api.action.RegisteredHandler;
7 | import net.pl3x.guithium.api.action.actions.Cancellable;
8 | import net.pl3x.guithium.api.gui.Screen;
9 | import net.pl3x.guithium.api.gui.element.ValueElement;
10 | import net.pl3x.guithium.api.player.WrappedPlayer;
11 | import org.jetbrains.annotations.NotNull;
12 |
13 | /**
14 | * Action that fires when an element's value is changed.
15 | *
16 | * @param Type of element
17 | * @param Type of value
18 | */
19 | public class ElementValueChangedAction, V> extends ElementClickedAction implements Cancellable {
20 | private static final List handlers = new ArrayList<>();
21 |
22 | private V value;
23 |
24 | /**
25 | * Create a new action for when an element's value is changed.
26 | *
27 | * @param player Player that performed the action
28 | * @param screen Screen action was performed on
29 | * @param element Element action was performed on
30 | * @param value New value of element
31 | */
32 | public ElementValueChangedAction(@NotNull WrappedPlayer player, @NotNull Screen screen, @NotNull T element, @NotNull V value) {
33 | super(player, screen, element);
34 | setValue(value);
35 | }
36 |
37 | /**
38 | * Get the new value of this element.
39 | *
40 | * @return New element value
41 | */
42 | @NotNull
43 | public V getValue() {
44 | return this.value;
45 | }
46 |
47 | /**
48 | * Set the new value of this element.
49 | *
50 | * @param value New element value
51 | */
52 | public void setValue(@NotNull V value) {
53 | Preconditions.checkNotNull(value, "value cannot be null");
54 | this.value = value;
55 | }
56 |
57 | @Override
58 | @NotNull
59 | public List getHandlers() {
60 | return handlers;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/gui/Vec2.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.gui;
2 |
3 | import com.google.gson.JsonElement;
4 | import com.google.gson.JsonObject;
5 | import net.pl3x.guithium.api.json.Gson;
6 | import net.pl3x.guithium.api.json.JsonObjectWrapper;
7 | import net.pl3x.guithium.api.json.JsonSerializable;
8 | import org.jetbrains.annotations.NotNull;
9 |
10 | /**
11 | * Represents a size (x and y)
12 | *
13 | * @param x X value
14 | * @param y Y value
15 | */
16 | public record Vec2(float x, float y) implements JsonSerializable {
17 | /**
18 | * Vec2 of 0,0
19 | */
20 | public static final Vec2 ZERO = Vec2.of(0, 0);
21 |
22 | /**
23 | * Vec2 of 1,1
24 | */
25 | public static final Vec2 ONE = Vec2.of(1, 1);
26 |
27 | /**
28 | * Create a new 2D vector.
29 | *
30 | * @param x X value
31 | * @param y Y value
32 | * @return A new 2D vector
33 | */
34 | @NotNull
35 | public static Vec2 of(float x, float y) {
36 | return new Vec2(x, y);
37 | }
38 |
39 | /**
40 | * Get the X value.
41 | *
42 | * @return The X value
43 | */
44 | public float getX() {
45 | return x();
46 | }
47 |
48 | /**
49 | * Get the Y value.
50 | *
51 | * @return The Y value
52 | */
53 | public float getY() {
54 | return y();
55 | }
56 |
57 | @Override
58 | @NotNull
59 | public String toString() {
60 | return String.format("%s%s", getClass().getSimpleName(), Gson.toJson(this));
61 | }
62 |
63 | @Override
64 | @NotNull
65 | public JsonElement toJson() {
66 | JsonObjectWrapper json = new JsonObjectWrapper();
67 | json.addProperty("x", getX());
68 | json.addProperty("y", getY());
69 | return json.getJsonObject();
70 | }
71 |
72 | /**
73 | * Create a new 2D vector from Json.
74 | *
75 | * @param json Json representation of a 2D vector
76 | * @return A new 2D vector
77 | */
78 | @NotNull
79 | public static Vec2 fromJson(@NotNull JsonObject json) {
80 | return new Vec2(
81 | !json.has("x") ? 0 : json.get("x").getAsFloat(),
82 | !json.has("y") ? 0 : json.get("y").getAsFloat()
83 | );
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/gui/Vec4.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.gui;
2 |
3 | import com.google.gson.JsonElement;
4 | import com.google.gson.JsonObject;
5 | import net.pl3x.guithium.api.json.Gson;
6 | import net.pl3x.guithium.api.json.JsonObjectWrapper;
7 | import net.pl3x.guithium.api.json.JsonSerializable;
8 | import org.jetbrains.annotations.NotNull;
9 |
10 | /**
11 | * Represents a 4D vector.
12 | *
13 | * @param x X value
14 | * @param y Y value
15 | * @param z Z value
16 | * @param w W value
17 | */
18 | public record Vec4(float x, float y, float z, float w) implements JsonSerializable {
19 | /**
20 | * Vec4 of 0,0,0,0
21 | */
22 | public static final Vec4 ZERO = Vec4.of(0, 0, 0, 0);
23 |
24 | /**
25 | * Vec4 of 1,1,1,1
26 | */
27 | public static final Vec4 ONE = Vec4.of(1, 1, 1, 1);
28 |
29 | /**
30 | * Create a new 4D vector.
31 | *
32 | * @param x X value
33 | * @param y Y value
34 | * @param z Z value
35 | * @param w W value
36 | * @return A new 4D vector
37 | */
38 | @NotNull
39 | public static Vec4 of(float x, float y, float z, float w) {
40 | return new Vec4(x, y, z, w);
41 | }
42 |
43 | /**
44 | * Get the X value.
45 | *
46 | * @return The X value
47 | */
48 | public float getX() {
49 | return x();
50 | }
51 |
52 | /**
53 | * Get the Y value.
54 | *
55 | * @return The Y value
56 | */
57 | public float getY() {
58 | return y();
59 | }
60 |
61 | /**
62 | * Get the Z value.
63 | *
64 | * @return The Z value
65 | */
66 | public float getZ() {
67 | return z();
68 | }
69 |
70 | /**
71 | * Get the W value.
72 | *
73 | * @return The W value
74 | */
75 | public float getW() {
76 | return w();
77 | }
78 |
79 | @Override
80 | @NotNull
81 | public String toString() {
82 | return String.format("%s%s", getClass().getSimpleName(), Gson.toJson(this));
83 | }
84 |
85 | @Override
86 | @NotNull
87 | public JsonElement toJson() {
88 | JsonObjectWrapper json = new JsonObjectWrapper();
89 | json.addProperty("x", getX());
90 | json.addProperty("y", getY());
91 | json.addProperty("z", getZ());
92 | json.addProperty("w", getW());
93 | return json.getJsonObject();
94 | }
95 |
96 | /**
97 | * Create a new 4D vector from Json.
98 | *
99 | * @param json Json representation of a 4D vector
100 | * @return A new 4D vector
101 | */
102 | @NotNull
103 | public static Vec4 fromJson(@NotNull JsonObject json) {
104 | return new Vec4(
105 | !json.has("x") ? 0 : json.get("x").getAsFloat(),
106 | !json.has("y") ? 0 : json.get("y").getAsFloat(),
107 | !json.has("z") ? 0 : json.get("z").getAsFloat(),
108 | !json.has("w") ? 0 : json.get("w").getAsFloat()
109 | );
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/gui/element/Button.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.gui.element;
2 |
3 | import com.google.common.base.Preconditions;
4 | import com.google.gson.JsonElement;
5 | import com.google.gson.JsonObject;
6 | import java.util.Objects;
7 | import net.pl3x.guithium.api.json.JsonObjectWrapper;
8 | import net.pl3x.guithium.api.key.Key;
9 | import org.jetbrains.annotations.NotNull;
10 | import org.jetbrains.annotations.Nullable;
11 |
12 | /**
13 | * Represents a button element.
14 | */
15 | public class Button extends LabeledRect implements ClickableElement {
16 | private OnClick onClick = (screen, button, player) -> {
17 | };
18 |
19 | /**
20 | * Create a new button element.
21 | *
22 | * @param key Unique identifier for element
23 | */
24 | public Button(@NotNull String key) {
25 | this(Key.of(key));
26 | }
27 |
28 | /**
29 | * Create a new button element.
30 | *
31 | * @param key Unique identifier for element
32 | */
33 | public Button(@NotNull Key key) {
34 | super(key);
35 | }
36 |
37 | /**
38 | * Create a new button element.
39 | *
40 | * @param key Unique identifier
41 | * @return New button element
42 | */
43 | @NotNull
44 | public static Button of(@NotNull String key) {
45 | return of(Key.of(key));
46 | }
47 |
48 | /**
49 | * Create a new button element.
50 | *
51 | * @param key Unique identifier
52 | * @return New button element
53 | */
54 | @NotNull
55 | public static Button of(@NotNull Key key) {
56 | return new Button(key);
57 | }
58 |
59 | @Override
60 | @Nullable
61 | public OnClick onClick() {
62 | return this.onClick;
63 | }
64 |
65 | @Override
66 | @NotNull
67 | public Button onClick(@Nullable OnClick onClick) {
68 | this.onClick = onClick;
69 | return this;
70 | }
71 |
72 | @Override
73 | public boolean equals(@Nullable Object obj) {
74 | if (!super.equals(obj)) {
75 | return false;
76 | }
77 | Button other = (Button) obj;
78 | return Objects.equals(onClick(), other.onClick());
79 | }
80 |
81 | @Override
82 | public int hashCode() {
83 | return Objects.hash(super.hashCode(), onClick());
84 | }
85 |
86 | @Override
87 | @NotNull
88 | public JsonElement toJson() {
89 | JsonObjectWrapper json = new JsonObjectWrapper(super.toJson());
90 | return json.getJsonObject();
91 | }
92 |
93 | /**
94 | * Create a new button from Json.
95 | *
96 | * @param json Json representation of a button
97 | * @return A new button
98 | */
99 | @NotNull
100 | public static Button fromJson(@NotNull JsonObject json) {
101 | Preconditions.checkArgument(json.has("key"), "Key cannot be null");
102 | Button button = new Button(Key.of(json.get("key").getAsString()));
103 | LabeledRect.fromJson(button, json);
104 | return button;
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/gui/element/Checkbox.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.gui.element;
2 |
3 | import com.google.common.base.Preconditions;
4 | import com.google.gson.JsonElement;
5 | import com.google.gson.JsonObject;
6 | import java.util.Objects;
7 | import net.pl3x.guithium.api.json.JsonObjectWrapper;
8 | import net.pl3x.guithium.api.key.Key;
9 | import org.jetbrains.annotations.NotNull;
10 | import org.jetbrains.annotations.Nullable;
11 |
12 | /**
13 | * Represents a checkbox element.
14 | */
15 | public class Checkbox extends LabeledRect implements ValueElement {
16 | private Boolean value;
17 |
18 | private OnChange onChange = (screen, checkbox, player, value) -> {
19 | };
20 |
21 | /**
22 | * Create a new checkbox element.
23 | *
24 | * @param key Unique identifier
25 | */
26 | public Checkbox(@NotNull String key) {
27 | this(Key.of(key));
28 | }
29 |
30 | /**
31 | * Create a new checkbox element.
32 | *
33 | * @param key Unique identifier
34 | */
35 | public Checkbox(@NotNull Key key) {
36 | super(key);
37 | }
38 |
39 | /**
40 | * Create a new checkbox element.
41 | *
42 | * @param key Unique identifier
43 | * @return New checkbox element
44 | */
45 | @NotNull
46 | public static Checkbox of(@NotNull String key) {
47 | return of(Key.of(key));
48 | }
49 |
50 | /**
51 | * Create a new checkbox element.
52 | *
53 | * @param key Unique identifier
54 | * @return New checkbox element
55 | */
56 | @NotNull
57 | public static Checkbox of(@NotNull Key key) {
58 | return new Checkbox(key);
59 | }
60 |
61 | @Override
62 | @NotNull
63 | public Boolean getValue() {
64 | return this.value;
65 | }
66 |
67 | @Override
68 | @NotNull
69 | public Checkbox setValue(@NotNull Boolean value) {
70 | this.value = value;
71 | return this;
72 | }
73 |
74 | @Override
75 | @Nullable
76 | public OnChange onChange() {
77 | return this.onChange;
78 | }
79 |
80 | @Override
81 | @NotNull
82 | public Checkbox onChange(@Nullable OnChange onChange) {
83 | this.onChange = onChange;
84 | return this;
85 | }
86 |
87 | @Override
88 | public boolean equals(@Nullable Object obj) {
89 | if (!super.equals(obj)) {
90 | return false;
91 | }
92 | Checkbox other = (Checkbox) obj;
93 | return Objects.equals(getValue(), other.getValue())
94 | && Objects.equals(onChange(), other.onChange());
95 | }
96 |
97 | @Override
98 | public int hashCode() {
99 | return Objects.hash(
100 | super.hashCode(),
101 | getValue(),
102 | onChange()
103 | );
104 | }
105 |
106 | @Override
107 | @NotNull
108 | public JsonElement toJson() {
109 | JsonObjectWrapper json = new JsonObjectWrapper(super.toJson());
110 | json.addProperty("label", getLabel());
111 | json.addProperty("tooltip", getTooltip());
112 | json.addProperty("value", getValue());
113 | return json.getJsonObject();
114 | }
115 |
116 | /**
117 | * Create a new checkbox from Json.
118 | *
119 | * @param json Json representation of a checkbox
120 | * @return A new checkbox
121 | */
122 | @NotNull
123 | public static Checkbox fromJson(@NotNull JsonObject json) {
124 | Preconditions.checkArgument(json.has("key"), "Key cannot be null");
125 | Checkbox checkbox = new Checkbox(Key.of(json.get("key").getAsString()));
126 | LabeledRect.fromJson(checkbox, json);
127 | checkbox.setValue(json.has("value") && json.get("value").getAsBoolean());
128 | return checkbox;
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/gui/element/ClickableElement.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.gui.element;
2 |
3 | import net.pl3x.guithium.api.gui.Screen;
4 | import net.pl3x.guithium.api.player.WrappedPlayer;
5 | import net.pl3x.guithium.api.util.TriConsumer;
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | /**
10 | * Represents an element that can be clicked, such as a button.
11 | *
12 | * @param Type of element
13 | */
14 | public interface ClickableElement> extends Element {
15 | /**
16 | * Get the action to execute when the button is clicked.
17 | *
18 | * If null, no click action will be used.
19 | *
20 | * @return OnClick action
21 | */
22 | @Nullable
23 | OnClick onClick();
24 |
25 | /**
26 | * Set the action to execute when the button is clicked.
27 | *
28 | * If null, no click action will be used.
29 | *
30 | * @param onClick OnClick action
31 | * @return This button
32 | */
33 | @NotNull
34 | T onClick(@Nullable OnClick onClick);
35 |
36 | /**
37 | * Executable functional interface to fire when a button is clicked.
38 | *
39 | * @param Type of element
40 | */
41 | @FunctionalInterface
42 | interface OnClick> extends TriConsumer {
43 | /**
44 | * Called when an element is clicked.
45 | *
46 | * @param screen Active screen where element was clicked
47 | * @param element Element that was clicked
48 | * @param player Player that clicked the element
49 | */
50 | void accept(@NotNull Screen screen, @NotNull T element, @NotNull WrappedPlayer player);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/gui/element/Rect.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.gui.element;
2 |
3 | import com.google.gson.JsonElement;
4 | import com.google.gson.JsonObject;
5 | import java.util.Objects;
6 | import net.pl3x.guithium.api.Unsafe;
7 | import net.pl3x.guithium.api.gui.Vec2;
8 | import net.pl3x.guithium.api.json.JsonObjectWrapper;
9 | import net.pl3x.guithium.api.key.Key;
10 | import org.jetbrains.annotations.NotNull;
11 | import org.jetbrains.annotations.Nullable;
12 |
13 | /**
14 | * Represents a rectangle element
15 | *
16 | * @param Type of rectangle element
17 | */
18 | public abstract class Rect> extends AbstractElement {
19 | private Vec2 size;
20 |
21 | /**
22 | * Create a new rect-type element.
23 | *
24 | * @param key Unique identifier for element
25 | */
26 | protected Rect(@NotNull Key key) {
27 | super(key);
28 | }
29 |
30 | /**
31 | * Get the size of this element.
32 | *
33 | * @return Size of element
34 | */
35 | @NotNull
36 | public Vec2 getSize() {
37 | return this.size == null ? Vec2.ZERO : this.size;
38 | }
39 |
40 | /**
41 | * Set the size of this element.
42 | *
43 | * @param width Width to set
44 | * @param height Height to set
45 | * @return This rect
46 | */
47 | @NotNull
48 | public T setSize(float width, float height) {
49 | return setSize(Vec2.of(width, height));
50 | }
51 |
52 | /**
53 | * Set the size of this element.
54 | *
55 | * @param size Size to set
56 | * @return This rect
57 | */
58 | @NotNull
59 | public T setSize(@Nullable Vec2 size) {
60 | this.size = size == Vec2.ZERO ? null : size;
61 | return Unsafe.cast(this);
62 | }
63 |
64 | @Override
65 | public boolean equals(@Nullable Object obj) {
66 | if (!super.equals(obj)) {
67 | return false;
68 | }
69 | Rect other = Unsafe.cast(obj);
70 | return Objects.equals(getSize(), other.getSize());
71 | }
72 |
73 | @Override
74 | public int hashCode() {
75 | return Objects.hash(
76 | super.hashCode(),
77 | getSize()
78 | );
79 | }
80 |
81 | @Override
82 | @NotNull
83 | public JsonElement toJson() {
84 | JsonObjectWrapper json = new JsonObjectWrapper(super.toJson());
85 | json.addProperty("size", getSize());
86 | return json.getJsonObject();
87 | }
88 |
89 | /**
90 | * Populate a rectangle from Json.
91 | *
92 | * @param element A rectangle to populate
93 | * @param json Json representation of a rectangle
94 | */
95 | public static void fromJson(@NotNull Rect> element, @NotNull JsonObject json) {
96 | AbstractElement.fromJson(element, json);
97 | element.setSize(!json.has("size") ? null : Vec2.fromJson(json.get("size").getAsJsonObject()));
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/gui/element/ValueElement.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.gui.element;
2 |
3 | import net.pl3x.guithium.api.gui.Screen;
4 | import net.pl3x.guithium.api.player.WrappedPlayer;
5 | import net.pl3x.guithium.api.util.QuadConsumer;
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | /**
10 | * Represents an element that contains a value.
11 | *
12 | * @param Type of element
13 | * @param Type of value
14 | */
15 | public interface ValueElement, V> extends Element {
16 | /**
17 | * Get the value of this element.
18 | *
19 | * @return Element's value
20 | */
21 | @NotNull
22 | V getValue();
23 |
24 | /**
25 | * Set the value of this element.
26 | *
27 | * @param value Element's value
28 | * @return This element
29 | */
30 | @NotNull
31 | T setValue(@NotNull V value);
32 |
33 | /**
34 | * Get the action to execute when the element's value is changed.
35 | *
36 | * If null, no change action will be used.
37 | *
38 | * @return OnClick action
39 | */
40 | @Nullable
41 | OnChange onChange();
42 |
43 | /**
44 | * Set the action to execute when the element's value is changed.
45 | *
46 | * If null, no change action will be used.
47 | *
48 | * @param onChange OnChange action
49 | * @return This element
50 | */
51 | @NotNull
52 | T onChange(@Nullable OnChange onChange);
53 |
54 | /**
55 | * Executable functional interface to fire when an element's value is changed.
56 | *
57 | * @param Type of element
58 | * @param Type of value
59 | */
60 | @FunctionalInterface
61 | interface OnChange, V> extends QuadConsumer {
62 | /**
63 | * Called when an element's value is changed.
64 | *
65 | * @param screen Active screen where element was changed
66 | * @param element Element that was changed
67 | * @param player Player that changed the element
68 | * @param value New value of the element
69 | */
70 | void accept(@NotNull Screen screen, @NotNull T element, @NotNull WrappedPlayer player, @NotNull V value);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/gui/texture/Texture.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.gui.texture;
2 |
3 | import com.google.common.base.Preconditions;
4 | import com.google.gson.JsonElement;
5 | import com.google.gson.JsonObject;
6 | import java.util.Objects;
7 | import net.pl3x.guithium.api.json.JsonObjectWrapper;
8 | import net.pl3x.guithium.api.key.Key;
9 | import net.pl3x.guithium.api.key.Keyed;
10 | import org.jetbrains.annotations.NotNull;
11 | import org.jetbrains.annotations.Nullable;
12 |
13 | /**
14 | * Represents an image texture.
15 | */
16 | public class Texture extends Keyed {
17 | /**
18 | * Mojang's default dirt texture used in options screens.
19 | */
20 | public static final Texture DIRT = Texture.of("minecraft:dirt", "textures/gui/options_background.png");
21 |
22 | private final String url;
23 |
24 | /**
25 | * Create a new image texture.
26 | *
27 | * @param key Unique identifying key
28 | * @param url URL or resource location
29 | */
30 | protected Texture(@NotNull Key key, @NotNull String url) {
31 | super(key);
32 | Preconditions.checkNotNull(url, "Url cannot be null");
33 | this.url = url;
34 | }
35 |
36 | /**
37 | * Create a new image texture.
38 | *
39 | * @param id Unique identifying key
40 | * @param url URL or resource location
41 | * @return new Texture
42 | */
43 | @NotNull
44 | public static Texture of(@NotNull String id, @NotNull String url) {
45 | return of(Key.of(id), url);
46 | }
47 |
48 | /**
49 | * Create a new image texture.
50 | *
51 | * @param key Unique identifying key
52 | * @param url URL or resource location
53 | * @return new Texture
54 | */
55 | @NotNull
56 | public static Texture of(@NotNull Key key, @NotNull String url) {
57 | return new Texture(key, url);
58 | }
59 |
60 | /**
61 | * Get the URL or resource location to the texture.
62 | *
63 | * Values starting with http://
or https://
will be retrieved from the internet.
64 | *
65 | * For vanilla textures, just specify the resource location with or without the minecraft:
namespace.
66 | *
67 | * For textures provided by other client mods, just specify the resource location with their mod id as the namespace.
68 | *
69 | * @return URL or resource location of the texture
70 | */
71 | @NotNull
72 | public String getUrl() {
73 | return this.url;
74 | }
75 |
76 | @Override
77 | public boolean equals(@Nullable Object obj) {
78 | if (!super.equals(obj)) {
79 | return false;
80 | }
81 | Texture other = (Texture) obj;
82 | return getUrl().equals(other.getUrl());
83 | }
84 |
85 | @Override
86 | public int hashCode() {
87 | return Objects.hash(
88 | super.hashCode(),
89 | getUrl()
90 | );
91 | }
92 |
93 | @Override
94 | @NotNull
95 | public JsonElement toJson() {
96 | JsonObjectWrapper json = new JsonObjectWrapper(super.toJson());
97 | json.addProperty("url", getUrl());
98 | return json.getJsonObject();
99 | }
100 |
101 | /**
102 | * Create a new texture from Json.
103 | *
104 | * @param json Json representation of a texture
105 | * @return A new texture
106 | */
107 | @NotNull
108 | public static Texture fromJson(@NotNull JsonObject json) {
109 | Preconditions.checkArgument(json.has("key"), "Key cannot be null");
110 | Preconditions.checkArgument(json.has("url"), "Url cannot be null");
111 | return new Texture(
112 | Key.of(json.get("key").getAsString()),
113 | json.get("url").getAsString()
114 | );
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/gui/texture/TextureManager.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.gui.texture;
2 |
3 | import java.util.Collection;
4 | import java.util.Collections;
5 | import java.util.HashMap;
6 | import java.util.Map;
7 | import net.pl3x.guithium.api.key.Key;
8 | import org.jetbrains.annotations.NotNull;
9 | import org.jetbrains.annotations.Nullable;
10 |
11 | /**
12 | * A texture manager that manages textures to store textures that need to be managed.
13 | *
14 | * Textures added here will be preloaded into memory for later use.
15 | */
16 | public class TextureManager {
17 | private final Map textures = new HashMap<>();
18 |
19 | /**
20 | * Create a new texture manager.
21 | */
22 | public TextureManager() {
23 | // Empty constructor to pacify javadoc lint
24 | }
25 |
26 | /**
27 | * Add some textures.
28 | *
29 | * @param textures Collection of textures to add
30 | */
31 | public void add(@NotNull Collection textures) {
32 | textures.forEach(this::add);
33 | }
34 |
35 | /**
36 | * Add a texture.
37 | *
38 | * If the texture is from the internet, it will be preloaded into memory on the next render thread tick.
39 | *
40 | * @param texture Texture to add
41 | */
42 | public void add(@NotNull Texture texture) {
43 | this.textures.put(texture.getKey(), texture);
44 | }
45 |
46 | /**
47 | * Get a texture by string.
48 | *
49 | * @param key Unique identifier for texture
50 | * @return A texture with specified string if it exists, otherwise {@code null}
51 | */
52 | @Nullable
53 | public Texture get(@NotNull String key) {
54 | return get(Key.of(key));
55 | }
56 |
57 | /**
58 | * Get a texture by key.
59 | *
60 | * @param key Unique identifier of texture
61 | * @return A texture with specified key if it exists, otherwise {@code null}
62 | */
63 | @Nullable
64 | public Texture get(@NotNull Key key) {
65 | return this.textures.get(key);
66 | }
67 |
68 | /**
69 | * Remove a texture by string.
70 | *
71 | * @param key Unique identifier of texture to remove
72 | * @return The removed texture associated with {@code key}, or {@code null} if there was none for {@code key}.
73 | */
74 | @Nullable
75 | public Texture remove(@NotNull String key) {
76 | return remove(Key.of(key));
77 | }
78 |
79 | /**
80 | * Remove a texture by key.
81 | *
82 | * @param key Unique identifier of texture to remove
83 | * @return The removed texture associated with {@code key}, or {@code null} if there was none for {@code key}.
84 | */
85 | @Nullable
86 | public Texture remove(@NotNull Key key) {
87 | return this.textures.remove(key);
88 | }
89 |
90 | /**
91 | * Get an unmodifiable view of the stored textures.
92 | *
93 | * @return An unmodifiable view of stored textures
94 | */
95 | @NotNull
96 | public Collection getTextures() {
97 | return Collections.unmodifiableCollection(this.textures.values());
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/json/Gson.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.json;
2 |
3 | import com.google.gson.FieldNamingPolicy;
4 | import com.google.gson.FormattingStyle;
5 | import com.google.gson.GsonBuilder;
6 | import com.google.gson.LongSerializationPolicy;
7 | import com.google.gson.Strictness;
8 | import java.lang.reflect.Type;
9 | import net.kyori.adventure.text.Component;
10 | import net.pl3x.guithium.api.gui.Screen;
11 | import net.pl3x.guithium.api.gui.element.Element;
12 | import net.pl3x.guithium.api.json.adapter.ComponentAdapter;
13 | import net.pl3x.guithium.api.json.adapter.ElementAdapter;
14 | import net.pl3x.guithium.api.json.adapter.ScreenAdapter;
15 | import net.pl3x.guithium.api.key.Key;
16 | import org.jetbrains.annotations.NotNull;
17 | import org.jetbrains.annotations.Nullable;
18 |
19 | /**
20 | * Represents some conveniences for using Gson.
21 | */
22 | public abstract class Gson {
23 | private Gson() {
24 | // Empty constructor to pacify javadoc lint
25 | }
26 |
27 | /**
28 | * Gson instance for (de)serializing objects to/from JSON.
29 | */
30 | private static final com.google.gson.Gson GSON = new GsonBuilder()
31 | .disableHtmlEscaping()
32 | .setStrictness(Strictness.LENIENT)
33 | .setFormattingStyle(FormattingStyle.COMPACT)
34 | .setFieldNamingPolicy(FieldNamingPolicy.IDENTITY)
35 | .setLongSerializationPolicy(LongSerializationPolicy.DEFAULT)
36 | .registerTypeAdapter(Component.class, new ComponentAdapter())
37 | .registerTypeAdapter(Key.class, new Key.Adapter())
38 | .registerTypeHierarchyAdapter(Element.class, new ElementAdapter())
39 | .registerTypeHierarchyAdapter(Screen.class, new ScreenAdapter())
40 | .create();
41 |
42 | /**
43 | * Get Guithium's stored Gson instance.
44 | *
45 | * @return Guithium's Gson instance
46 | */
47 | @NotNull
48 | public static com.google.gson.Gson gson() {
49 | return GSON;
50 | }
51 |
52 | /**
53 | * Serialize an object to a json string.
54 | *
55 | * @param src Object to serialize
56 | * @return Json string
57 | */
58 | @NotNull
59 | public static String toJson(@Nullable Object src) {
60 | return gson().toJson(src);
61 | }
62 |
63 | /**
64 | * Create object from json string.
65 | *
66 | * @param json Json string
67 | * @param classOfT Type of object
68 | * @param Type of object
69 | * @return New object of specified type
70 | */
71 | @Nullable
72 | public static T fromJson(@Nullable String json, @NotNull Class classOfT) {
73 | return gson().fromJson(json, classOfT);
74 | }
75 |
76 | /**
77 | * Create object from json string.
78 | *
79 | * @param json Json string
80 | * @param typeOfT Type of object
81 | * @param Type of object
82 | * @return New object of specified type
83 | */
84 | @Nullable
85 | public static T fromJson(@Nullable String json, @NotNull Type typeOfT) {
86 | return gson().fromJson(json, typeOfT);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/json/JsonSerializable.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.json;
2 |
3 | import com.google.gson.JsonElement;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | /**
7 | * Represents an object that can be (de)serialized to/from JSON.
8 | */
9 | public interface JsonSerializable {
10 | /**
11 | * Jsonify this object.
12 | *
13 | * @return object as json element
14 | */
15 | @NotNull
16 | JsonElement toJson();
17 | }
18 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/json/adapter/ComponentAdapter.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.json.adapter;
2 |
3 | import com.google.gson.JsonDeserializationContext;
4 | import com.google.gson.JsonDeserializer;
5 | import com.google.gson.JsonElement;
6 | import com.google.gson.JsonParseException;
7 | import com.google.gson.JsonPrimitive;
8 | import com.google.gson.JsonSerializationContext;
9 | import com.google.gson.JsonSerializer;
10 | import java.lang.reflect.Type;
11 | import net.kyori.adventure.text.Component;
12 | import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
13 | import org.jetbrains.annotations.NotNull;
14 | import org.jetbrains.annotations.Nullable;
15 |
16 | /**
17 | * A custom JSON (de)serializer for the GSON library specifically for adventure components.
18 | */
19 | public class ComponentAdapter implements JsonSerializer, JsonDeserializer {
20 | /**
21 | * Create a new component adapter for gson.
22 | */
23 | public ComponentAdapter() {
24 | // Empty constructor to pacify javadoc lint
25 | }
26 |
27 | @Override
28 | @NotNull
29 | public JsonElement serialize(@NotNull Component component, @NotNull Type type, @NotNull JsonSerializationContext context) {
30 | return new JsonPrimitive(GsonComponentSerializer.gson().serialize(component));
31 | }
32 |
33 | @Override
34 | @Nullable
35 | public Component deserialize(@NotNull JsonElement json, @NotNull Type type, @NotNull JsonDeserializationContext context) throws JsonParseException {
36 | return GsonComponentSerializer.gson().deserialize(json.getAsString());
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/json/adapter/ElementAdapter.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.json.adapter;
2 |
3 | import com.google.gson.JsonDeserializationContext;
4 | import com.google.gson.JsonDeserializer;
5 | import com.google.gson.JsonElement;
6 | import com.google.gson.JsonParseException;
7 | import com.google.gson.JsonSerializationContext;
8 | import com.google.gson.JsonSerializer;
9 | import java.lang.reflect.Type;
10 | import net.pl3x.guithium.api.gui.element.Element;
11 | import org.jetbrains.annotations.NotNull;
12 | import org.jetbrains.annotations.Nullable;
13 |
14 | /**
15 | * A custom JSON (de)serializer for the GSON library specifically for elements.
16 | */
17 | public class ElementAdapter implements JsonSerializer, JsonDeserializer {
18 | /**
19 | * Create a new component adapter for gson.
20 | */
21 | public ElementAdapter() {
22 | // Empty constructor to pacify javadoc lint
23 | }
24 |
25 | @Override
26 | @NotNull
27 | public JsonElement serialize(@NotNull Element element, @NotNull Type type, @NotNull JsonSerializationContext context) {
28 | return element.toJson();
29 | }
30 |
31 | @Override
32 | @Nullable
33 | public Element deserialize(@NotNull JsonElement json, @NotNull Type type, @NotNull JsonDeserializationContext context) throws JsonParseException {
34 | return Element.fromJson(json.getAsJsonObject());
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/json/adapter/ScreenAdapter.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.json.adapter;
2 |
3 | import com.google.gson.JsonDeserializationContext;
4 | import com.google.gson.JsonDeserializer;
5 | import com.google.gson.JsonElement;
6 | import com.google.gson.JsonParseException;
7 | import com.google.gson.JsonSerializationContext;
8 | import com.google.gson.JsonSerializer;
9 | import java.lang.reflect.Type;
10 | import net.pl3x.guithium.api.gui.Screen;
11 | import org.jetbrains.annotations.NotNull;
12 | import org.jetbrains.annotations.Nullable;
13 |
14 | /**
15 | * A custom JSON (de)serializer for the GSON library specifically for screens.
16 | */
17 | public class ScreenAdapter implements JsonSerializer, JsonDeserializer {
18 | /**
19 | * Create a new screen adapter for gson.
20 | */
21 | public ScreenAdapter() {
22 | // Empty constructor to pacify javadoc lint
23 | }
24 |
25 | @Override
26 | @NotNull
27 | public JsonElement serialize(@NotNull Screen screen, @NotNull Type type, @NotNull JsonSerializationContext context) {
28 | return screen.toJson();
29 | }
30 |
31 | @Override
32 | @Nullable
33 | public Screen deserialize(@NotNull JsonElement json, @NotNull Type type, @NotNull JsonDeserializationContext context) throws JsonParseException {
34 | return Screen.fromJson(json.getAsJsonObject());
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/key/Key.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.key;
2 |
3 | import com.google.common.base.Preconditions;
4 | import com.google.gson.JsonDeserializationContext;
5 | import com.google.gson.JsonDeserializer;
6 | import com.google.gson.JsonElement;
7 | import com.google.gson.JsonParseException;
8 | import com.google.gson.JsonPrimitive;
9 | import com.google.gson.JsonSerializationContext;
10 | import com.google.gson.JsonSerializer;
11 | import java.lang.reflect.Type;
12 | import java.util.regex.Pattern;
13 | import org.jetbrains.annotations.NotNull;
14 | import org.jetbrains.annotations.Nullable;
15 |
16 | /**
17 | * Simple string wrapper used to identify objects.
18 | *
19 | * In most cases keys should be unique, so prefixing keys with a plugin
20 | * name, for example {@code myplugin:screen-1}, would be good practice.
21 | */
22 | public final class Key {
23 | private static final Pattern VALID_CHARS = Pattern.compile("[a-zA-Z0-9:/._-]+");
24 |
25 | private final String key;
26 |
27 | /**
28 | * Create a new key.
29 | *
30 | * Valid key values {@code [a-zA-Z0-9:/._-]+}
31 | *
32 | * @param key Unique identifier
33 | */
34 | public Key(@NotNull String key) {
35 | Preconditions.checkNotNull(key, "Key cannot be null");
36 | if (!VALID_CHARS.matcher(key).matches()) {
37 | throw new IllegalArgumentException(String.format("Non [a-zA-Z0-9:/._-] character in key '%s'", key));
38 | }
39 | this.key = key;
40 | }
41 |
42 | /**
43 | * Create a new key.
44 | *
45 | * @param key Unique identifier
46 | * @return A new {@link Key}
47 | */
48 | @NotNull
49 | public static Key of(@NotNull String key) {
50 | return new Key(key);
51 | }
52 |
53 | @Override
54 | public boolean equals(@Nullable Object obj) {
55 | if (this == obj) {
56 | return true;
57 | }
58 | if (obj == null) {
59 | return false;
60 | }
61 | if (getClass() != obj.getClass()) {
62 | return false;
63 | }
64 | Key other = (Key) obj;
65 | return toString().equals(other.toString());
66 | }
67 |
68 | @Override
69 | public int hashCode() {
70 | return toString().hashCode();
71 | }
72 |
73 | @Override
74 | @NotNull
75 | public String toString() {
76 | return this.key;
77 | }
78 |
79 | /**
80 | * A custom JSON (de)serializer for the GSON library specifically for Key objects.
81 | */
82 | public static class Adapter implements JsonSerializer, JsonDeserializer {
83 | /**
84 | * Create a new Key adapter for gson.
85 | */
86 | public Adapter() {
87 | // Empty constructor to pacify javadoc lint
88 | }
89 |
90 | @Override
91 | @NotNull
92 | public JsonElement serialize(@NotNull Key key, @NotNull Type type, @NotNull JsonSerializationContext context) {
93 | return new JsonPrimitive(key.toString());
94 | }
95 |
96 | @Override
97 | @Nullable
98 | public Key deserialize(@NotNull JsonElement json, @NotNull Type type, @NotNull JsonDeserializationContext context) throws JsonParseException {
99 | return Key.of(json.getAsString());
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/key/Keyed.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.key;
2 |
3 | import com.google.common.base.Preconditions;
4 | import com.google.gson.JsonElement;
5 | import net.pl3x.guithium.api.json.JsonObjectWrapper;
6 | import net.pl3x.guithium.api.json.JsonSerializable;
7 | import org.jetbrains.annotations.NotNull;
8 | import org.jetbrains.annotations.Nullable;
9 |
10 | /**
11 | * Represents an object with a unique identifier.
12 | */
13 | public abstract class Keyed implements JsonSerializable {
14 | private final Key key;
15 |
16 | /**
17 | * Create a new key identified object.
18 | *
19 | * @param key Unique identifier
20 | */
21 | public Keyed(@NotNull Key key) {
22 | Preconditions.checkNotNull(key, "Key cannot be null");
23 | this.key = key;
24 | }
25 |
26 | /**
27 | * Get the identifying key for this object.
28 | *
29 | * @return Unique identifier
30 | */
31 | @NotNull
32 | public Key getKey() {
33 | return this.key;
34 | }
35 |
36 | @Override
37 | public boolean equals(@Nullable Object obj) {
38 | if (this == obj) {
39 | return true;
40 | }
41 | if (obj == null) {
42 | return false;
43 | }
44 | if (this.getClass() != obj.getClass()) {
45 | return false;
46 | }
47 | Keyed other = (Keyed) obj;
48 | return getKey().equals(other.getKey());
49 | }
50 |
51 | @Override
52 | public int hashCode() {
53 | return getKey().hashCode();
54 | }
55 |
56 | @Override
57 | @NotNull
58 | public String toString() {
59 | return String.format("%s%s", getClass().getSimpleName(), toJson());
60 | }
61 |
62 | @Override
63 | @NotNull
64 | public JsonElement toJson() {
65 | JsonObjectWrapper json = new JsonObjectWrapper();
66 | json.addProperty("key", getKey());
67 | json.addProperty("type", getClass().getSimpleName());
68 | return json.getJsonObject();
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/network/Connection.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.network;
2 |
3 | import net.pl3x.guithium.api.network.packet.Packet;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | /**
7 | * Represents a network connection.
8 | */
9 | public interface Connection {
10 | /**
11 | * Get the packet listener.
12 | *
13 | * @return Packet listener
14 | */
15 | @NotNull
16 | PacketListener getPacketListener();
17 |
18 | /**
19 | * Send packet.
20 | *
21 | * @param packet Packet to send
22 | */
23 | void send(@NotNull Packet packet);
24 |
25 | /**
26 | * Send packet.
27 | *
28 | * @param packet Packet to send
29 | * @param force Ignore protocol checks
30 | */
31 | void send(@NotNull Packet packet, boolean force);
32 | }
33 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/network/NetworkHandler.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.network;
2 |
3 | import com.google.common.io.ByteArrayDataInput;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 | import java.util.function.Function;
7 | import net.pl3x.guithium.api.Guithium;
8 | import net.pl3x.guithium.api.key.Key;
9 | import net.pl3x.guithium.api.network.packet.ElementClickedPacket;
10 | import net.pl3x.guithium.api.network.packet.CloseScreenPacket;
11 | import net.pl3x.guithium.api.network.packet.ElementPacket;
12 | import net.pl3x.guithium.api.network.packet.HelloPacket;
13 | import net.pl3x.guithium.api.network.packet.OpenScreenPacket;
14 | import net.pl3x.guithium.api.network.packet.Packet;
15 | import net.pl3x.guithium.api.network.packet.ElementChangedValuePacket;
16 | import net.pl3x.guithium.api.network.packet.TexturesPacket;
17 | import org.jetbrains.annotations.NotNull;
18 | import org.jetbrains.annotations.Nullable;
19 |
20 | /**
21 | * Represents a network handler. All packets are registered here.
22 | */
23 | public abstract class NetworkHandler {
24 | /**
25 | * A unique identifier for the network channel between client and server.
26 | */
27 | public final static String CHANNEL = String.format("%1$s:%1$s", Guithium.MOD_ID);
28 |
29 | private final Map> packets = new HashMap<>();
30 |
31 | /**
32 | * Create a new network handler instance
33 | */
34 | public NetworkHandler() {
35 | registerListener(ElementClickedPacket.KEY, ElementClickedPacket::new);
36 | //registerListener(CheckboxTogglePacket.KEY, CheckboxTogglePacket::new);
37 | registerListener(CloseScreenPacket.KEY, CloseScreenPacket::new);
38 | registerListener(ElementPacket.KEY, ElementPacket::new);
39 | registerListener(HelloPacket.KEY, HelloPacket::new);
40 | registerListener(OpenScreenPacket.KEY, OpenScreenPacket::new);
41 | //registerListener(RadioTogglePacket.KEY, RadioTogglePacket::new);
42 | registerListener(ElementChangedValuePacket.KEY, ElementChangedValuePacket::new);
43 | registerListener(TexturesPacket.KEY, TexturesPacket::new);
44 | }
45 |
46 | /**
47 | * Register the network listeners
48 | */
49 | public abstract void registerListeners();
50 |
51 | /**
52 | * Register incoming packet handlers.
53 | *
54 | * @param key Identifying key
55 | * @param function Packet handler
56 | */
57 | protected void registerListener(@NotNull Key key, @NotNull Function function) {
58 | this.packets.put(key, function);
59 | }
60 |
61 | /**
62 | * Receive data.
63 | *
64 | * @param connection Connection to receive on
65 | * @param data Raw data received
66 | */
67 | public void receive(@NotNull Connection connection, byte[] data) {
68 | Packet packet = getPacket(Packet.in(data));
69 | if (packet != null) {
70 | packet.handle(connection.getPacketListener());
71 | }
72 | }
73 |
74 | /**
75 | * Get the packet from the raw input data.
76 | *
77 | * @param in Raw input data
78 | * @return The packet for the data, or null if not recognized
79 | */
80 | @Nullable
81 | protected Packet getPacket(@NotNull ByteArrayDataInput in) {
82 | // verify protocol
83 | int protocol = in.readInt();
84 | if (protocol != Guithium.PROTOCOL) {
85 | Guithium.logger.warn("Received packet with invalid protocol ({}) from server", protocol);
86 | return null;
87 | }
88 |
89 | // get registered packet handler
90 | Key packetId = Key.of(in.readUTF());
91 | Function function = this.packets.get(packetId);
92 | if (function == null) {
93 | Guithium.logger.warn("Received unknown packet ({}) from player", packetId);
94 | return null;
95 | }
96 | return function.apply(in);
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/network/PacketListener.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.network;
2 |
3 | import net.pl3x.guithium.api.gui.element.ClickableElement;
4 | import net.pl3x.guithium.api.gui.element.ValueElement;
5 | import net.pl3x.guithium.api.network.packet.CloseScreenPacket;
6 | import net.pl3x.guithium.api.network.packet.ElementChangedValuePacket;
7 | import net.pl3x.guithium.api.network.packet.ElementClickedPacket;
8 | import net.pl3x.guithium.api.network.packet.ElementPacket;
9 | import net.pl3x.guithium.api.network.packet.HelloPacket;
10 | import net.pl3x.guithium.api.network.packet.OpenScreenPacket;
11 | import net.pl3x.guithium.api.network.packet.TexturesPacket;
12 | import org.jetbrains.annotations.NotNull;
13 |
14 | /**
15 | * Represents a listener of packets. Packets sent from the client to the server are handled here.
16 | */
17 | public interface PacketListener {
18 | /**
19 | * Handle element click packet.
20 | *
21 | * @param packet Element click packet to handle
22 | * @param Type of element
23 | */
24 | > void handleElementClick(@NotNull ElementClickedPacket packet);
25 |
26 | /**
27 | * Handle element changed value packet.
28 | *
29 | * @param packet Element changed value packet to handle
30 | * @param Type of element
31 | * @param Type of value
32 | */
33 | , V> void handleElementChangedValue(@NotNull ElementChangedValuePacket packet);
34 |
35 | /**
36 | * Handle update element packet.
37 | *
38 | * @param packet Element packet to handle
39 | */
40 | void handleElement(@NotNull ElementPacket packet);
41 |
42 | /**
43 | * Handle open screen packet.
44 | *
45 | * @param packet Open screen packet to handle
46 | */
47 | void handleOpenScreen(@NotNull OpenScreenPacket packet);
48 |
49 | /**
50 | * Handle close screen packet.
51 | *
52 | * @param packet Close screen packet to handle
53 | */
54 | void handleCloseScreen(@NotNull CloseScreenPacket packet);
55 |
56 | /**
57 | * Handle texture preload packet.
58 | *
59 | * @param packet Texture preload packet to handle
60 | */
61 | void handleTextures(@NotNull TexturesPacket packet);
62 |
63 | /**
64 | * Handle the hello packet.
65 | *
66 | * @param packet Hello packet to handle
67 | */
68 | void handleHello(@NotNull HelloPacket packet);
69 | }
70 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/network/packet/CloseScreenPacket.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.network.packet;
2 |
3 | import com.google.common.io.ByteArrayDataInput;
4 | import com.google.common.io.ByteArrayDataOutput;
5 | import net.pl3x.guithium.api.key.Key;
6 | import net.pl3x.guithium.api.network.PacketListener;
7 | import org.jetbrains.annotations.NotNull;
8 |
9 | /**
10 | * Represents a close screen packet.
11 | */
12 | public class CloseScreenPacket extends Packet {
13 | /**
14 | * Unique identifying key
15 | */
16 | public static final Key KEY = Key.of("packet:close_screen");
17 |
18 | private final Key screenKey;
19 |
20 | /**
21 | * Create a new close screen packet.
22 | *
23 | * @param screenKey Unique identifying key for the screen to close
24 | */
25 | public CloseScreenPacket(@NotNull Key screenKey) {
26 | super(KEY);
27 | this.screenKey = screenKey;
28 | }
29 |
30 | /**
31 | * Create a new close screen packet.
32 | *
33 | * @param in Input byte array
34 | */
35 | public CloseScreenPacket(@NotNull ByteArrayDataInput in) {
36 | super(KEY);
37 | this.screenKey = Key.of(in.readUTF());
38 | }
39 |
40 | /**
41 | * Get the unique identifying key for the screen to close.
42 | *
43 | * @return Screen's key
44 | */
45 | @NotNull
46 | public Key getScreenKey() {
47 | return this.screenKey;
48 | }
49 |
50 | @Override
51 | public void handle(@NotNull PacketListener listener) {
52 | listener.handleCloseScreen(this);
53 | }
54 |
55 | @Override
56 | @NotNull
57 | public ByteArrayDataOutput write() {
58 | ByteArrayDataOutput out = out(this);
59 | out.writeUTF(getScreenKey().toString());
60 | return out;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/network/packet/ElementClickedPacket.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.network.packet;
2 |
3 | import com.google.common.io.ByteArrayDataInput;
4 | import com.google.common.io.ByteArrayDataOutput;
5 | import net.pl3x.guithium.api.gui.Screen;
6 | import net.pl3x.guithium.api.gui.element.ClickableElement;
7 | import net.pl3x.guithium.api.key.Key;
8 | import net.pl3x.guithium.api.network.PacketListener;
9 | import org.jetbrains.annotations.NotNull;
10 |
11 | /**
12 | * Represents a packet containing element click information.
13 | *
14 | * @param Type of element clicked
15 | */
16 | public class ElementClickedPacket> extends Packet {
17 | /**
18 | * Unique identifying key
19 | */
20 | public static final Key KEY = Key.of("packet:element_click");
21 |
22 | private final Key screen;
23 | private final Key element;
24 |
25 | /**
26 | * Create a new element click packet.
27 | *
28 | * @param screen Screen element was clicked on
29 | * @param element Element that was clicked
30 | */
31 | public ElementClickedPacket(@NotNull Screen screen, @NotNull ClickableElement element) {
32 | super(KEY);
33 | this.screen = screen.getKey();
34 | this.element = element.getKey();
35 | }
36 |
37 | /**
38 | * Create a new element click packet.
39 | *
40 | * @param in Input byte array
41 | */
42 | public ElementClickedPacket(@NotNull ByteArrayDataInput in) {
43 | super(KEY);
44 | this.screen = Key.of(in.readUTF());
45 | this.element = Key.of(in.readUTF());
46 | }
47 |
48 | /**
49 | * Get the screen the element was clicked on.
50 | *
51 | * @return Element's screen
52 | */
53 | @NotNull
54 | public Key getScreen() {
55 | return this.screen;
56 | }
57 |
58 | /**
59 | * Get the element that was clicked.
60 | *
61 | * @return Clicked element
62 | */
63 | @NotNull
64 | public Key getElement() {
65 | return this.element;
66 | }
67 |
68 | @Override
69 | public void handle(@NotNull PacketListener listener) {
70 | listener.handleElementClick(this);
71 | }
72 |
73 | @Override
74 | @NotNull
75 | public ByteArrayDataOutput write() {
76 | ByteArrayDataOutput out = out(this);
77 | out.writeUTF(getScreen().toString());
78 | out.writeUTF(getElement().toString());
79 | return out;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/network/packet/ElementPacket.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.network.packet;
2 |
3 | import com.google.common.io.ByteArrayDataInput;
4 | import com.google.common.io.ByteArrayDataOutput;
5 | import net.pl3x.guithium.api.gui.element.Element;
6 | import net.pl3x.guithium.api.json.Gson;
7 | import net.pl3x.guithium.api.key.Key;
8 | import net.pl3x.guithium.api.network.PacketListener;
9 | import org.jetbrains.annotations.NotNull;
10 |
11 | /**
12 | * Represents an update element packet.
13 | */
14 | public class ElementPacket extends Packet {
15 | /**
16 | * Unique identifier for element packets.
17 | */
18 | public static final Key KEY = Key.of("packet:element");
19 |
20 | private final Element element;
21 |
22 | /**
23 | * Create a new update element packet.
24 | *
25 | * @param element Element to update
26 | */
27 | public ElementPacket(@NotNull Element element) {
28 | super(KEY);
29 | this.element = element;
30 | }
31 |
32 | /**
33 | * Create a new update element packet.
34 | *
35 | * @param in Input byte array
36 | */
37 | public ElementPacket(@NotNull ByteArrayDataInput in) {
38 | super(KEY);
39 | this.element = Gson.fromJson(in.readUTF(), Element.class);
40 | }
41 |
42 | /**
43 | * Get the element to update.
44 | *
45 | * @return Element to update
46 | */
47 | @NotNull
48 | public Element getElement() {
49 | return this.element;
50 | }
51 |
52 | @Override
53 | public void handle(@NotNull T listener) {
54 | listener.handleElement(this);
55 | }
56 |
57 | @Override
58 | @NotNull
59 | public ByteArrayDataOutput write() {
60 | ByteArrayDataOutput out = out(this);
61 | out.writeUTF(Gson.toJson(getElement()));
62 | return out;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/network/packet/HelloPacket.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.network.packet;
2 |
3 | import com.google.common.io.ByteArrayDataInput;
4 | import com.google.common.io.ByteArrayDataOutput;
5 | import net.pl3x.guithium.api.Guithium;
6 | import net.pl3x.guithium.api.key.Key;
7 | import net.pl3x.guithium.api.network.PacketListener;
8 | import org.jetbrains.annotations.NotNull;
9 |
10 | /**
11 | * Represents a packet that players send when they join the server.
12 | *
13 | * This packet is also used for the server to reply to the player.
14 | */
15 | public class HelloPacket extends Packet {
16 | /**
17 | * Unique identifier for hello packets
18 | */
19 | public static final Key KEY = Key.of("packet:hello");
20 |
21 | private final int protocol;
22 |
23 | /**
24 | * Create new packet, ready to send to player.
25 | */
26 | public HelloPacket() {
27 | this(Guithium.PROTOCOL);
28 | }
29 |
30 | /**
31 | * Create new packet, captured from player.
32 | *
33 | * @param in Inbound raw data byte array
34 | */
35 | public HelloPacket(@NotNull ByteArrayDataInput in) {
36 | this(in.readInt());
37 | }
38 |
39 | private HelloPacket(int protocol) {
40 | super(KEY);
41 | this.protocol = protocol;
42 | }
43 |
44 | /**
45 | * Get the protocol stored in this packet.
46 | *
47 | * @return Protocol number
48 | */
49 | public int getProtocol() {
50 | return this.protocol;
51 | }
52 |
53 | @Override
54 | public void handle(@NotNull PacketListener listener) {
55 | listener.handleHello(this);
56 | }
57 |
58 | @Override
59 | @NotNull
60 | public ByteArrayDataOutput write() {
61 | ByteArrayDataOutput out = out(this);
62 | out.writeInt(getProtocol());
63 | return out;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/network/packet/OpenScreenPacket.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.network.packet;
2 |
3 | import com.google.common.io.ByteArrayDataInput;
4 | import com.google.common.io.ByteArrayDataOutput;
5 | import net.pl3x.guithium.api.gui.Screen;
6 | import net.pl3x.guithium.api.json.Gson;
7 | import net.pl3x.guithium.api.key.Key;
8 | import net.pl3x.guithium.api.network.PacketListener;
9 | import org.jetbrains.annotations.NotNull;
10 |
11 | /**
12 | * Represents an open screen packet.
13 | */
14 | public class OpenScreenPacket extends Packet {
15 | /**
16 | * Unique identifying key
17 | */
18 | public static final Key KEY = Key.of("packet:open_screen");
19 |
20 | private final Screen screen;
21 |
22 | /**
23 | * Create an open screen packet.
24 | *
25 | * @param screen Screen to open
26 | */
27 | public OpenScreenPacket(@NotNull Screen screen) {
28 | super(KEY);
29 | this.screen = screen;
30 | }
31 |
32 | /**
33 | * Create an open screen packet.
34 | *
35 | * @param in Input byte array
36 | */
37 | public OpenScreenPacket(@NotNull ByteArrayDataInput in) {
38 | super(KEY);
39 | this.screen = Gson.fromJson(in.readUTF(), Screen.class);
40 | }
41 |
42 | /**
43 | * Get the screen to open
44 | *
45 | * @return Screen to open
46 | */
47 | @NotNull
48 | public Screen getScreen() {
49 | return this.screen;
50 | }
51 |
52 | @Override
53 | public void handle(@NotNull PacketListener listener) {
54 | listener.handleOpenScreen(this);
55 | }
56 |
57 | @Override
58 | @NotNull
59 | public ByteArrayDataOutput write() {
60 | ByteArrayDataOutput out = out(this);
61 | out.writeUTF(Gson.toJson(getScreen()));
62 | return out;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/network/packet/Packet.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.network.packet;
2 |
3 | import com.google.common.io.ByteArrayDataInput;
4 | import com.google.common.io.ByteArrayDataOutput;
5 | import com.google.common.io.ByteStreams;
6 | import net.pl3x.guithium.api.Guithium;
7 | import net.pl3x.guithium.api.key.Key;
8 | import net.pl3x.guithium.api.key.Keyed;
9 | import net.pl3x.guithium.api.network.PacketListener;
10 | import org.jetbrains.annotations.NotNull;
11 |
12 | /**
13 | * Represents a packet of data to send to/from server/client.
14 | */
15 | public abstract class Packet extends Keyed {
16 | /**
17 | * Create a new key identified object.
18 | *
19 | * @param key Unique identifier
20 | */
21 | public Packet(@NotNull Key key) {
22 | super(key);
23 | }
24 |
25 | /**
26 | * Handle this packet with specified listener
27 | *
28 | * @param listener Handling listener
29 | * @param Type of listener
30 | */
31 | public abstract void handle(@NotNull T listener);
32 |
33 | /**
34 | * Write packet to raw data byte array
35 | *
36 | * @return Raw data byte array
37 | */
38 | @NotNull
39 | public abstract ByteArrayDataOutput write();
40 |
41 | /**
42 | * Get outbound raw data byte array for specified packet.
43 | *
44 | * @param packet Packet to use
45 | * @return Outbound raw data byte array
46 | */
47 | @NotNull
48 | public static ByteArrayDataOutput out(@NotNull Packet packet) {
49 | ByteArrayDataOutput out = ByteStreams.newDataOutput();
50 | out.writeInt(Guithium.PROTOCOL);
51 | out.writeUTF(packet.getKey().toString());
52 | return out;
53 | }
54 |
55 | /**
56 | * Get inbound raw data byte array from raw data
57 | *
58 | * @param bytes Raw data
59 | * @return Inbound raw data byte array
60 | */
61 | @NotNull
62 | public static ByteArrayDataInput in(byte[] bytes) {
63 | return ByteStreams.newDataInput(bytes);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/network/packet/TexturesPacket.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.network.packet;
2 |
3 | import com.google.common.io.ByteArrayDataInput;
4 | import com.google.common.io.ByteArrayDataOutput;
5 | import com.google.gson.reflect.TypeToken;
6 | import java.lang.reflect.Type;
7 | import java.util.Collection;
8 | import net.pl3x.guithium.api.gui.texture.Texture;
9 | import net.pl3x.guithium.api.json.Gson;
10 | import net.pl3x.guithium.api.key.Key;
11 | import net.pl3x.guithium.api.network.PacketListener;
12 | import org.jetbrains.annotations.NotNull;
13 |
14 | /**
15 | * Represents a textures packet containing a list of textures to preload.
16 | */
17 | public class TexturesPacket extends Packet {
18 | /**
19 | * Unique identifying key
20 | */
21 | public static final Key KEY = Key.of("packet:textures");
22 |
23 | private static final Type TYPE_TOKEN = new TypeToken>() {
24 | }.getType();
25 |
26 | private final Collection textures;
27 |
28 | /**
29 | * Create a new texture packet.
30 | *
31 | * @param textures Textures to preload
32 | */
33 | public TexturesPacket(@NotNull Collection textures) {
34 | super(KEY);
35 | this.textures = textures;
36 | }
37 |
38 | /**
39 | * Create a new texture packet.
40 | *
41 | * @param in Input byte array
42 | */
43 | public TexturesPacket(@NotNull ByteArrayDataInput in) {
44 | super(KEY);
45 | this.textures = Gson.fromJson(in.readUTF(), TYPE_TOKEN);
46 | }
47 |
48 | /**
49 | * Get the textures to preload.
50 | *
51 | * @return Texture to preload
52 | */
53 | @NotNull
54 | public Collection getTextures() {
55 | return this.textures;
56 | }
57 |
58 | @Override
59 | public void handle(@NotNull PacketListener listener) {
60 | listener.handleTextures(this);
61 | }
62 |
63 | @Override
64 | @NotNull
65 | public ByteArrayDataOutput write() {
66 | ByteArrayDataOutput out = out(this);
67 | out.writeUTF(Gson.toJson(getTextures()));
68 | return out;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/player/PlayerManager.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.player;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import java.util.UUID;
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | /**
10 | * Represents a manager of wrapped players.
11 | */
12 | public abstract class PlayerManager {
13 | private final Map players = new HashMap<>();
14 |
15 | /**
16 | * Create a new player manager instance
17 | */
18 | public PlayerManager() {
19 | // Empty constructor to pacify javadoc lint
20 | }
21 |
22 | /**
23 | * Add and wrap player.
24 | *
25 | * @param player Player to add
26 | * @param Type of player to wrap
27 | * @return the wrapped player that was added
28 | * @throws IllegalArgumentException if player is not correct type for the environment
29 | */
30 | @NotNull
31 | public abstract WrappedPlayer add(@NotNull T player);
32 |
33 | /**
34 | * Add wrapped player.
35 | *
36 | * @param player Wrapped player to add
37 | * @return the wrapped player that was added
38 | */
39 | @NotNull
40 | public WrappedPlayer add(@NotNull WrappedPlayer player) {
41 | this.players.put(player.getUUID(), player);
42 | return player;
43 | }
44 |
45 | /**
46 | * Get a wrapped player.
47 | *
48 | * If player is not currently in the manager, they will be wrapped and added.
49 | *
50 | * @param player Player to get
51 | * @param Type of player
52 | * @return Wrapped player, or null if not managed
53 | * @throws IllegalArgumentException if player is not correct type for the environment
54 | */
55 | @NotNull
56 | public abstract WrappedPlayer get(@NotNull T player);
57 |
58 | /**
59 | * Get a managed player.
60 | *
61 | * @param uuid Unique identifier of player to get
62 | * @return Wrapped player, or null if not managed
63 | */
64 | @Nullable
65 | public WrappedPlayer get(@NotNull UUID uuid) {
66 | return this.players.get(uuid);
67 | }
68 |
69 | /**
70 | * Remove player from manager.
71 | *
72 | * @param player Player to remove
73 | * @param Type of wrapped player
74 | * @return the wrapped player that was removed, or null if there was no player to remove
75 | * @throws IllegalArgumentException if player is not correct type for the environment
76 | */
77 | @Nullable
78 | public abstract WrappedPlayer remove(@NotNull T player);
79 |
80 | /**
81 | * Remove player from manager.
82 | *
83 | * @param uuid Unique identifier of player to remove
84 | * @return the wrapped player that was removed, or null if there was no player to remove
85 | */
86 | @Nullable
87 | public WrappedPlayer remove(@NotNull UUID uuid) {
88 | return this.players.remove(uuid);
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/player/WrappedPlayer.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.player;
2 |
3 | import java.util.UUID;
4 | import net.pl3x.guithium.api.gui.Screen;
5 | import net.pl3x.guithium.api.network.Connection;
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | /**
10 | * A wrapper for a player connected to the server.
11 | */
12 | public interface WrappedPlayer {
13 | /**
14 | * Get the internal player object that is being wrapped.
15 | *
16 | * @param Type of player object
17 | * @return Internal player object
18 | */
19 | @NotNull
20 | T unwrap();
21 |
22 | /**
23 | * Get the player's name.
24 | *
25 | * @return Player's name
26 | */
27 | @NotNull
28 | String getName();
29 |
30 | /**
31 | * Get player's unique identifier.
32 | *
33 | * @return Unique identifier
34 | */
35 | @NotNull
36 | UUID getUUID();
37 |
38 | /**
39 | * Get the player's connection
40 | *
41 | * @return Player connection
42 | */
43 | @NotNull
44 | Connection getConnection();
45 |
46 | /**
47 | * Get the current screen the player is looking at.
48 | *
49 | * @return The current screen
50 | */
51 | @Nullable
52 | Screen getCurrentScreen();
53 |
54 | /**
55 | * Set the screen the player should be looking at.
56 | *
57 | * @param screen The screen
58 | */
59 | void setCurrentScreen(@Nullable Screen screen);
60 |
61 | /**
62 | * Check if player has Guithium client mod installed.
63 | *
64 | * @return {@code true} if player has Guithium mod, otherwise {@code false}
65 | */
66 | boolean hasGuithium();
67 | }
68 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/scheduler/AbstractScheduler.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.scheduler;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Iterator;
5 | import java.util.List;
6 | import org.jetbrains.annotations.NotNull;
7 |
8 | /**
9 | * Represents the tick based task scheduler.
10 | */
11 | public abstract class AbstractScheduler {
12 | private final List tasks = new ArrayList<>();
13 |
14 | /**
15 | * Create a new scheduler.
16 | */
17 | public AbstractScheduler() {
18 | // Empty constructor to pacify javadoc lint
19 | }
20 |
21 | /**
22 | * Register the scheduler so it starts ticking.
23 | */
24 | public abstract void register();
25 |
26 | /**
27 | * Tick the scheduler.
28 | */
29 | protected void tick() {
30 | Iterator iter = this.tasks.iterator();
31 | while (iter.hasNext()) {
32 | Task task = iter.next();
33 | if (task.tick++ < task.delay) {
34 | continue;
35 | }
36 | if (task.cancelled()) {
37 | iter.remove();
38 | continue;
39 | }
40 | task.run();
41 | if (task.repeat) {
42 | task.tick = 0;
43 | continue;
44 | }
45 | iter.remove();
46 | }
47 | }
48 |
49 | /**
50 | * Cancel all scheduled tasks.
51 | */
52 | public void cancelAll() {
53 | Iterator iter = this.tasks.iterator();
54 | while (iter.hasNext()) {
55 | iter.next().cancel();
56 | iter.remove();
57 | }
58 | }
59 |
60 | /**
61 | * Add task to the scheduler.
62 | *
63 | * @param task Task to add
64 | */
65 | public void addTask(@NotNull Task task) {
66 | this.tasks.add(task);
67 | }
68 |
69 | /**
70 | * Add non-repeating task to the scheduler to run on the next tick.
71 | *
72 | * @param runnable Task to add
73 | */
74 | public void addTask(@NotNull Runnable runnable) {
75 | addTask(0, runnable);
76 | }
77 |
78 | /**
79 | * Add non-repeating task to the scheduler with delay.
80 | *
81 | * @param delay Delay (in ticks) before task runs
82 | * @param runnable Task to add
83 | */
84 | public void addTask(int delay, @NotNull Runnable runnable) {
85 | addTask(delay, false, runnable);
86 | }
87 |
88 | /**
89 | * Add task to the scheduler.
90 | *
91 | * @param delay Delay (in ticks) before task runs
92 | * @param repeat Whether task should start again after running
93 | * @param runnable Task to add
94 | */
95 | public void addTask(int delay, boolean repeat, @NotNull Runnable runnable) {
96 | addTask(new Task(delay, repeat) {
97 | @Override
98 | public void run() {
99 | runnable.run();
100 | }
101 | });
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/scheduler/Task.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.scheduler;
2 |
3 | /**
4 | * Represents a task that can be scheduled
5 | */
6 | public abstract class Task implements Runnable {
7 | final int delay;
8 | final boolean repeat;
9 |
10 | boolean cancelled = false;
11 | int tick;
12 |
13 | /**
14 | * Create a new task.
15 | *
16 | * @param delay Delay (in ticks) before task runs
17 | */
18 | public Task(int delay) {
19 | this(delay, false);
20 | }
21 |
22 | /**
23 | * Create a new task.
24 | *
25 | * @param delay Delay (in ticks) before task runs
26 | * @param repeat Whether task should start again after running
27 | */
28 | public Task(int delay, boolean repeat) {
29 | this.delay = delay;
30 | this.repeat = repeat;
31 | }
32 |
33 | /**
34 | * Cancel the task from running.
35 | */
36 | public void cancel() {
37 | this.cancelled = true;
38 | }
39 |
40 | /**
41 | * Check if task is cancelled.
42 | *
43 | * @return {@code true} is cancelled, otherwise {@code false}
44 | */
45 | public boolean cancelled() {
46 | return this.cancelled;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/util/Mathf.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.util;
2 |
3 | /**
4 | * Math utility that works with floats rather than doubles
5 | */
6 | public abstract class Mathf {
7 | private Mathf() {
8 | // Empty constructor to pacify javadoc lint
9 | }
10 |
11 | private final static float DEG2RAD = (float) (Math.PI / 180D);
12 | private final static float RAD2DEG = (float) (180D / Math.PI);
13 |
14 | /**
15 | * Converts an angle measured in degrees to an approximately
16 | * equivalent angle measured in radians. The conversion from
17 | * degrees to radians is generally inexact.
18 | *
19 | * @param degrees an angle, in degrees
20 | * @return the measurement of the angle {@code degrees} in radians.
21 | */
22 | public static float toRadians(final float degrees) {
23 | return degrees * DEG2RAD;
24 | }
25 |
26 | /**
27 | * Converts an angle measured in radians to an approximately
28 | * equivalent angle measured in degrees. The conversion from
29 | * radians to degrees is generally inexact; users should
30 | * not expect {@code cos(toRadians(90.0))} to exactly
31 | * equal {@code 0.0}.
32 | *
33 | * @param radians an angle, in radians
34 | * @return the measurement of the angle {@code radians} in degrees.
35 | */
36 | public static float toDegrees(final float radians) {
37 | return radians * RAD2DEG;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/util/QuadConsumer.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.util;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 |
5 | /**
6 | * This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
7 | *
8 | * @param the type of the first argument to the operation
9 | * @param the type of the second argument to the operation
10 | * @param the type of the third argument to the operation
11 | * @param the type of the forth argument to the operation
12 | */
13 | @FunctionalInterface
14 | public interface QuadConsumer {
15 | /**
16 | * Performs this operation on the given arguments.
17 | *
18 | * @param t the first input argument
19 | * @param u the second input argument
20 | * @param v the third input argument
21 | * @param w the forth input argument
22 | */
23 | void accept(@NotNull T t, @NotNull U u, @NotNull V v, @NotNull W w);
24 | }
25 |
--------------------------------------------------------------------------------
/api/src/main/java/net/pl3x/guithium/api/util/TriConsumer.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.api.util;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 |
5 | /**
6 | * This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
7 | *
8 | * @param the type of the first argument to the operation
9 | * @param the type of the second argument to the operation
10 | * @param the type of the third argument to the operation
11 | */
12 | @FunctionalInterface
13 | public interface TriConsumer {
14 | /**
15 | * Performs this operation on the given arguments.
16 | *
17 | * @param t the first input argument
18 | * @param u the second input argument
19 | * @param v the third input argument
20 | */
21 | void accept(@NotNull T t, @NotNull U u, @NotNull V v);
22 | }
23 |
--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | _site
2 | .sass-cache/
3 | .jekyll-cache/
4 | .jekyll-metadata
5 |
6 | .bundle
7 | vendor/
8 | .idea/
9 |
--------------------------------------------------------------------------------
/docs/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem "jekyll", "~> 4.4.1" # installed by `gem jekyll`
4 | # gem "webrick" # required when using Ruby >= 3 and Jekyll <= 4.2.2
5 |
6 | gem "just-the-docs", "0.10.1" # pinned to the current release
7 | # gem "just-the-docs" # always download the latest release
8 |
--------------------------------------------------------------------------------
/docs/_includes/footer_custom.html:
--------------------------------------------------------------------------------
1 |
2 |
Copyright © 2022-2025 William Blake Galbreath (BillyGalbreath)
3 |
4 | This website is not an official Minecraft website and is not associated with Mojang Studios or Microsoft.
5 | All product and company names are trademarks or registered trademarks of their respective holders.
6 | Use of these names does not imply any affiliation or endorsement by them.
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/_includes/head_custom.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pl3x-net/guithium/4a6f1fdf3d3be182323e444595d518ed3346ce83/docs/_includes/head_custom.html
--------------------------------------------------------------------------------
/docs/_includes/header_custom.html:
--------------------------------------------------------------------------------
1 | {% if site.nav_external_links %}
2 |
18 | {% endif %}
19 |
--------------------------------------------------------------------------------
/docs/_includes/js/custom.js:
--------------------------------------------------------------------------------
1 | realRemoveAttr = Element.prototype.removeAttribute;
2 | Element.prototype.removeAttribute = function(attr) {
3 | if (attr == 'href') {
4 | return;// this.setAttribute(attr, '#');
5 | }
6 | realRemoveAttr(attr);
7 | }
8 |
--------------------------------------------------------------------------------
/docs/_includes/nav_footer_custom.html:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/docs/_includes/search_placeholder_custom.html:
--------------------------------------------------------------------------------
1 | Search
2 |
--------------------------------------------------------------------------------
/docs/_includes/toc_heading_custom.html:
--------------------------------------------------------------------------------
1 | Contents
2 |
--------------------------------------------------------------------------------
/docs/_sass/color_schemes/guithium.scss:
--------------------------------------------------------------------------------
1 | @import "./color_schemes/dark";
2 |
3 | $color-scheme: dark;
4 |
5 | $body-background-color: #1e1f22; // $grey-dk-300;
6 | $body-heading-color: #f5f6fa; // $grey-lt-000;
7 | $body-text-color: #bcbec4; // $grey-lt-300;
8 | $link-color: #90caf9; // $blue-000;
9 | $nav-child-link-color: #959396; // $grey-dk-000;
10 | $sidebar-color: #2b2d30; // $grey-dk-300;
11 | $base-button-color: #302d36; // $grey-dk-250;
12 | $btn-primary-color: #264caf; // $blue-200;
13 | $code-background-color: #31343f; // #31343f // OneDarkJekyll default for syntax-one-dark-vivid
14 | $code-linenumber-color: #dee2f7; // #dee2f7 // OneDarkJekyll .nf for syntax-one-dark-vivid
15 | $feedback-color: #26282b; // darken($sidebar-color, 2%);
16 | $table-background-color: #2b2d30; // $grey-dk-250;
17 | $search-background-color: #2b2d30; // $grey-dk-250;
18 | $search-result-preview-color: #959396; // $grey-dk-000;
19 | $border-color: #454545; // $grey-dk-200;
20 |
21 | $white: #fff !default;
22 | $grey-dk-000: #959396 !default;
23 | $grey-dk-100: #5c5962 !default;
24 | $grey-dk-200: #44434d !default;
25 | $grey-dk-250: #302d36 !default;
26 | $grey-dk-300: #27262b !default;
27 | $grey-lt-000: #f5f6fa !default;
28 | $grey-lt-100: #eeebee !default;
29 | $grey-lt-200: #ecebed !default;
30 | $grey-lt-300: #e6e1e8 !default;
31 | $purple-000: #7253ed !default;
32 | $purple-100: #5e41d0 !default;
33 | $purple-200: #4e26af !default;
34 | $purple-300: #381885 !default;
35 | $blue-000: #2c84fa !default;
36 | $blue-100: #2869e6 !default;
37 | $blue-200: #264caf !default;
38 | $blue-300: #183385 !default;
39 | $green-000: #41d693 !default;
40 | $green-100: #11b584 !default;
41 | $green-200: #009c7b !default;
42 | $green-300: #026e57 !default;
43 | $yellow-000: #ffeb82 !default;
44 | $yellow-100: #fadf50 !default;
45 | $yellow-200: #f7d12e !default;
46 | $yellow-300: #e7af06 !default;
47 | $red-000: #f77e7e !default;
48 | $red-100: #f96e65 !default;
49 | $red-200: #e94c4c !default;
50 | $red-300: #dd2e2e !default;
51 |
--------------------------------------------------------------------------------
/docs/_sass/custom/custom.scss:
--------------------------------------------------------------------------------
1 | #logos-svg {
2 | display: none;
3 | }
4 | .main-header {
5 | div#external-links {
6 | margin-top: 12px;
7 | a {
8 | text-decoration: none;
9 | svg {
10 | margin: 4px;
11 | width: 24px;
12 | height: 24px;
13 | background: transparent;
14 | color: $body-text-color;
15 | transition: 0.3s;
16 | }
17 | &:hover svg {
18 | color: $body-background-color;
19 | filter: drop-shadow(0 0 3px $body-heading-color);
20 | }
21 | }
22 | }
23 | }
24 | .center {
25 | text-align: center;
26 | }
27 |
--------------------------------------------------------------------------------
/docs/api.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: API
3 | nav_order: 4
4 | has_toc: false
5 | ---
6 |
7 | ## API
8 |
--------------------------------------------------------------------------------
/docs/api/element/button.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Button
3 | parent: Elements
4 | nav_order: 1
5 | has_toc: false
6 | ---
7 |
8 | ## Button
9 |
--------------------------------------------------------------------------------
/docs/api/element/checkbox.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Checkbox
3 | parent: Elements
4 | nav_order: 2
5 | has_toc: false
6 | ---
7 |
8 | ## Checkbox
9 |
--------------------------------------------------------------------------------
/docs/api/element/circle.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Circle
3 | parent: Elements
4 | nav_order: 3
5 | has_toc: false
6 | ---
7 |
8 | ## Circle
9 |
--------------------------------------------------------------------------------
/docs/api/element/gradient.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Gradient
3 | parent: Elements
4 | nav_order: 4
5 | has_toc: false
6 | ---
7 |
8 | ## Gradient
9 |
--------------------------------------------------------------------------------
/docs/api/element/image.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Image
3 | parent: Elements
4 | nav_order: 5
5 | has_toc: false
6 | ---
7 |
8 | ## Image
9 |
10 | Image is an element to display a Texture on a Screen.
11 |
12 | ### Position
13 | This is the position on the screen in scaled pixels where 0,0 is the top left of the screen.
14 |
15 | Omitting the position will default to `0.0, 0.0`.
16 |
17 | ### Anchor
18 | This is the anchor point where the Position starts from. This is a percentage (0.0-1.0) of the Screen's size.
19 |
20 | Omitting the anchor will default to `0.0, 0.0`.
21 |
22 | Examples:
23 | `0.0, 0.0` will anchor the Position to the top left corner of the Screen.
24 | `0.5, 0.5` will anchor the Position to the center of the Screen.
25 | `1.0, 1.0` will anchor the Position to the bottom right of the Screen.
26 |
27 | ### Offset
28 | This is the offset point where the Position aligns on the Image. This is a percentage (0.0-1.0) of the Image's size.
29 |
30 | Omitting the offset will default to `0.0, 0.0`.
31 |
32 | Examples:
33 | `0.0, 0.0` will offset the Image so the top left corner of the Image is at the anchored position.
34 | `0.5, 0.5` will offset the Image so the center of the Image is at the anchored position.
35 | `1.0, 1.0` will offset the Image so the bottom right corner of the Image is at the anchored position.
36 |
37 | ### Size
38 | This is the size of the Image in scaled pixels.
39 |
40 | Omitting the size will default to the Screen's full width and height.
41 |
42 | ### Texture
43 | This is the Texture to draw.
44 |
45 | ### Vertex Color
46 | This controls how much of a texture's colors show through on the screen. See Mojang's [position texture color fragment shader](https://mcasset.cloud/1.19.2/assets/minecraft/shaders/core/position_tex_color.fsh) for details.
47 |
48 | Eg, a modifier of `0xFF00FFFF` will remove all red from the texture.
49 |
50 | Omitting the vertex color will default to `0xFFFFFFFF` (opaque white).
51 |
52 | ### TileModifier
53 | This is used to divide the UV into tiled segments on each axis (repeat).
54 |
55 | Eg, a value of 32 is used on vanilla option screens with the dirt texture in order to get the tiled effect. This does not mean it is tiled 32 times.
56 |
57 | Omitting the tile modifier will default to `1.0` (no tile/repeat).
58 |
59 | Examples:
60 | `1.0` makes the texture fit `1` times inside the allotted size, showing only the single image.
61 | `2.0` makes the texture fit `2` times inside the allotted size, showing 4 images tiled in a 2x2.
62 | `0.5` makes the texture fit `0.5` times inside the allotted size, showing the top left 25% of the image.
63 |
64 | # Examples
65 |
66 | ### Basic Image
67 | An example of a basic image
68 | ```java
69 | Image image = Image.builder("my_plugin:github")
70 | .setPos(0, 20)
71 | .setSize(50, 50)
72 | .setTexture(new Texture("my_plugin:github_logo", "https://cdn-icons-png.flaticon.com/512/25/25231.png"))
73 | .build();
74 | ```
75 |
76 | ### Tiled Image
77 | An example of a tiled image.
78 |
79 | **Note**: *This Image is provided to you at `Image.TILED_DIRT` since it is a common Image (used in options screens).*
80 | ```java
81 | public static final Image TILED_DIRT = Image.builder("guithium:tiled_dirt")
82 | .setTexture(new Texture("minecraft:dirt", "textures/gui/options_background.png"))
83 | .setVertexColor(0xFF404040)
84 | .setTileModifier(32.0F)
85 | .build();
86 | ```
87 |
--------------------------------------------------------------------------------
/docs/api/element/line.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Line
3 | parent: Elements
4 | nav_order: 6
5 | has_toc: false
6 | ---
7 |
8 | ## Line
9 |
--------------------------------------------------------------------------------
/docs/api/element/radio.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Radio
3 | parent: Elements
4 | nav_order: 7
5 | has_toc: false
6 | ---
7 |
8 | ## Radio
9 |
--------------------------------------------------------------------------------
/docs/api/element/slider.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Slider
3 | parent: Elements
4 | nav_order: 8
5 | has_toc: false
6 | ---
7 |
8 | ## Slider
9 |
--------------------------------------------------------------------------------
/docs/api/element/text.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Text
3 | parent: Elements
4 | nav_order: 9
5 | has_toc: false
6 | ---
7 |
8 | ## Text
9 |
--------------------------------------------------------------------------------
/docs/api/element/textbox.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Textbox
3 | parent: Elements
4 | nav_order: 10
5 | has_toc: false
6 | ---
7 |
8 | ## Textbox
9 |
--------------------------------------------------------------------------------
/docs/api/elements.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Elements
3 | parent: API
4 | nav_order: 1
5 | has_toc: true
6 | ---
7 |
8 | ## Elements
9 |
--------------------------------------------------------------------------------
/docs/api/screen.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Screen
3 | parent: API
4 | nav_order: 2
5 | has_toc: false
6 | ---
7 |
8 | ## Screen
9 |
--------------------------------------------------------------------------------
/docs/api/texture.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Texture
3 | parent: API
4 | nav_order: 3
5 | has_toc: false
6 | ---
7 |
8 | ## Texture
9 |
10 | *This needs updating. Was pulled from the old wiki. Information is likely outdated*
11 |
12 | Texture is an image that can be drawn on the screen.
13 |
14 | You can use textures that are already loaded in the game (from vanilla, or other mods) or load new ones in directly from the internet.
15 |
16 | Textures require 2 parameters. First one is a unique Key that we use to identify it. The second is where the image file is located.
17 |
18 | ### Vanilla Textures
19 |
20 | For example, to use a vanilla texture:
21 |
22 | ```java
23 | // without namespace
24 | Texture texture = new Texture(Key.of("some:unique_key"), "textures/gui/options_background.png");
25 | // or with the namespace
26 | Texture texture = new Texture(Key.of("some:unique_key"), "minecraft:textures/gui/options_background.png");
27 | ```
28 |
29 | ### Modded Textures
30 |
31 | To use a loaded image from another mod just use the mod_id for the namespace:
32 |
33 | ```java
34 | Texture texture = new Texture(Key.of("some:unique_key"), "mod_id:textures/path/image.png");
35 | ```
36 |
37 | ### External Textures
38 |
39 | To use an external image from the internet, just use the url (beginning with `http://` or `https://`)
40 |
41 | ```java
42 | Texture texture = new Texture(Key.of("some:unique_key"), "https://avatars.githubusercontent.com/u/332527?v=4");
43 | ```
44 |
45 | # Preloading Textures
46 |
47 | If you are using textures from the internet, they will have to be loaded into memory during runtime. Normally textures are loaded when the game does that huge loading bar overlay (starting the game and loading resource packs), and takes quite some time to do.
48 |
49 | We offer you a `TextureManager` where you can preload your textures into. This makes using them in your GUIs just as fast and efficient as using native vanilla textures.
50 |
51 | ```java
52 | public void onEnable() {
53 | Texture texture = new Texture("my_plugin:hayley", "https://pl3x.net/hayley.png");
54 | Guithium.api().getTextureManager().add(texture);
55 | }
56 | ```
57 |
--------------------------------------------------------------------------------
/docs/assets/images/fabric.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pl3x-net/guithium/4a6f1fdf3d3be182323e444595d518ed3346ce83/docs/assets/images/fabric.png
--------------------------------------------------------------------------------
/docs/assets/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pl3x-net/guithium/4a6f1fdf3d3be182323e444595d518ed3346ce83/docs/assets/images/favicon.ico
--------------------------------------------------------------------------------
/docs/assets/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pl3x-net/guithium/4a6f1fdf3d3be182323e444595d518ed3346ce83/docs/assets/images/favicon.png
--------------------------------------------------------------------------------
/docs/assets/images/paper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pl3x-net/guithium/4a6f1fdf3d3be182323e444595d518ed3346ce83/docs/assets/images/paper.png
--------------------------------------------------------------------------------
/docs/assets/images/purpur.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pl3x-net/guithium/4a6f1fdf3d3be182323e444595d518ed3346ce83/docs/assets/images/purpur.png
--------------------------------------------------------------------------------
/docs/faq.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: F.A.Q.
3 | nav_order: 2
4 | has_toc: false
5 | ---
6 |
7 | ## Frequently Asked Questions
8 |
--------------------------------------------------------------------------------
/docs/getting-started/developers.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Developers
3 | parent: Getting Started
4 | nav_order: 2
5 | ---
6 |
7 | ## Developers
8 |
9 | Javadoc: https://jd.pl3x.net/net/pl3x/guithium/guithium-api/latest/
10 |
11 | Repository (Gradle)
12 |
13 | ```groovy
14 | repositories {
15 | maven { url = 'https://repo.pl3x.net/public/' }
16 | }
17 |
18 | dependencies {
19 | compileOnly 'net.pl3x.guithium:guithium-api:0.0.1-SNAPSHOT'
20 | }
21 | ```
22 |
23 | Repository (Maven)
24 |
25 | ```xml
26 |
27 |
28 |
29 | pl3x-repo
30 | https://repo.pl3x.net/public/
31 |
32 |
33 | net.pl3x.guithium
34 | guithium-api
35 | 0.0.1-SNAPSHOT
36 | provided
37 |
38 |
39 | ```
40 |
--------------------------------------------------------------------------------
/docs/getting-started/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Getting Started
3 | nav_order: 3
4 | has_toc: false
5 | ---
6 |
7 | ## Getting Started
8 |
--------------------------------------------------------------------------------
/docs/getting-started/installation.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Installation
3 | parent: Getting Started
4 | nav_order: 1
5 | ---
6 |
7 | ## Installation
8 |
--------------------------------------------------------------------------------
/docs/integrations.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Integrations
3 | nav_order: 5
4 | has_toc: false
5 | ---
6 |
7 | ## Integrations
8 |
9 | Here is a list of known plugins that utilize the Guithium API to provide their users a better GUI experience.
10 |
11 | | Plugin | Links |
12 | |:----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------:|
13 | | GuithiumExample | [![][Modrinth]](https://modrinth.com/plugin/GuithiumExample){:target="_blank"} [![][GitHub]](https://github.com/pl3x-net/GuithiumExample){:target="_blank"} |
14 |
15 | Are you a developer and have integrated Guithium into your plugin and want to see your project listed below? Use the link below to edit this page!
16 |
17 |
18 | [Discord]: /guithium/assets/images/discord.png
19 | [GitHub]: /guithium/assets/images/github.png
20 | [Modrinth]: /guithium/assets/images/modrinth.png
21 |
--------------------------------------------------------------------------------
/fabric/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.fabric.loom)
3 | }
4 |
5 | loom {
6 | @Suppress("UnstableApiUsage")
7 | mixin.defaultRefmapName = "guithium.refmap.json"
8 | accessWidenerPath = file("src/main/resources/guithium.accesswidener")
9 | runConfigs.configureEach {
10 | ideConfigGenerated(true)
11 | }
12 | }
13 |
14 | dependencies {
15 | implementation(project(":api"))
16 |
17 | minecraft(libs.minecraft)
18 | mappings(loom.officialMojangMappings())
19 |
20 | modImplementation(libs.fabric.loader)
21 | modImplementation(libs.fabric.api.get())
22 |
23 | modImplementation(libs.adventure.fabric) {
24 | // Temporary: kyori compiled ansi against jdk22
25 | // which causes the remapJar task to fail :/
26 | exclude("net.kyori", "ansi")
27 | }
28 |
29 | // this escapes >= in fabric.mod.json to \u003e\u003d
30 | // but its the only sane way to include adventure jar
31 | // without also pulling in all the other b.s.
32 | include(libs.adventure.fabric)
33 | }
34 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/GuithiumMod.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric;
2 |
3 | import java.lang.reflect.Field;
4 | import net.fabricmc.api.ClientModInitializer;
5 | import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
6 | import net.pl3x.guithium.api.Guithium;
7 | import net.pl3x.guithium.api.action.ActionRegistry;
8 | import net.pl3x.guithium.api.network.packet.HelloPacket;
9 | import net.pl3x.guithium.api.player.PlayerManager;
10 | import net.pl3x.guithium.fabric.gui.HudManager;
11 | import net.pl3x.guithium.fabric.gui.texture.FabricTextureManager;
12 | import net.pl3x.guithium.fabric.network.FabricNetworkHandler;
13 | import net.pl3x.guithium.fabric.scheduler.Scheduler;
14 | import org.jetbrains.annotations.NotNull;
15 |
16 | public class GuithiumMod implements ClientModInitializer, Guithium {
17 | private final FabricNetworkHandler networkHandler = new FabricNetworkHandler(this);
18 | private final FabricTextureManager textureManager = new FabricTextureManager();
19 |
20 | private final HudManager hudManager = new HudManager();
21 | private final Scheduler scheduler = new Scheduler();
22 |
23 | private final String version;
24 |
25 | public GuithiumMod() {
26 | String version = getClass().getPackage().getImplementationVersion();
27 | this.version = version == null ? "unknown" : version;
28 |
29 | try {
30 | Field api = Provider.class.getDeclaredField("api");
31 | api.setAccessible(true);
32 | api.set(null, this);
33 | } catch (NoSuchFieldException | IllegalAccessException e) {
34 | logger.error("Failed to set Guithium API", e);
35 | }
36 | }
37 |
38 | @Override
39 | public void onInitializeClient() {
40 | getNetworkHandler().registerListeners();
41 |
42 | getScheduler().register();
43 |
44 | // tell server hello when joining so it knows we have guithium installed
45 | ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> {
46 | // ensure we are not connecting to a single player game
47 | if (!client.isLocalServer()) {
48 | // wait for first client tick to ensure everything is ready to receive a reply
49 | getScheduler().addTask(() -> getNetworkHandler().getConnection().send(new HelloPacket()));
50 | }
51 | });
52 |
53 | // clean everything up when disconnecting from server
54 | ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> {
55 | getScheduler().cancelAll();
56 | getTextureManager().clear();
57 | getHudManager().clear();
58 | });
59 | }
60 |
61 | @Override
62 | @NotNull
63 | public String getVersion() {
64 | return this.version;
65 | }
66 |
67 | @Override
68 | @NotNull
69 | public ActionRegistry getActionRegistry() {
70 | throw new UnsupportedOperationException("Not supported on client.");
71 | }
72 |
73 | @Override
74 | @NotNull
75 | public FabricNetworkHandler getNetworkHandler() {
76 | return this.networkHandler;
77 | }
78 |
79 | @Override
80 | @NotNull
81 | public PlayerManager getPlayerManager() {
82 | throw new UnsupportedOperationException("Not supported on client.");
83 | }
84 |
85 | @Override
86 | @NotNull
87 | public FabricTextureManager getTextureManager() {
88 | return this.textureManager;
89 | }
90 |
91 | @NotNull
92 | public HudManager getHudManager() {
93 | return this.hudManager;
94 | }
95 |
96 | @NotNull
97 | public Scheduler getScheduler() {
98 | return this.scheduler;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/Gfx.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui;
2 |
3 | import net.minecraft.client.gui.GuiGraphics;
4 | import net.pl3x.guithium.api.Guithium;
5 | import org.jetbrains.annotations.NotNull;
6 |
7 | public abstract class Gfx {
8 | private Gfx() {
9 | // Empty constructor to pacify javadoc lint
10 | }
11 |
12 | public static void wrap(@NotNull GuiGraphics gfx, @NotNull Runnable runnable) {
13 | gfx.pose().pushPose();
14 | try {
15 | runnable.run();
16 | } catch (Exception e) {
17 | Guithium.logger.error("Uncaught exception trying to render wrapped task", e);
18 | }
19 | gfx.pose().popPose();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/HudManager.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import net.minecraft.client.Minecraft;
6 | import net.minecraft.client.gui.GuiGraphics;
7 | import net.pl3x.guithium.api.key.Key;
8 | import net.pl3x.guithium.fabric.gui.screen.AbstractScreen;
9 | import org.jetbrains.annotations.NotNull;
10 | import org.jetbrains.annotations.Nullable;
11 |
12 | public class HudManager {
13 | private final Map screens = new HashMap<>();
14 |
15 | public void add(@NotNull AbstractScreen screen) {
16 | this.screens.put(screen.getKey(), screen);
17 | screen.init(
18 | Minecraft.getInstance(),
19 | Minecraft.getInstance().getWindow().getGuiScaledWidth(),
20 | Minecraft.getInstance().getWindow().getGuiScaledHeight()
21 | );
22 | screen.refresh();
23 | }
24 |
25 | @NotNull
26 | public Map getAllScreens() {
27 | return this.screens;
28 | }
29 |
30 | @Nullable
31 | public AbstractScreen get(@NotNull Key key) {
32 | return this.screens.get(key);
33 | }
34 |
35 | @Nullable
36 | public AbstractScreen remove(@NotNull Key key) {
37 | return this.screens.remove(key);
38 | }
39 |
40 | public void clear() {
41 | this.screens.clear();
42 | }
43 |
44 | public void preRender(@NotNull GuiGraphics gfx, float delta) {
45 | if (!Minecraft.getInstance().gui.getDebugOverlay().showDebugScreen()) {
46 | this.screens.values().forEach((screen) -> screen.preRender(gfx, delta));
47 | }
48 | }
49 |
50 | public void postRender(@NotNull GuiGraphics gfx, float delta) {
51 | if (!Minecraft.getInstance().gui.getDebugOverlay().showDebugScreen()) {
52 | this.screens.values().forEach((screen) -> screen.postRender(gfx, delta));
53 | }
54 | }
55 |
56 | public void refresh() {
57 | this.screens.forEach((key, screen) -> screen.refresh());
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/element/RenderableButton.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui.element;
2 |
3 | import java.util.function.Supplier;
4 | import net.minecraft.client.Minecraft;
5 | import net.minecraft.client.gui.GuiGraphics;
6 | import net.minecraft.client.gui.components.Tooltip;
7 | import net.minecraft.client.resources.sounds.SimpleSoundInstance;
8 | import net.minecraft.network.chat.Component;
9 | import net.minecraft.sounds.SoundEvents;
10 | import net.pl3x.guithium.api.gui.element.Button;
11 | import net.pl3x.guithium.api.gui.element.Element;
12 | import net.pl3x.guithium.api.network.packet.ElementClickedPacket;
13 | import net.pl3x.guithium.fabric.gui.screen.AbstractScreen;
14 | import net.pl3x.guithium.fabric.util.ComponentHelper;
15 | import org.jetbrains.annotations.NotNull;
16 |
17 | public class RenderableButton extends net.minecraft.client.gui.components.Button implements RenderableWidget {
18 | private final RenderableDuck self;
19 |
20 | private Button button;
21 |
22 | public RenderableButton(@NotNull Minecraft client, @NotNull AbstractScreen screen, @NotNull Button button) {
23 | super(0, 0, 0, 0, Component.empty(), null, Supplier::get);
24 | this.self = ((RenderableDuck) this).duck(client, screen);
25 | this.button = button;
26 | }
27 |
28 | @NotNull
29 | public Button getElement() {
30 | return this.button;
31 | }
32 |
33 | @Override
34 | public void updateElement(@NotNull Element element) {
35 | this.button = (Button) element;
36 | this.self.getScreen().refresh();
37 | }
38 |
39 | @Override
40 | public void init() {
41 | // update contents
42 | setMessage(ComponentHelper.toVanilla(this.button.getLabel()));
43 | setTooltip(Tooltip.create(ComponentHelper.toVanilla(this.button.getTooltip())));
44 |
45 | // update pos/size
46 | setX((int) getElement().getPos().getX());
47 | setY((int) getElement().getPos().getY());
48 | setWidth((int) getElement().getSize().getX());
49 | setHeight((int) getElement().getSize().getY());
50 |
51 | // recalculate position on screen
52 | this.self.calcScreenPos(getWidth(), getHeight());
53 | }
54 |
55 | @Override
56 | public void renderWidget(@NotNull GuiGraphics gfx, int mouseX, int mouseY, float delta) {
57 | this.self.rotate(gfx, this.self.getCenterX(), this.self.getCenterY(), getElement().getRotation());
58 | this.self.scale(gfx, this.self.getCenterX(), this.self.getCenterY(), getElement().getScale());
59 |
60 | super.renderWidget(gfx, mouseX, mouseY, delta);
61 | }
62 |
63 | @Override
64 | public void onPress() {
65 | this.self.getClient().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
66 | conn().send(new ElementClickedPacket<>(this.self.getScreen().getScreen(), getElement()));
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/element/RenderableCheckbox.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui.element;
2 |
3 | import net.minecraft.client.Minecraft;
4 | import net.minecraft.client.gui.GuiGraphics;
5 | import net.minecraft.client.gui.components.MultiLineTextWidget;
6 | import net.minecraft.client.gui.components.Tooltip;
7 | import net.minecraft.resources.ResourceLocation;
8 | import net.pl3x.guithium.api.gui.element.Checkbox;
9 | import net.pl3x.guithium.api.gui.element.Element;
10 | import net.pl3x.guithium.api.network.packet.ElementChangedValuePacket;
11 | import net.pl3x.guithium.fabric.gui.screen.AbstractScreen;
12 | import net.pl3x.guithium.fabric.util.ComponentHelper;
13 | import org.apache.commons.lang3.BooleanUtils;
14 | import org.jetbrains.annotations.NotNull;
15 |
16 | public class RenderableCheckbox extends net.minecraft.client.gui.components.Checkbox implements TextureSwappableWidget, RenderableWidget {
17 | private final RenderableDuck self;
18 |
19 | private Checkbox checkbox;
20 |
21 | public RenderableCheckbox(@NotNull Minecraft client, @NotNull AbstractScreen screen, @NotNull Checkbox checkbox) {
22 | super(
23 | 0, 0, (int) checkbox.getSize().getX(),
24 | ComponentHelper.toVanilla(checkbox.getLabel()),
25 | client.font, false, null
26 | );
27 | this.self = ((RenderableDuck) this).duck(client, screen);
28 | this.checkbox = checkbox;
29 | }
30 |
31 | @NotNull
32 | public Checkbox getElement() {
33 | return this.checkbox;
34 | }
35 |
36 | @Override
37 | public void updateElement(@NotNull Element element) {
38 | this.checkbox = (Checkbox) element;
39 | this.self.getScreen().refresh();
40 | }
41 |
42 | @Override
43 | @NotNull
44 | public MultiLineTextWidget getTextWidget() {
45 | return this.textWidget;
46 | }
47 |
48 | @Override
49 | @NotNull
50 | public ResourceLocation getTexture() {
51 | if (selected()) {
52 | return isHoveredOrFocused() ? CHECKBOX_SELECTED_HIGHLIGHTED_SPRITE : CHECKBOX_SELECTED_SPRITE;
53 | } else {
54 | return isHoveredOrFocused() ? CHECKBOX_HIGHLIGHTED_SPRITE : CHECKBOX_SPRITE;
55 | }
56 | }
57 |
58 | @Override
59 | public float getAlpha() {
60 | return this.alpha;
61 | }
62 |
63 | @Override
64 | public void init() {
65 | // update contents
66 | setMessage(ComponentHelper.toVanilla(getElement().getLabel()));
67 | setTooltip(Tooltip.create(ComponentHelper.toVanilla(getElement().getTooltip())));
68 | this.selected = BooleanUtils.isTrue(getElement().getValue());
69 |
70 | // update pos/size
71 | setX((int) getElement().getPos().getX());
72 | setY((int) getElement().getPos().getY());
73 | setWidth(getAdjustedWidth((int) getElement().getSize().getX(), getMessage(), this.self.getClient().font));
74 | setHeight(getAdjustedHeight(this.self.getClient().font));
75 |
76 | // recalculate position on screen
77 | this.self.calcScreenPos(getWidth(), getHeight());
78 | }
79 |
80 | @Override
81 | public void renderWidget(@NotNull GuiGraphics gfx, int mouseX, int mouseY, float delta) {
82 | TextureSwappableWidget.super.renderWidget(gfx, mouseX, mouseY, delta);
83 | }
84 |
85 | @Override
86 | public void onPress() {
87 | // toggle it
88 | this.selected = !selected();
89 |
90 | // make sure the value is actually changed
91 | if (getElement().getValue() == selected()) {
92 | return;
93 | }
94 |
95 | // toggle this checkbox
96 | getElement().setValue(selected());
97 |
98 | // tell the server
99 | conn().send(new ElementChangedValuePacket<>(
100 | this.self.getScreen().getScreen(),
101 | getElement(),
102 | selected()
103 | ));
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/element/RenderableCircle.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui.element;
2 |
3 | import com.mojang.blaze3d.vertex.VertexConsumer;
4 | import net.minecraft.client.Minecraft;
5 | import net.minecraft.client.gui.GuiGraphics;
6 | import net.minecraft.client.gui.components.AbstractWidget;
7 | import net.minecraft.client.gui.narration.NarrationElementOutput;
8 | import net.minecraft.client.renderer.RenderType;
9 | import net.minecraft.network.chat.Component;
10 | import net.pl3x.guithium.api.gui.element.Circle;
11 | import net.pl3x.guithium.api.gui.element.Element;
12 | import net.pl3x.guithium.fabric.gui.screen.AbstractScreen;
13 | import net.pl3x.guithium.fabric.gui.screen.RenderableScreen;
14 | import net.pl3x.guithium.fabric.util.Numbers;
15 | import org.jetbrains.annotations.NotNull;
16 | import org.joml.Matrix4f;
17 |
18 | public class RenderableCircle extends AbstractWidget implements RenderableWidget {
19 | private final RenderableDuck self;
20 |
21 | private Circle circle;
22 |
23 | private int radius;
24 | private int resolution;
25 | private int innerColor;
26 | private int outerColor;
27 |
28 | public RenderableCircle(@NotNull Minecraft client, @NotNull AbstractScreen screen, @NotNull Circle circle) {
29 | super(0, 0, 0, 0, Component.empty());
30 | this.self = ((RenderableDuck) this).duck(client, screen);
31 | this.circle = circle;
32 | this.active = false;
33 | }
34 |
35 | @Override
36 | @NotNull
37 | public Circle getElement() {
38 | return this.circle;
39 | }
40 |
41 | @Override
42 | public void updateElement(@NotNull Element element) {
43 | this.circle = (Circle) element;
44 | this.self.getScreen().refresh();
45 | }
46 |
47 | @Override
48 | public void init() {
49 | // update pos/size
50 | setX((int) getElement().getPos().getX());
51 | setY((int) getElement().getPos().getY());
52 |
53 | if (getElement().getRadius() != null) {
54 | this.radius = getElement().getRadius();
55 | } else {
56 | this.radius = Math.min(
57 | RenderableScreen.windowWidth() / 2,
58 | RenderableScreen.windowHeight() / 2
59 | );
60 | }
61 |
62 | setWidth(this.radius * 2);
63 | setHeight(this.radius * 2);
64 |
65 | // recalculate position on screen
66 | this.self.calcScreenPos(getWidth(), getHeight());
67 |
68 | this.innerColor = getElement().getInnerColor();
69 | this.outerColor = getElement().getOuterColor();
70 |
71 | this.resolution = Numbers.unbox(getElement().getResolution(), this.radius);
72 | }
73 |
74 | @Override
75 | protected void renderWidget(@NotNull GuiGraphics gfx, int mouseX, int mouseY, float delta) {
76 | this.self.rotate(gfx, this.self.getCenterX(), this.self.getCenterY(), getElement().getRotation());
77 | this.self.scale(gfx, this.self.getCenterX(), this.self.getCenterY(), getElement().getScale());
78 |
79 | Matrix4f matrix4f = gfx.pose().last().pose();
80 | VertexConsumer buf = gfx.bufferSource.getBuffer(RenderType.debugTriangleFan());
81 | buf.addVertex(matrix4f, getX(), getY(), 0).setColor(this.innerColor);
82 | for (int i = 0; i <= this.resolution; i++) {
83 | float angle = (float) (2 * Math.PI * i / this.resolution);
84 | float x = getX() + (float) Math.sin(angle) * this.radius;
85 | float y = getY() + (float) Math.cos(angle) * this.radius;
86 | buf.addVertex(matrix4f, x, y, 0).setColor(this.outerColor);
87 | }
88 | }
89 |
90 | @Override
91 | protected void updateWidgetNarration(@NotNull NarrationElementOutput narrationElementOutput) {
92 | // nothing to narrate
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/element/RenderableDuck.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui.element;
2 |
3 | import net.minecraft.client.Minecraft;
4 | import net.minecraft.client.gui.GuiGraphics;
5 | import net.pl3x.guithium.fabric.gui.screen.AbstractScreen;
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 | import org.joml.Quaternionf;
9 |
10 | // Vanilla's abstract widget mixin implements these
11 | public interface RenderableDuck extends RenderableWidget {
12 | @NotNull
13 | Minecraft getClient();
14 |
15 | @NotNull
16 | AbstractScreen getScreen();
17 |
18 | @NotNull
19 | RenderableDuck duck(@NotNull Minecraft client, @NotNull AbstractScreen screen);
20 |
21 | int getCenterX();
22 |
23 | void setCenterX(int x);
24 |
25 | int getCenterY();
26 |
27 | void setCenterY(int y);
28 |
29 | void calcScreenPos(int width, int height);
30 |
31 | default void rotate(@NotNull GuiGraphics gfx, int x, int y, int width, int height, @Nullable Float degrees) {
32 | if (degrees == null) {
33 | return;
34 | }
35 | rotate(gfx, (int) (x + width / 2F), (int) (y + height / 2F), degrees);
36 | }
37 |
38 | default void rotate(@NotNull GuiGraphics gfx, int x, int y, @Nullable Float degrees) {
39 | if (degrees == null) {
40 | return;
41 | }
42 | gfx.pose().translate(x, y, 0);
43 | gfx.pose().mulPose((new Quaternionf()).rotateZ(degrees * 0.017453292F));
44 | gfx.pose().translate(-x, -y, 0);
45 | }
46 |
47 | default void scale(@NotNull GuiGraphics gfx, int x, int y, int width, int height, @Nullable Float scale) {
48 | if (scale == null) {
49 | return;
50 | }
51 | scale(gfx, (int) (x + width / 2F), (int) (y + height / 2F), scale);
52 | }
53 |
54 | default void scale(@NotNull GuiGraphics gfx, int x, int y, @Nullable Float scale) {
55 | if (scale == null) {
56 | return;
57 | }
58 | gfx.pose().translate(x, y, 0);
59 | gfx.pose().scale(scale, scale, 0);
60 | gfx.pose().translate(-x, -y, 0);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/element/RenderableGradient.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui.element;
2 |
3 | import com.mojang.blaze3d.vertex.VertexConsumer;
4 | import net.minecraft.client.Minecraft;
5 | import net.minecraft.client.gui.GuiGraphics;
6 | import net.minecraft.client.gui.components.AbstractWidget;
7 | import net.minecraft.client.gui.narration.NarrationElementOutput;
8 | import net.minecraft.client.renderer.RenderType;
9 | import net.minecraft.network.chat.Component;
10 | import net.pl3x.guithium.api.gui.element.Element;
11 | import net.pl3x.guithium.api.gui.element.Gradient;
12 | import net.pl3x.guithium.fabric.gui.screen.AbstractScreen;
13 | import org.jetbrains.annotations.NotNull;
14 | import org.joml.Matrix4f;
15 |
16 | public class RenderableGradient extends AbstractWidget implements RenderableWidget {
17 | private final RenderableDuck self;
18 |
19 | private Gradient gradient;
20 |
21 | private int x0, y0, x1, y1;
22 | private int[] color;
23 |
24 | public RenderableGradient(@NotNull Minecraft client, @NotNull AbstractScreen screen, @NotNull Gradient gradient) {
25 | super(0, 0, 0, 0, Component.empty());
26 | this.self = ((RenderableDuck) this).duck(client, screen);
27 | this.gradient = gradient;
28 | this.active = false;
29 | }
30 |
31 | @Override
32 | @NotNull
33 | public Gradient getElement() {
34 | return this.gradient;
35 | }
36 |
37 | @Override
38 | public void updateElement(@NotNull Element element) {
39 | this.gradient = (Gradient) element;
40 | this.self.getScreen().refresh();
41 | }
42 |
43 | @Override
44 | public void init() {
45 | // update pos/size
46 | setX((int) getElement().getPos().getX());
47 | setY((int) getElement().getPos().getY());
48 | setWidth((int) getElement().getSize().getX());
49 | setHeight((int) getElement().getSize().getY());
50 |
51 | // recalculate position on screen
52 | this.self.calcScreenPos(getWidth(), getHeight());
53 |
54 | this.x0 = getX();
55 | this.y0 = getY();
56 | this.x1 = getX() + getWidth();
57 | this.y1 = getY() + getHeight();
58 |
59 | this.color = getElement().getColors();
60 | }
61 |
62 | @Override
63 | protected void renderWidget(@NotNull GuiGraphics gfx, int mouseX, int mouseY, float delta) {
64 | this.self.rotate(gfx, this.self.getCenterX(), this.self.getCenterY(), getElement().getRotation());
65 | this.self.scale(gfx, this.self.getCenterX(), this.self.getCenterY(), getElement().getScale());
66 |
67 | Matrix4f matrix4f = gfx.pose().last().pose();
68 | VertexConsumer buf = gfx.bufferSource.getBuffer(RenderType.gui());
69 | buf.addVertex(matrix4f, this.x0, this.y0, 0).setColor(this.color[0]);
70 | buf.addVertex(matrix4f, this.x0, this.y1, 0).setColor(this.color[1]);
71 | buf.addVertex(matrix4f, this.x1, this.y1, 0).setColor(this.color[2]);
72 | buf.addVertex(matrix4f, this.x1, this.y0, 0).setColor(this.color[3]);
73 | }
74 |
75 | @Override
76 | protected void updateWidgetNarration(@NotNull NarrationElementOutput narrationElementOutput) {
77 | // nothing to narrate
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/element/RenderableImage.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui.element;
2 |
3 | import net.minecraft.client.Minecraft;
4 | import net.minecraft.client.gui.GuiGraphics;
5 | import net.minecraft.client.gui.components.AbstractWidget;
6 | import net.minecraft.client.gui.narration.NarrationElementOutput;
7 | import net.minecraft.network.chat.Component;
8 | import net.pl3x.guithium.api.Guithium;
9 | import net.pl3x.guithium.api.gui.Vec4;
10 | import net.pl3x.guithium.api.gui.element.Element;
11 | import net.pl3x.guithium.api.gui.element.Image;
12 | import net.pl3x.guithium.fabric.GuithiumMod;
13 | import net.pl3x.guithium.fabric.gui.screen.AbstractScreen;
14 | import net.pl3x.guithium.fabric.gui.texture.FabricTexture;
15 | import org.jetbrains.annotations.NotNull;
16 |
17 | public class RenderableImage extends AbstractWidget implements RenderableWidget {
18 | private final RenderableDuck self;
19 | private final FabricTexture texture;
20 |
21 | private Image image;
22 | private float x0, y0, x1, y1;
23 | private float u0, v0, u1, v1;
24 | private int vertexColor;
25 |
26 | public RenderableImage(@NotNull Minecraft client, @NotNull AbstractScreen screen, @NotNull Image image) {
27 | super(0, 0, 0, 0, Component.empty());
28 | this.self = ((RenderableDuck) this).duck(client, screen);
29 | this.image = image;
30 | this.active = false;
31 |
32 | this.texture = ((GuithiumMod) Guithium.api()).getTextureManager().getOrCreate(image);
33 | }
34 |
35 | @Override
36 | @NotNull
37 | public Image getElement() {
38 | return this.image;
39 | }
40 |
41 | @Override
42 | public void updateElement(@NotNull Element element) {
43 | this.image = (Image) element;
44 | this.self.getScreen().refresh();
45 | }
46 |
47 | @Override
48 | public void init() {
49 | // update pos/size
50 | setX((int) getElement().getPos().getX());
51 | setY((int) getElement().getPos().getY());
52 | setWidth((int) getElement().getSize().getX());
53 | setHeight((int) getElement().getSize().getY());
54 |
55 | // recalculate position on screen
56 | this.self.calcScreenPos(getWidth(), getHeight());
57 |
58 | this.x0 = getX();
59 | this.y0 = getY();
60 | this.x1 = getX() + getWidth();
61 | this.y1 = getY() + getHeight();
62 |
63 | Vec4 uv = getElement().getUV();
64 | Float tileMod = getElement().getTileModifier();
65 | if (uv != null) {
66 | this.u0 = uv.getX();
67 | this.v0 = uv.getY();
68 | this.u1 = uv.getZ();
69 | this.v1 = uv.getW();
70 | if (tileMod != null) {
71 | this.u1 /= tileMod;
72 | this.v1 /= tileMod;
73 | }
74 | } else {
75 | this.u0 = 0;
76 | this.v0 = 0;
77 | if (tileMod == null) {
78 | this.u1 = 1;
79 | this.v1 = 1;
80 | } else {
81 | this.u1 = this.x1 / tileMod;
82 | this.v1 = this.y1 / tileMod;
83 | }
84 | }
85 |
86 | this.vertexColor = getElement().getVertexColor() == null ? 0xFFFFFFFF : getElement().getVertexColor();
87 | }
88 |
89 | @Override
90 | protected void renderWidget(@NotNull GuiGraphics gfx, int mouseX, int mouseY, float delta) {
91 | if (!this.texture.isLoaded()) {
92 | return;
93 | }
94 |
95 | this.self.rotate(gfx, this.self.getCenterX(), this.self.getCenterY(), getElement().getRotation());
96 | this.self.scale(gfx, this.self.getCenterX(), this.self.getCenterY(), getElement().getScale());
97 |
98 | this.texture.render(gfx, this.x0, this.y0, this.x1, this.y1, this.u0, this.v0, this.u1, this.v1, this.vertexColor);
99 | }
100 |
101 | @Override
102 | protected void updateWidgetNarration(@NotNull NarrationElementOutput narrationElementOutput) {
103 | // nothing to narrate
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/element/RenderableLine.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui.element;
2 |
3 | import com.mojang.blaze3d.vertex.PoseStack;
4 | import com.mojang.blaze3d.vertex.VertexConsumer;
5 | import net.minecraft.client.Minecraft;
6 | import net.minecraft.client.gui.GuiGraphics;
7 | import net.minecraft.client.gui.components.AbstractWidget;
8 | import net.minecraft.client.gui.narration.NarrationElementOutput;
9 | import net.minecraft.client.renderer.RenderType;
10 | import net.minecraft.network.chat.Component;
11 | import net.pl3x.guithium.api.gui.element.Element;
12 | import net.pl3x.guithium.api.gui.element.Line;
13 | import net.pl3x.guithium.fabric.gui.screen.AbstractScreen;
14 | import org.jetbrains.annotations.NotNull;
15 | import org.joml.Matrix4f;
16 |
17 | public class RenderableLine extends AbstractWidget implements RenderableWidget {
18 | private final RenderableDuck self;
19 |
20 | private Line line;
21 |
22 | private int startColor;
23 | private int endColor;
24 | private int endPosX = 0;
25 | private int endPosY = 0;
26 |
27 | public RenderableLine(@NotNull Minecraft client, @NotNull AbstractScreen screen, @NotNull Line line) {
28 | super(0, 0, 0, 0, Component.empty());
29 | this.self = ((RenderableDuck) this).duck(client, screen);
30 | this.line = line;
31 | this.active = false;
32 | }
33 |
34 | @Override
35 | @NotNull
36 | public Line getElement() {
37 | return this.line;
38 | }
39 |
40 | @Override
41 | public void updateElement(@NotNull Element element) {
42 | this.line = (Line) element;
43 | this.self.getScreen().refresh();
44 | }
45 |
46 | @Override
47 | public void init() {
48 | // update size
49 | setWidth((int) (getElement().getWidth() * this.self.getClient().getWindow().getGuiScale()));
50 | setHeight(0);
51 |
52 | // colors
53 | this.startColor = getElement().getStartColor();
54 | this.endColor = getElement().getEndColor();
55 |
56 | // start point
57 | setX((int) (this.self.getScreen().width * getElement().getAnchor().getX() + getElement().getPos().getX()));
58 | setY((int) (this.self.getScreen().height * getElement().getAnchor().getY() + getElement().getPos().getY()));
59 |
60 | // end point
61 | this.endPosX = (int) (this.self.getScreen().width * getElement().getEndAnchor().getX() + getElement().getEndPos().getX());
62 | this.endPosY = (int) (this.self.getScreen().height * getElement().getEndAnchor().getY() + getElement().getEndPos().getY());
63 |
64 | // center point
65 | this.self.setCenterX(getX() + (this.endPosX - getX()) / 2);
66 | this.self.setCenterY(getY() + (this.endPosY - getY()) / 2);
67 | }
68 |
69 | @Override
70 | protected void renderWidget(@NotNull GuiGraphics gfx, int mouseX, int mouseY, float delta) {
71 | this.self.rotate(gfx, this.self.getCenterX(), this.self.getCenterY(), getElement().getRotation());
72 | this.self.scale(gfx, this.self.getCenterX(), this.self.getCenterY(), getElement().getScale());
73 |
74 | PoseStack.Pose pose = gfx.pose().last();
75 | Matrix4f model = pose.pose();
76 |
77 | VertexConsumer buf = gfx.bufferSource.getBuffer(RenderType.debugLine(getWidth()));
78 | buf.addVertex(model, getX(), getY(), 0).setColor(this.startColor).setNormal(pose, 1, 0, 0);
79 | buf.addVertex(model, this.endPosX, this.endPosY, 0).setColor(this.endColor).setNormal(pose, 1, 0, 0);
80 | }
81 |
82 | @Override
83 | protected void updateWidgetNarration(@NotNull NarrationElementOutput narrationElementOutput) {
84 | // nothing to narrate
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/element/RenderableText.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui.element;
2 |
3 | import net.minecraft.client.Minecraft;
4 | import net.minecraft.client.gui.GuiGraphics;
5 | import net.minecraft.client.gui.components.AbstractWidget;
6 | import net.minecraft.client.gui.narration.NarrationElementOutput;
7 | import net.minecraft.network.chat.Component;
8 | import net.pl3x.guithium.api.gui.element.Element;
9 | import net.pl3x.guithium.api.gui.element.Text;
10 | import net.pl3x.guithium.fabric.gui.screen.AbstractScreen;
11 | import net.pl3x.guithium.fabric.util.ComponentHelper;
12 | import org.apache.commons.lang3.BooleanUtils;
13 | import org.jetbrains.annotations.NotNull;
14 |
15 | public class RenderableText extends AbstractWidget implements RenderableWidget {
16 | private final RenderableDuck self;
17 |
18 | private Text text;
19 |
20 | public RenderableText(@NotNull Minecraft client, @NotNull AbstractScreen screen, @NotNull Text text) {
21 | super(0, 0, 0, 0, Component.empty());
22 | this.self = ((RenderableDuck) this).duck(client, screen);
23 | this.text = text;
24 | this.active = false;
25 | }
26 |
27 | @Override
28 | @NotNull
29 | public Text getElement() {
30 | return this.text;
31 | }
32 |
33 | @Override
34 | public void updateElement(@NotNull Element element) {
35 | this.text = (Text) element;
36 | this.self.getScreen().refresh();
37 | }
38 |
39 | @Override
40 | public void init() {
41 | if (getElement().getText() == null) {
42 | return;
43 | }
44 |
45 | // update contents
46 | setMessage(ComponentHelper.toVanilla(getElement().getText()));
47 |
48 | // update pos/size
49 | setX((int) getElement().getPos().getX());
50 | setY((int) getElement().getPos().getY());
51 | setWidth(this.self.getClient().font.width(getMessage()));
52 | setHeight(this.self.getClient().font.lineHeight);
53 |
54 | // recalculate position on screen
55 | this.self.calcScreenPos(getWidth(), getHeight());
56 | }
57 |
58 | @Override
59 | protected void renderWidget(@NotNull GuiGraphics gfx, int mouseX, int mouseY, float delta) {
60 | if (getElement().getText() == null) {
61 | return;
62 | }
63 |
64 | this.self.rotate(gfx, this.self.getCenterX(), this.self.getCenterY(), getElement().getRotation());
65 | this.self.scale(gfx, this.self.getCenterX(), this.self.getCenterY(), getElement().getScale());
66 |
67 | gfx.drawString(
68 | this.self.getClient().font,
69 | getMessage(),
70 | getX(),
71 | getY(),
72 | 0xFFFFFF,
73 | BooleanUtils.isTrue(getElement().hasShadow())
74 | );
75 | }
76 |
77 | @Override
78 | protected void updateWidgetNarration(@NotNull NarrationElementOutput narrationElementOutput) {
79 | // nothing to narrate
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/element/RenderableTextbox.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui.element;
2 |
3 | import net.minecraft.client.Minecraft;
4 | import net.minecraft.client.gui.GuiGraphics;
5 | import net.minecraft.client.gui.components.EditBox;
6 | import net.minecraft.client.gui.narration.NarrationElementOutput;
7 | import net.minecraft.network.chat.Component;
8 | import net.pl3x.guithium.api.gui.element.Element;
9 | import net.pl3x.guithium.api.gui.element.Textbox;
10 | import net.pl3x.guithium.api.network.packet.ElementChangedValuePacket;
11 | import net.pl3x.guithium.fabric.gui.screen.AbstractScreen;
12 | import net.pl3x.guithium.fabric.util.ComponentHelper;
13 | import net.pl3x.guithium.fabric.util.Numbers;
14 | import org.apache.commons.lang3.BooleanUtils;
15 | import org.jetbrains.annotations.NotNull;
16 |
17 | public class RenderableTextbox extends EditBox implements RenderableWidget {
18 | private final RenderableDuck self;
19 |
20 | private Textbox textbox;
21 |
22 | public RenderableTextbox(@NotNull Minecraft client, @NotNull AbstractScreen screen, @NotNull Textbox textbox) {
23 | super(client.font, 0, 0, Component.empty());
24 | this.self = ((RenderableDuck) this).duck(client, screen);
25 | this.textbox = textbox;
26 | }
27 |
28 | @Override
29 | @NotNull
30 | public Textbox getElement() {
31 | return this.textbox;
32 | }
33 |
34 | @Override
35 | public void updateElement(@NotNull Element element) {
36 | this.textbox = (Textbox) element;
37 | this.self.getScreen().refresh();
38 | }
39 |
40 | @Override
41 | public void init() {
42 | setHint(ComponentHelper.toVanilla(getElement().getSuggestion()));
43 | setValue(getElement().getValue());
44 | setBordered(!BooleanUtils.isFalse(getElement().isBordered()));
45 | setCanLoseFocus(!BooleanUtils.isFalse(getElement().canLoseFocus()));
46 | setEditable(!BooleanUtils.isFalse(getElement().isEditable()));
47 | setMaxLength(Numbers.unbox(getElement().getMaxLength(), 32));
48 | setTextColor(Numbers.unbox(getElement().getTextColor(), 0xFFFFFF));
49 | setTextColorUneditable(Numbers.unbox(getElement().getUneditableTextColor(), 0x707070));
50 |
51 | // update pos/size
52 | setX((int) getElement().getPos().getX());
53 | setY((int) getElement().getPos().getY());
54 | setWidth((int) getElement().getSize().getX());
55 | setHeight((int) getElement().getSize().getY());
56 |
57 | // recalculate position on screen
58 | this.self.calcScreenPos(getWidth(), getHeight());
59 |
60 | setResponder(untrimmedRawNewValue -> {
61 | // get the real value, since it might have been trimmed
62 | getElement().setValue(getValue());
63 | if (getElement().onChange() != null) {
64 | conn().send(new ElementChangedValuePacket<>(
65 | this.self.getScreen().getScreen(),
66 | getElement(),
67 | getValue()
68 | ));
69 | }
70 | });
71 | }
72 |
73 | @Override
74 | public void renderWidget(@NotNull GuiGraphics gfx, int mouseX, int mouseY, float delta) {
75 | this.self.rotate(gfx, this.self.getCenterX(), this.self.getCenterY(), getElement().getRotation());
76 | this.self.scale(gfx, this.self.getCenterX(), this.self.getCenterY(), getElement().getScale());
77 |
78 | super.renderWidget(gfx, mouseX, mouseY, delta);
79 | }
80 |
81 | @Override
82 | public void updateWidgetNarration(@NotNull NarrationElementOutput narrationElementOutput) {
83 | // nothing to narrate
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/element/RenderableWidget.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui.element;
2 |
3 | import net.minecraft.client.Minecraft;
4 | import net.minecraft.client.gui.components.AbstractWidget;
5 | import net.pl3x.guithium.api.Guithium;
6 | import net.pl3x.guithium.api.gui.element.Button;
7 | import net.pl3x.guithium.api.gui.element.Checkbox;
8 | import net.pl3x.guithium.api.gui.element.Circle;
9 | import net.pl3x.guithium.api.gui.element.Element;
10 | import net.pl3x.guithium.api.gui.element.Gradient;
11 | import net.pl3x.guithium.api.gui.element.Image;
12 | import net.pl3x.guithium.api.gui.element.Line;
13 | import net.pl3x.guithium.api.gui.element.Radio;
14 | import net.pl3x.guithium.api.gui.element.Slider;
15 | import net.pl3x.guithium.api.gui.element.Text;
16 | import net.pl3x.guithium.api.gui.element.Textbox;
17 | import net.pl3x.guithium.api.network.Connection;
18 | import net.pl3x.guithium.fabric.GuithiumMod;
19 | import net.pl3x.guithium.fabric.gui.screen.AbstractScreen;
20 | import org.jetbrains.annotations.NotNull;
21 |
22 | // Guithium's renderable widgets implements these
23 | public interface RenderableWidget {
24 | @NotNull
25 | Element getElement();
26 |
27 | void updateElement(@NotNull Element element);
28 |
29 | void init();
30 |
31 | @NotNull
32 | default Connection conn() {
33 | return ((GuithiumMod) Guithium.api()).getNetworkHandler().getConnection();
34 | }
35 |
36 | @NotNull
37 | static AbstractWidget create(@NotNull Minecraft client, @NotNull AbstractScreen screen, @NotNull Element element) {
38 | String type = element.getClass().getSimpleName();
39 | return switch (type) {
40 | case "Button" -> new RenderableButton(client, screen, (Button) element);
41 | case "Checkbox" -> new RenderableCheckbox(client, screen, (Checkbox) element);
42 | case "Circle" -> new RenderableCircle(client, screen, (Circle) element);
43 | case "Gradient" -> new RenderableGradient(client, screen, (Gradient) element);
44 | case "Image" -> new RenderableImage(client, screen, (Image) element);
45 | case "Line" -> new RenderableLine(client, screen, (Line) element);
46 | case "Radio" -> new RenderableRadio(client, screen, (Radio) element);
47 | case "Slider" -> new RenderableSlider(client, screen, (Slider) element);
48 | case "Text" -> new RenderableText(client, screen, (Text) element);
49 | case "Textbox" -> new RenderableTextbox(client, screen, (Textbox) element);
50 | default -> throw new IllegalStateException("Unexpected value: " + type);
51 | };
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/element/TextureSwappableWidget.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui.element;
2 |
3 | import net.minecraft.client.Minecraft;
4 | import net.minecraft.client.gui.GuiGraphics;
5 | import net.minecraft.client.gui.components.Checkbox;
6 | import net.minecraft.client.gui.components.MultiLineTextWidget;
7 | import net.minecraft.client.renderer.RenderType;
8 | import net.minecraft.resources.ResourceLocation;
9 | import net.minecraft.util.ARGB;
10 | import net.pl3x.guithium.api.gui.element.Element;
11 | import org.jetbrains.annotations.NotNull;
12 |
13 | public interface TextureSwappableWidget {
14 | int getX();
15 |
16 | int getY();
17 |
18 | float getAlpha();
19 |
20 | @NotNull
21 | Element getElement();
22 |
23 | @NotNull
24 | MultiLineTextWidget getTextWidget();
25 |
26 | @NotNull
27 | ResourceLocation getTexture();
28 |
29 | default void renderWidget(@NotNull GuiGraphics gfx, int mouseX, int mouseY, float delta) {
30 | int size = Checkbox.getBoxSize(Minecraft.getInstance().font);
31 | gfx.blitSprite(RenderType::guiTextured, getTexture(), getX(), getY(), size, size, ARGB.white(getAlpha()));
32 | int textX = this.getX() + size + 4;
33 | int textY = this.getY() + size / 2 - getTextWidget().getHeight() / 2;
34 | getTextWidget().setPosition(textX, textY);
35 | getTextWidget().renderWidget(gfx, mouseX, mouseY, delta);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/screen/RenderableScreen.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui.screen;
2 |
3 | import net.minecraft.client.Minecraft;
4 | import net.pl3x.guithium.api.gui.Screen;
5 | import net.pl3x.guithium.api.network.packet.CloseScreenPacket;
6 | import net.pl3x.guithium.fabric.GuithiumMod;
7 | import org.jetbrains.annotations.NotNull;
8 |
9 | public class RenderableScreen extends AbstractScreen {
10 | public RenderableScreen(@NotNull GuithiumMod mod, @NotNull Screen screen) {
11 | super(mod, screen);
12 | }
13 |
14 | @Override
15 | public void onClose() {
16 | CloseScreenPacket packet = new CloseScreenPacket(this.screen.getKey());
17 | this.mod.getNetworkHandler().getConnection().send(packet);
18 | super.onClose();
19 | }
20 |
21 | public static int windowWidth() {
22 | return Minecraft.getInstance().getWindow().getGuiScaledWidth();
23 | }
24 |
25 | public static int windowHeight() {
26 | return Minecraft.getInstance().getWindow().getGuiScaledHeight();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/test/RectWidget.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui.test;
2 |
3 | import com.mojang.blaze3d.vertex.VertexConsumer;
4 | import net.minecraft.client.Minecraft;
5 | import net.minecraft.client.gui.GuiGraphics;
6 | import net.minecraft.client.gui.components.AbstractWidget;
7 | import net.minecraft.client.gui.narration.NarrationElementOutput;
8 | import net.minecraft.client.renderer.RenderType;
9 | import net.minecraft.network.chat.Component;
10 | import org.jetbrains.annotations.NotNull;
11 | import org.joml.Matrix4f;
12 |
13 | public class RectWidget extends AbstractWidget {
14 | private final int[] color = new int[4];
15 |
16 | public RectWidget(int width, int height, int[] color) {
17 | this(0, 0, width, height, color);
18 | }
19 |
20 | public RectWidget(int x, int y, int width, int height, int[] color) {
21 | super(x, y, width, height, Component.empty());
22 | this.color[0] = color.length > 0 ? color[0] : 0xff000000;
23 | this.color[1] = color.length > 1 ? color[1] : 0xff000000;
24 | this.color[2] = color.length > 2 ? color[2] : 0xff000000;
25 | this.color[3] = color.length > 3 ? color[3] : 0xff000000;
26 | }
27 |
28 | @Override
29 | protected void renderWidget(@NotNull GuiGraphics gfx, int mouseX, int mouseY, float delta) {
30 | VertexConsumer buf = Minecraft.getInstance().renderBuffers().bufferSource().getBuffer(RenderType.gui());
31 | Matrix4f m4f = gfx.pose().last().pose();
32 | buf.addVertex(m4f, this.getX(), this.getY(), 0).setColor(this.color[0]);
33 | buf.addVertex(m4f, this.getX(), this.getBottom(), 0).setColor(this.color[1]);
34 | buf.addVertex(m4f, this.getRight(), this.getBottom(), 0).setColor(this.color[2]);
35 | buf.addVertex(m4f, this.getRight(), this.getY(), 0).setColor(this.color[3]);
36 | }
37 |
38 | @Override
39 | protected void updateWidgetNarration(@NotNull NarrationElementOutput narrationElementOutput) {
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/test/TestScreen.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui.test;
2 |
3 | import net.minecraft.client.gui.components.Button;
4 | import net.minecraft.client.gui.components.StringWidget;
5 | import net.minecraft.client.gui.layouts.GridLayout;
6 | import net.minecraft.client.gui.screens.Screen;
7 | import net.minecraft.network.chat.CommonComponents;
8 | import net.minecraft.network.chat.Component;
9 |
10 | public class TestScreen extends Screen {
11 | public TestScreen() {
12 | super(Component.translatable("guithium.test.screen"));
13 | }
14 |
15 | protected void init() {
16 | super.init();
17 |
18 | GridLayout layout = new GridLayout();
19 | layout.defaultCellSetting().padding(4, 4, 4, 0);
20 |
21 | GridLayout.RowHelper row = layout.createRowHelper(1);
22 |
23 | row.addChild(new StringWidget(this.title, this.font));
24 |
25 | row.addChild(new StringWidget(Component.literal("test string 1"), this.font));
26 | row.addChild(new StringWidget(Component.literal("test string 2"), this.font));
27 | row.addChild(new StringWidget(Component.literal("test string 3"), this.font));
28 |
29 | row.addChild(new RectWidget(100, 25, new int[]{0xffff0000, 0xff00ff00, 0xff0000ff, 0xffffff00}));
30 |
31 | row.addChild(Button.builder(CommonComponents.GUI_DONE, (btn) -> onClose()).width(200).build());
32 |
33 | layout.visitWidgets(this::addRenderableWidget);
34 | layout.arrangeElements();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/test/TextWidget.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui.test;
2 |
3 | import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
4 |
5 | public class TextWidget {
6 | GsonComponentSerializer serializer = GsonComponentSerializer.gson();
7 | }
8 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/gui/texture/FabricTextureManager.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.gui.texture;
2 |
3 | import java.util.Collection;
4 | import java.util.Collections;
5 | import java.util.HashMap;
6 | import java.util.HashSet;
7 | import java.util.Map;
8 | import net.pl3x.guithium.api.Unsafe;
9 | import net.pl3x.guithium.api.gui.element.Image;
10 | import net.pl3x.guithium.api.gui.texture.Texture;
11 | import net.pl3x.guithium.api.gui.texture.TextureManager;
12 | import net.pl3x.guithium.api.key.Key;
13 | import org.jetbrains.annotations.NotNull;
14 | import org.jetbrains.annotations.Nullable;
15 |
16 | public class FabricTextureManager extends TextureManager {
17 | protected final Map textures = new HashMap<>();
18 |
19 | @NotNull
20 | public FabricTexture getOrCreate(@NotNull Image image) {
21 | Texture texture = image.getTexture();
22 | FabricTexture fabricTexture = get(texture.getKey());
23 | if (fabricTexture == null) {
24 | return new FabricTexture(texture.getKey(), texture.getUrl());
25 | }
26 | return fabricTexture;
27 | }
28 |
29 | @Override
30 | public void add(@NotNull Collection textures) {
31 | textures.forEach(this::add);
32 | }
33 |
34 | @Override
35 | public void add(@NotNull Texture texture) {
36 | add(new FabricTexture(texture));
37 | }
38 |
39 | public void add(@NotNull FabricTexture texture) {
40 | this.textures.put(texture.getKey(), texture);
41 | }
42 |
43 | @Override
44 | @Nullable
45 | public FabricTexture get(@NotNull String key) {
46 | return get(Key.of(key));
47 | }
48 |
49 | @Override
50 | @Nullable
51 | public FabricTexture get(@NotNull Key key) {
52 | return this.textures.get(key);
53 | }
54 |
55 | @Override
56 | @Nullable
57 | public FabricTexture remove(@NotNull String key) {
58 | return remove(Key.of(key));
59 | }
60 |
61 | @Override
62 | @Nullable
63 | public FabricTexture remove(@NotNull Key key) {
64 | FabricTexture texture = Unsafe.cast(super.remove(key));
65 | if (texture != null) {
66 | texture.unload();
67 | }
68 | return texture;
69 | }
70 |
71 | @Override
72 | @NotNull
73 | public Collection getTextures() {
74 | return Collections.unmodifiableCollection(this.textures.values());
75 | }
76 |
77 | public void clear() {
78 | new HashSet<>(this.textures.keySet()).forEach(super::remove);
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/mixin/AbstractWidgetMixin.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.mixin;
2 |
3 | import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
4 | import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
5 | import net.minecraft.client.Minecraft;
6 | import net.minecraft.client.gui.GuiGraphics;
7 | import net.minecraft.client.gui.components.AbstractWidget;
8 | import net.pl3x.guithium.api.gui.Vec2;
9 | import net.pl3x.guithium.fabric.gui.element.RenderableDuck;
10 | import net.pl3x.guithium.fabric.gui.screen.AbstractScreen;
11 | import org.jetbrains.annotations.NotNull;
12 | import org.spongepowered.asm.mixin.Mixin;
13 | import org.spongepowered.asm.mixin.Shadow;
14 | import org.spongepowered.asm.mixin.Unique;
15 |
16 | @Mixin(AbstractWidget.class)
17 | public abstract class AbstractWidgetMixin implements RenderableDuck {
18 | @Unique
19 | private Minecraft client;
20 | @Unique
21 | private AbstractScreen screen;
22 |
23 | @Unique
24 | private int centerX;
25 | @Unique
26 | private int centerY;
27 |
28 | @Shadow
29 | private int x;
30 | @Shadow
31 | private int y;
32 | @Shadow
33 | protected int width;
34 | @Shadow
35 | protected int height;
36 |
37 | @Override
38 | @Unique
39 | @NotNull
40 | public Minecraft getClient() {
41 | return this.client;
42 | }
43 |
44 | @Override
45 | @Unique
46 | @NotNull
47 | public AbstractScreen getScreen() {
48 | return this.screen;
49 | }
50 |
51 | @Override
52 | @Unique
53 | @NotNull
54 | public RenderableDuck duck(@NotNull Minecraft client, @NotNull AbstractScreen screen) {
55 | this.client = client;
56 | this.screen = screen;
57 | return this;
58 | }
59 |
60 | @Override
61 | @Unique
62 | public int getCenterX() {
63 | return this.centerX;
64 | }
65 |
66 | @Override
67 | @Unique
68 | public void setCenterX(int x) {
69 | this.centerX = x;
70 | }
71 |
72 | @Override
73 | @Unique
74 | public int getCenterY() {
75 | return this.centerY;
76 | }
77 |
78 | @Override
79 | @Unique
80 | public void setCenterY(int y) {
81 | this.centerY = y;
82 | }
83 |
84 | @Override
85 | @Unique
86 | public void calcScreenPos(int sizeX, int sizeY) {
87 | float anchorX, anchorY;
88 | Vec2 anchor = getElement().getAnchor();
89 | if (anchor == Vec2.ZERO) {
90 | anchorX = 0;
91 | anchorY = 0;
92 | } else if (anchor == Vec2.ONE) {
93 | anchorX = this.screen.width;
94 | anchorY = this.screen.height;
95 | } else {
96 | anchorX = this.screen.width * anchor.getX();
97 | anchorY = this.screen.height * anchor.getY();
98 | }
99 |
100 | float offsetX, offsetY;
101 | Vec2 offset = getElement().getOffset();
102 | if (offset == Vec2.ZERO) {
103 | offsetX = 0;
104 | offsetY = 0;
105 | } else if (offset == Vec2.ONE) {
106 | offsetX = this.width;
107 | offsetY = this.height;
108 | } else {
109 | offsetX = sizeX * offset.getX();
110 | offsetY = sizeY * offset.getY();
111 | }
112 |
113 | Vec2 pos = getElement().getPos();
114 | this.x = (int) (anchorX + pos.getX() - offsetX);
115 | this.y = (int) (anchorY + pos.getY() - offsetY);
116 |
117 | setCenterX(this.x + this.width / 2);
118 | setCenterY(this.y + this.height / 2);
119 | }
120 |
121 | @WrapMethod(method = "render")
122 | public void render(@NotNull GuiGraphics gfx, int mouseX, int mouseY, float delta, @NotNull Operation original) {
123 | gfx.pose().pushPose();
124 | original.call(gfx, mouseX, mouseY, delta);
125 | gfx.pose().popPose();
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/mixin/GuiMixin.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.mixin;
2 |
3 | import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
4 | import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
5 | import net.minecraft.client.DeltaTracker;
6 | import net.minecraft.client.gui.Gui;
7 | import net.minecraft.client.gui.GuiGraphics;
8 | import net.pl3x.guithium.api.Guithium;
9 | import net.pl3x.guithium.fabric.GuithiumMod;
10 | import net.pl3x.guithium.fabric.gui.Gfx;
11 | import net.pl3x.guithium.fabric.gui.HudManager;
12 | import org.jetbrains.annotations.NotNull;
13 | import org.spongepowered.asm.mixin.Mixin;
14 |
15 | @Mixin(Gui.class)
16 | public class GuiMixin {
17 | @WrapMethod(method = "render")
18 | private void preRender(@NotNull GuiGraphics gfx, @NotNull DeltaTracker deltaTracker, @NotNull Operation original) {
19 | HudManager hud = ((GuithiumMod) Guithium.api()).getHudManager();
20 | float delta = deltaTracker.getGameTimeDeltaTicks();
21 |
22 | Gfx.wrap(gfx, () -> hud.preRender(gfx, delta));
23 | original.call(gfx, deltaTracker);
24 | Gfx.wrap(gfx, () -> hud.postRender(gfx, delta));
25 | }
26 |
27 | // list of render methods in mojang's Gui.class
28 | // we might want to ass toggle overrides for
29 |
30 | // renderCameraOverlays
31 | // renderCrosshair
32 | // renderHotbarAndDecorations
33 | // spectatorGui.renderHotbar
34 | // renderItemHotbar
35 | // renderJumpMeter
36 | // renderExperienceBar
37 | // renderPlayerHealth
38 | // renderVehicleHealth
39 | // renderSelectedItemName
40 | // spectatorGui.renderTooltip
41 | // renderExperienceLevel
42 | // renderEffects
43 | // ??? bossOverlay
44 |
45 | // renderScoreboardSidebar
46 | // renderOverlayMessage
47 | // renderTitle
48 | // renderChat
49 | // renderTabList
50 | // ??? subtitleOverlay
51 |
52 | // renderSleepOverlay
53 | }
54 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/mixin/RenderSystemMixin.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.mixin;
2 |
3 | import com.mojang.blaze3d.systems.RenderSystem;
4 | import net.pl3x.guithium.fabric.util.RenderQueue;
5 | import org.jetbrains.annotations.NotNull;
6 | import org.spongepowered.asm.mixin.Mixin;
7 | import org.spongepowered.asm.mixin.injection.At;
8 | import org.spongepowered.asm.mixin.injection.Inject;
9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
10 |
11 | @Mixin(RenderSystem.class)
12 | public abstract class RenderSystemMixin {
13 | @Inject(
14 | method = "flipFrame",
15 | at = @At(
16 | value = "INVOKE",
17 | target = "Lcom/mojang/blaze3d/vertex/Tesselator;clear()V"
18 | )
19 | )
20 | private static void processRenderQueue(@NotNull CallbackInfo ci) {
21 | RenderQueue.process();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/network/FabricConnection.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.network;
2 |
3 | import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
4 | import net.minecraft.client.Minecraft;
5 | import net.pl3x.guithium.api.network.Connection;
6 | import net.pl3x.guithium.api.network.packet.Packet;
7 | import net.pl3x.guithium.fabric.GuithiumMod;
8 | import org.jetbrains.annotations.NotNull;
9 |
10 | public class FabricConnection implements Connection {
11 | private final FabricPacketListener packetListener;
12 |
13 | public FabricConnection(@NotNull GuithiumMod mod) {
14 | this.packetListener = new FabricPacketListener(mod);
15 | }
16 |
17 | @Override
18 | @NotNull
19 | public FabricPacketListener getPacketListener() {
20 | return this.packetListener;
21 | }
22 |
23 | @Override
24 | public void send(@NotNull Packet packet) {
25 | send(packet, false);
26 | }
27 |
28 | @Override
29 | public void send(@NotNull Packet packet, boolean force) {
30 | if (force || Minecraft.getInstance().getConnection() != null) {
31 | ClientPlayNetworking.send(new FabricNetworkHandler.Payload(packet));
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/network/FabricNetworkHandler.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.network;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
5 | import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
6 | import net.minecraft.network.codec.StreamCodec;
7 | import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
8 | import net.minecraft.resources.ResourceLocation;
9 | import net.pl3x.guithium.api.network.NetworkHandler;
10 | import net.pl3x.guithium.api.network.packet.Packet;
11 | import net.pl3x.guithium.fabric.GuithiumMod;
12 | import org.jetbrains.annotations.NotNull;
13 |
14 | public class FabricNetworkHandler extends NetworkHandler {
15 | private final FabricConnection connection;
16 |
17 | public FabricNetworkHandler(@NotNull GuithiumMod mod) {
18 | this.connection = new FabricConnection(mod);
19 | }
20 |
21 | @NotNull
22 | public FabricConnection getConnection() {
23 | return this.connection;
24 | }
25 |
26 | @Override
27 | public void registerListeners() {
28 | PayloadTypeRegistry.playC2S().register(Payload.TYPE, Payload.CODEC);
29 | PayloadTypeRegistry.playS2C().register(Payload.TYPE, Payload.CODEC);
30 |
31 | ClientPlayNetworking.registerGlobalReceiver(Payload.TYPE,
32 | (payload, ctx) -> receive(getConnection(), payload.data())
33 | );
34 | }
35 |
36 | // Wrap our data into this packet that mimics paper's DiscardedPayload packet
37 | // I'm not sure why Fabric's is so different (it's missing the 'data' field)
38 | record Payload(@NotNull ResourceLocation id, byte[] data) implements CustomPacketPayload {
39 | private static final Type TYPE = new Type<>(ResourceLocation.parse(NetworkHandler.CHANNEL));
40 | private static final StreamCodec CODEC = StreamCodec.ofMember(Payload::serialize, Payload::new);
41 |
42 | Payload(@NotNull Packet packet) {
43 | this(TYPE.id(), packet.write().toByteArray());
44 | }
45 |
46 | private Payload(@NotNull ByteBuf buf) {
47 | this(TYPE.id(), new byte[buf.readableBytes()]);
48 | buf.readBytes(this.data);
49 | }
50 |
51 | @NotNull
52 | public Type type() {
53 | return TYPE;
54 | }
55 |
56 | private static void serialize(@NotNull Payload value, @NotNull ByteBuf output) {
57 | output.writeBytes(value.data);
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/scheduler/Scheduler.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.scheduler;
2 |
3 | import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
4 | import net.pl3x.guithium.api.scheduler.AbstractScheduler;
5 |
6 | public class Scheduler extends AbstractScheduler {
7 | @Override
8 | public void register() {
9 | ClientTickEvents.END_CLIENT_TICK.register(client -> tick());
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/util/ComponentHelper.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.util;
2 |
3 | import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
4 | import net.minecraft.core.RegistryAccess;
5 | import net.minecraft.network.chat.Component;
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | public abstract class ComponentHelper {
10 | @NotNull
11 | public static Component toVanilla(@Nullable net.kyori.adventure.text.Component adventure) {
12 | return toVanilla(adventure == null ? null : GsonComponentSerializer.gson().serialize(adventure));
13 | }
14 |
15 | @NotNull
16 | public static Component toVanilla(@Nullable String json) {
17 | Component vanilla = null;
18 | if (json != null) {
19 | try {
20 | vanilla = Component.Serializer.fromJson(json, RegistryAccess.EMPTY);
21 | } catch (Throwable t) {
22 | vanilla = Component.translatable(json);
23 | }
24 | }
25 | return vanilla == null ? Component.empty() : vanilla;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/util/Numbers.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.util;
2 |
3 | import net.minecraft.util.Mth;
4 | import org.jetbrains.annotations.Nullable;
5 |
6 | public abstract class Numbers {
7 | public static double unbox(@Nullable Double val, double def) {
8 | return val == null ? def : val;
9 | }
10 |
11 | public static float unbox(@Nullable Float val, float def) {
12 | return val == null ? def : val;
13 | }
14 |
15 | public static int unbox(@Nullable Integer val, int def) {
16 | return val == null ? def : val;
17 | }
18 |
19 | public static double invLerp(double val, double min, double max) {
20 | return (Mth.clamp(val, min, max) - min) / (max - min);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/fabric/src/main/java/net/pl3x/guithium/fabric/util/RenderQueue.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.fabric.util;
2 |
3 | import com.google.common.collect.Queues;
4 | import java.util.concurrent.ConcurrentLinkedQueue;
5 | import org.jetbrains.annotations.NotNull;
6 |
7 | // recreated from 1.21.4
8 | public abstract class RenderQueue {
9 | private static final ConcurrentLinkedQueue recordingQueue = Queues.newConcurrentLinkedQueue();
10 |
11 | public static void recordRenderCall(@NotNull Runnable runnable) {
12 | recordingQueue.add(runnable);
13 | }
14 |
15 | // called from RenderSystem#flipFrame using mixin
16 | public static void process() {
17 | while (!recordingQueue.isEmpty()) {
18 | recordingQueue.poll().run();
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/fabric/src/main/resources/assets/guithium/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pl3x-net/guithium/4a6f1fdf3d3be182323e444595d518ed3346ce83/fabric/src/main/resources/assets/guithium/icon.png
--------------------------------------------------------------------------------
/fabric/src/main/resources/assets/guithium/lang/en_us.json:
--------------------------------------------------------------------------------
1 | {
2 | "guithium.test.screen" : "Guithium Client Options"
3 | }
4 |
--------------------------------------------------------------------------------
/fabric/src/main/resources/assets/guithium/textures/gui/sprites/widget/radio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pl3x-net/guithium/4a6f1fdf3d3be182323e444595d518ed3346ce83/fabric/src/main/resources/assets/guithium/textures/gui/sprites/widget/radio.png
--------------------------------------------------------------------------------
/fabric/src/main/resources/assets/guithium/textures/gui/sprites/widget/radio_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pl3x-net/guithium/4a6f1fdf3d3be182323e444595d518ed3346ce83/fabric/src/main/resources/assets/guithium/textures/gui/sprites/widget/radio_highlighted.png
--------------------------------------------------------------------------------
/fabric/src/main/resources/assets/guithium/textures/gui/sprites/widget/radio_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pl3x-net/guithium/4a6f1fdf3d3be182323e444595d518ed3346ce83/fabric/src/main/resources/assets/guithium/textures/gui/sprites/widget/radio_selected.png
--------------------------------------------------------------------------------
/fabric/src/main/resources/assets/guithium/textures/gui/sprites/widget/radio_selected_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pl3x-net/guithium/4a6f1fdf3d3be182323e444595d518ed3346ce83/fabric/src/main/resources/assets/guithium/textures/gui/sprites/widget/radio_selected_highlighted.png
--------------------------------------------------------------------------------
/fabric/src/main/resources/fabric.mod.json:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": 1,
3 | "id": "guithium",
4 | "version": "${version}",
5 | "name": "Guithium",
6 | "description": "${description}",
7 | "authors": [
8 | "BillyGalbreath"
9 | ],
10 | "contact": {
11 | "homepage": "${website}",
12 | "sources": "${website}",
13 | "issues": "https://github.com/pl3x-net/guithium/issues"
14 | },
15 | "license": "MIT",
16 | "icon": "assets/guithium/icon.png",
17 | "environment": "*",
18 | "entrypoints": {
19 | "client": [
20 | "net.pl3x.guithium.fabric.GuithiumMod"
21 | ]
22 | },
23 | "mixins": [
24 | "guithium.mixins.json"
25 | ],
26 | "accessWidener": "guithium.accesswidener",
27 | "depends": {
28 | "fabricloader": ">=${fabricloader}",
29 | "minecraft": "${minecraft}",
30 | "java": ">=21",
31 | "fabric-api": "*"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/fabric/src/main/resources/guithium.accesswidener:
--------------------------------------------------------------------------------
1 | accessWidener v2 named
2 |
3 | accessible field net/minecraft/client/gui/GuiGraphics bufferSource Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;
4 |
5 | accessible field net/minecraft/client/gui/screens/Screen initialized Z
6 | accessible field net/minecraft/client/gui/screens/Screen renderables Ljava/util/List;
7 |
8 | accessible field net/minecraft/client/gui/components/AbstractWidget message Lnet/minecraft/network/chat/Component;
9 | extendable method net/minecraft/client/gui/components/AbstractWidget render (Lnet/minecraft/client/gui/GuiGraphics;IIF)V
10 |
11 | accessible field net/minecraft/client/gui/components/Checkbox selected Z
12 | accessible field net/minecraft/client/gui/components/Checkbox textWidget Lnet/minecraft/client/gui/components/MultiLineTextWidget;
13 | accessible field net/minecraft/client/gui/components/Checkbox CHECKBOX_SELECTED_HIGHLIGHTED_SPRITE Lnet/minecraft/resources/ResourceLocation;
14 | accessible field net/minecraft/client/gui/components/Checkbox CHECKBOX_SELECTED_SPRITE Lnet/minecraft/resources/ResourceLocation;
15 | accessible field net/minecraft/client/gui/components/Checkbox CHECKBOX_HIGHLIGHTED_SPRITE Lnet/minecraft/resources/ResourceLocation;
16 | accessible field net/minecraft/client/gui/components/Checkbox CHECKBOX_SPRITE Lnet/minecraft/resources/ResourceLocation;
17 | accessible method net/minecraft/client/gui/components/Checkbox (IIILnet/minecraft/network/chat/Component;Lnet/minecraft/client/gui/Font;ZLnet/minecraft/client/gui/components/Checkbox$OnValueChange;)V
18 | accessible method net/minecraft/client/gui/components/Checkbox getAdjustedWidth (ILnet/minecraft/network/chat/Component;Lnet/minecraft/client/gui/Font;)I
19 | accessible method net/minecraft/client/gui/components/Checkbox getAdjustedHeight (Lnet/minecraft/client/gui/Font;)I
20 | accessible method net/minecraft/client/gui/components/Checkbox getDefaultWidth (Lnet/minecraft/network/chat/Component;Lnet/minecraft/client/gui/Font;)I
21 |
22 | accessible method net/minecraft/client/gui/components/AbstractSliderButton setValue (D)V
23 |
--------------------------------------------------------------------------------
/fabric/src/main/resources/guithium.mixins.json:
--------------------------------------------------------------------------------
1 | {
2 | "required": true,
3 | "minVersion": "0.8",
4 | "package": "net.pl3x.guithium.fabric.mixin",
5 | "compatibilityLevel": "JAVA_21",
6 | "refmap": "guithium.refmap.json",
7 | "injectors": {
8 | "defaultRequire": 1
9 | },
10 | "client": [
11 | "AbstractWidgetMixin",
12 | "GuiMixin",
13 | "RenderSystemMixin"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx3G
2 | org.gradle.daemon=false
3 | org.gradle.parallel=false
4 |
--------------------------------------------------------------------------------
/gradle/libs.versions.toml:
--------------------------------------------------------------------------------
1 | [versions]
2 | guithium = "0.1.0"
3 | minecraft = "1.21.5"
4 |
5 | paperweight = "2.0.0-beta.17" # https://github.com/PaperMC/paperweight
6 |
7 | # https://fabricmc.net/develop/
8 | fabricApi = "0.123.2+1.21.5"
9 | fabricLoader = "0.16.14"
10 | fabricLoom = "1.10-SNAPSHOT"
11 |
12 | adventureApi = "4.21.0" # https://github.com/KyoriPowered/adventure
13 | adventureFabric = "6.4.0" # https://github.com/KyoriPowered/adventure-platform-mod
14 |
15 | bstats = "3.1.0" # https://github.com/Bastian/bstats-metrics
16 | minotaur = "2.+" # https://github.com/modrinth/minotaur
17 | indra-git = "3.1.3" # https://github.com/KyoriPowered/indra
18 | shadowjar = "8.3.5" # https://github.com/GradleUp/shadow
19 | fix-javadoc = "1.19" # https://github.com/mfnalex/gradle-fix-javadoc-plugin
20 |
21 | # make these match versions Paper API uses
22 | # https://github.com/PaperMC/Paper/blob/main/paper-api/build.gradle.kts
23 | apache = "3.17.0"
24 | gson = "2.11.0"
25 | guava = "33.3.1-jre"
26 | annotations = "26.0.2"
27 | slf4j = "2.0.16"
28 | junit = "5.12.2"
29 | asm = "9.8"
30 |
31 | [plugins]
32 | paperweight = { id = "io.papermc.paperweight.userdev", version.ref = "paperweight" }
33 | fabric-loom = { id = "fabric-loom", version.ref = "fabricLoom" }
34 | minotaur = { id = "com.modrinth.minotaur", version.ref = "minotaur" }
35 | indra-git = { id = "net.kyori.indra.git", version.ref = "indra-git" }
36 | shadowjar = { id = "com.gradleup.shadow", version.ref = "shadowjar" }
37 | fix-javadoc = { id = "com.jeff-media.fix-javadoc-plugin", version.ref = "fix-javadoc" }
38 |
39 | [libraries]
40 | minecraft = { group = "com.mojang", name = "minecraft", version.ref = "minecraft" }
41 |
42 | fabric-api = { group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = "fabricApi" }
43 | fabric-loader = { group = "net.fabricmc", name = "fabric-loader", version.ref = "fabricLoader" }
44 |
45 | adventure-api = { group = "net.kyori", name = "adventure-api", version.ref = "adventureApi" }
46 | adventure-fabric = { group = "net.kyori", name = "adventure-platform-fabric", version.ref = "adventureFabric" }
47 | adventure-gson = { group = "net.kyori", name = "adventure-text-serializer-gson", version.ref = "adventureApi" }
48 |
49 | bstats = { group = "org.bstats", name = "bstats-bukkit", version.ref = "bstats" }
50 |
51 | apache = { group = "org.apache.commons", name = "commons-lang3", version.ref = "apache" }
52 | gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" }
53 | guava = { group = "com.google.guava", name = "guava", version.ref = "guava" }
54 | annotations = { group = "org.jetbrains", name = "annotations", version.ref = "annotations" }
55 | slf4j = { group = "org.slf4j", name = "slf4j-api", version.ref = "slf4j" }
56 | junit = { group = "org.junit.jupiter", name = "junit-jupiter", version.ref = "junit" }
57 | junitPlatform = { group = "org.junit.platform", name = "junit-platform-launcher" }
58 | asm = { group = "org.ow2.asm", name = "asm-tree", version.ref = "asm" }
59 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pl3x-net/guithium/4a6f1fdf3d3be182323e444595d518ed3346ce83/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/paper/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.paperweight)
3 | alias(libs.plugins.shadowjar)
4 | }
5 |
6 | dependencies {
7 | implementation(project(":api"))
8 |
9 | paperweight.paperDevBundle("${libs.versions.minecraft.get()}-R0.1-SNAPSHOT")
10 |
11 | implementation(libs.bstats.get())
12 | }
13 |
14 | tasks {
15 | build {
16 | dependsOn(shadowJar)
17 | }
18 |
19 | shadowJar {
20 | archiveClassifier.set("")
21 | arrayOf(
22 | "org.bstats",
23 | ).forEach { it -> relocate(it, "libs.$it") }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/paper/src/main/java/net/pl3x/guithium/plugin/GuithiumPlugin.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.plugin;
2 |
3 | import java.lang.reflect.Field;
4 | import net.pl3x.guithium.api.Guithium;
5 | import net.pl3x.guithium.api.action.ActionRegistry;
6 | import net.pl3x.guithium.api.gui.texture.TextureManager;
7 | import net.pl3x.guithium.plugin.listener.PaperListener;
8 | import net.pl3x.guithium.plugin.network.PaperNetworkHandler;
9 | import net.pl3x.guithium.plugin.player.PaperPlayerManager;
10 | import org.bstats.bukkit.Metrics;
11 | import org.bukkit.plugin.java.JavaPlugin;
12 | import org.jetbrains.annotations.NotNull;
13 |
14 | public class GuithiumPlugin extends JavaPlugin implements Guithium {
15 | private final ActionRegistry actionRegistry = new ActionRegistry();
16 | private final PaperNetworkHandler networkHandler = new PaperNetworkHandler();
17 | private final PaperPlayerManager playerManager = new PaperPlayerManager();
18 | private final TextureManager textureManager = new TextureManager();
19 |
20 | private final String version;
21 |
22 | private Metrics metrics;
23 |
24 | public GuithiumPlugin() {
25 | String version = getClass().getPackage().getImplementationVersion();
26 | this.version = version == null ? "unknown" : version;
27 |
28 | try {
29 | Field api = Provider.class.getDeclaredField("api");
30 | api.setAccessible(true);
31 | api.set(null, this);
32 | } catch (NoSuchFieldException | IllegalAccessException e) {
33 | logger.error("Failed to set Guithium API", e);
34 | }
35 | }
36 |
37 | public void onEnable() {
38 | getNetworkHandler().registerListeners();
39 |
40 | getServer().getPluginManager().registerEvents(new PaperListener(), this);
41 |
42 | this.metrics = new Metrics(this, BSTATS_ID);
43 | }
44 |
45 | public void onDisable() {
46 | if (this.metrics != null) {
47 | this.metrics.shutdown();
48 | this.metrics = null;
49 | }
50 | }
51 |
52 | @Override
53 | @NotNull
54 | public String getVersion() {
55 | return this.version;
56 | }
57 |
58 | @Override
59 | @NotNull
60 | public ActionRegistry getActionRegistry() {
61 | return this.actionRegistry;
62 | }
63 |
64 | @Override
65 | @NotNull
66 | public PaperNetworkHandler getNetworkHandler() {
67 | return this.networkHandler;
68 | }
69 |
70 | @Override
71 | @NotNull
72 | public PaperPlayerManager getPlayerManager() {
73 | return this.playerManager;
74 | }
75 |
76 | @Override
77 | @NotNull
78 | public TextureManager getTextureManager() {
79 | return this.textureManager;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/paper/src/main/java/net/pl3x/guithium/plugin/listener/PaperListener.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.plugin.listener;
2 |
3 | import net.pl3x.guithium.api.Guithium;
4 | import org.bukkit.event.EventHandler;
5 | import org.bukkit.event.EventPriority;
6 | import org.bukkit.event.Listener;
7 | import org.bukkit.event.player.PlayerLoginEvent;
8 | import org.bukkit.event.player.PlayerQuitEvent;
9 | import org.jetbrains.annotations.NotNull;
10 |
11 | public class PaperListener implements Listener {
12 | @EventHandler(priority = EventPriority.MONITOR)
13 | public void onLogin(@NotNull PlayerLoginEvent event) {
14 | if (event.getResult() == PlayerLoginEvent.Result.ALLOWED) {
15 | Guithium.api().getPlayerManager().add(event.getPlayer());
16 | }
17 | }
18 |
19 | @EventHandler
20 | public void onQuit(@NotNull PlayerQuitEvent event) {
21 | Guithium.api().getPlayerManager().remove(event.getPlayer());
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/paper/src/main/java/net/pl3x/guithium/plugin/network/PaperConnection.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.plugin.network;
2 |
3 | import net.pl3x.guithium.api.Guithium;
4 | import net.pl3x.guithium.api.network.Connection;
5 | import net.pl3x.guithium.api.network.NetworkHandler;
6 | import net.pl3x.guithium.api.network.packet.Packet;
7 | import net.pl3x.guithium.plugin.GuithiumPlugin;
8 | import net.pl3x.guithium.plugin.player.PaperPlayer;
9 | import org.bukkit.entity.Player;
10 | import org.jetbrains.annotations.NotNull;
11 |
12 | public class PaperConnection implements Connection {
13 | private final PaperPlayer player;
14 | private final PaperPacketListener packetListener;
15 |
16 | public PaperConnection(@NotNull PaperPlayer player) {
17 | this.player = player;
18 | this.packetListener = new PaperPacketListener(player);
19 | }
20 |
21 | @Override
22 | @NotNull
23 | public PaperPacketListener getPacketListener() {
24 | return this.packetListener;
25 | }
26 |
27 | @Override
28 | public void send(@NotNull Packet packet) {
29 | send(packet, false);
30 | }
31 |
32 | @Override
33 | public void send(@NotNull Packet packet, boolean force) {
34 | if (force || this.player.hasGuithium()) {
35 | this.player.unwrap().sendPluginMessage(
36 | (GuithiumPlugin) Guithium.api(),
37 | NetworkHandler.CHANNEL,
38 | packet.write().toByteArray()
39 | );
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/paper/src/main/java/net/pl3x/guithium/plugin/network/PaperNetworkHandler.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.plugin.network;
2 |
3 | import net.pl3x.guithium.api.Guithium;
4 | import net.pl3x.guithium.api.network.NetworkHandler;
5 | import net.pl3x.guithium.api.player.WrappedPlayer;
6 | import net.pl3x.guithium.plugin.GuithiumPlugin;
7 | import org.bukkit.plugin.messaging.Messenger;
8 |
9 | public class PaperNetworkHandler extends NetworkHandler {
10 | @Override
11 | public void registerListeners() {
12 | GuithiumPlugin plugin = (GuithiumPlugin) Guithium.api();
13 | Messenger messenger = plugin.getServer().getMessenger();
14 | messenger.registerOutgoingPluginChannel(plugin, CHANNEL);
15 | messenger.registerIncomingPluginChannel(plugin, CHANNEL,
16 | (channel, sender, bytes) -> {
17 | // verify player
18 | WrappedPlayer player = plugin.getPlayerManager().get(sender.getUniqueId());
19 | if (player == null) {
20 | Guithium.logger.warn("Received packet from unknown player ({})", sender.getName());
21 | return;
22 | }
23 |
24 | // receive data from player
25 | receive(player.getConnection(), bytes);
26 | }
27 | );
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/paper/src/main/java/net/pl3x/guithium/plugin/player/PaperPlayer.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.plugin.player;
2 |
3 | import java.util.UUID;
4 | import net.pl3x.guithium.api.Guithium;
5 | import net.pl3x.guithium.api.Unsafe;
6 | import net.pl3x.guithium.api.gui.Screen;
7 | import net.pl3x.guithium.api.player.WrappedPlayer;
8 | import net.pl3x.guithium.plugin.network.PaperConnection;
9 | import org.bukkit.entity.Player;
10 | import org.jetbrains.annotations.NotNull;
11 | import org.jetbrains.annotations.Nullable;
12 |
13 | public class PaperPlayer implements WrappedPlayer {
14 | private final Player player;
15 | private final PaperConnection connection;
16 |
17 | private Screen currentScreen;
18 | private int protocol = -1;
19 |
20 | protected PaperPlayer(@NotNull Player player) {
21 | this.player = player;
22 | this.connection = new PaperConnection(this);
23 | }
24 |
25 | @NotNull
26 | public T unwrap() {
27 | return Unsafe.cast(this.player);
28 | }
29 |
30 | @Override
31 | @NotNull
32 | public String getName() {
33 | return this.player.getName();
34 | }
35 |
36 | @Override
37 | @NotNull
38 | public UUID getUUID() {
39 | return this.player.getUniqueId();
40 | }
41 |
42 | @Override
43 | @NotNull
44 | public PaperConnection getConnection() {
45 | return this.connection;
46 | }
47 |
48 | @Override
49 | @Nullable
50 | public Screen getCurrentScreen() {
51 | return this.currentScreen;
52 | }
53 |
54 | @Override
55 | public void setCurrentScreen(@Nullable Screen screen) {
56 | this.currentScreen = screen;
57 | }
58 |
59 | @Override
60 | public boolean hasGuithium() {
61 | return getProtocol() == Guithium.PROTOCOL;
62 | }
63 |
64 | public int getProtocol() {
65 | return this.protocol;
66 | }
67 |
68 | public void setProtocol(int protocol) {
69 | this.protocol = protocol;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/paper/src/main/java/net/pl3x/guithium/plugin/player/PaperPlayerManager.java:
--------------------------------------------------------------------------------
1 | package net.pl3x.guithium.plugin.player;
2 |
3 | import net.pl3x.guithium.api.player.PlayerManager;
4 | import net.pl3x.guithium.api.player.WrappedPlayer;
5 | import org.bukkit.entity.Player;
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | public class PaperPlayerManager extends PlayerManager {
10 | @Override
11 | @NotNull
12 | public WrappedPlayer add(@NotNull T player) {
13 | if (!(player instanceof Player bukkit)) {
14 | throw new IllegalArgumentException("player is not a bukkit player");
15 | }
16 | return add(new PaperPlayer(bukkit));
17 | }
18 |
19 | @Override
20 | @NotNull
21 | public WrappedPlayer get(@NotNull T player) {
22 | if (!(player instanceof Player bukkit)) {
23 | throw new IllegalArgumentException("player is not a bukkit player");
24 | }
25 | WrappedPlayer wrappedPlayer = get(bukkit.getUniqueId());
26 | if (wrappedPlayer != null) {
27 | return wrappedPlayer;
28 | }
29 | return add(new PaperPlayer(bukkit));
30 | }
31 |
32 | @Override
33 | @Nullable
34 | public WrappedPlayer remove(@NotNull T player) {
35 | if (!(player instanceof Player bukkit)) {
36 | throw new IllegalArgumentException("player is not a bukkit player");
37 | }
38 | return remove(bukkit.getUniqueId());
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/paper/src/main/resources/paper-plugin.yml:
--------------------------------------------------------------------------------
1 | name: "Guithium"
2 | main: "net.pl3x.guithium.plugin.GuithiumPlugin"
3 | version: "${version}"
4 | api-version: "${minecraft}"
5 | description: "${description}"
6 | authors: [ "BillyGalbreath" ]
7 | website: "${website}"
8 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | gradlePluginPortal()
4 | maven("https://maven.fabricmc.net/")
5 | maven("https://repo.papermc.io/repository/maven-public/")
6 | }
7 | }
8 |
9 | rootProject.name = "guithium"
10 |
11 | include("api")
12 | include("fabric")
13 | include("paper")
14 |
--------------------------------------------------------------------------------