diff --git a/src/main/java/dev/elijahr/CollabVM4j/AccountLoginResult.java b/src/main/java/dev/elijahr/CollabVM4j/AccountLoginResult.java new file mode 100644 index 0000000..900fc1f --- /dev/null +++ b/src/main/java/dev/elijahr/CollabVM4j/AccountLoginResult.java @@ -0,0 +1,10 @@ +package dev.elijahr.CollabVM4j; + +public class AccountLoginResult { + public boolean Success; + public String Error; + public AccountLoginResult(boolean success, String error) { + Success = success; + Error = error; + } +} diff --git a/src/main/java/dev/elijahr/CollabVM4j/CollabVMClient.java b/src/main/java/dev/elijahr/CollabVM4j/CollabVMClient.java index 0dbfd98..d94d40e 100644 --- a/src/main/java/dev/elijahr/CollabVM4j/CollabVMClient.java +++ b/src/main/java/dev/elijahr/CollabVM4j/CollabVMClient.java @@ -12,39 +12,49 @@ import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; +import java.util.concurrent.CompletableFuture; public class CollabVMClient { // Private fields private boolean _debug; private URI _url; - private CollabVMEventHandler _eventHandler; + private CollabVMEventHandler _eventHandler = new CollabVMEventHandler() {}; private CollabVMWebSocket _socket; private AbstractMap.SimpleEntry[] _customHeaders; private boolean _connected; private boolean _connectedToNode; private String _username; + private int _rank; + private Permissions _permissions; private String _node; private ArrayList _users = new ArrayList<>(); private BufferedImage _framebuffer; + private TurnQueue _currentTurnQueue; + private TurnStatus _turnStatus; + // Futures + private CompletableFuture _loginFuture; // Constructor @SuppressWarnings("unchecked") - public CollabVMClient(URI url, CollabVMEventHandler eventHandler) { - this(url, eventHandler, (AbstractMap.SimpleEntry[]) new AbstractMap.SimpleEntry[0]); + public CollabVMClient(URI url) { + this(url, (AbstractMap.SimpleEntry[]) new AbstractMap.SimpleEntry[0]); } - public CollabVMClient(URI url, CollabVMEventHandler eventHandler, AbstractMap.SimpleEntry[] customHeaders) { - this(url, eventHandler, customHeaders, false); + public CollabVMClient(URI url, AbstractMap.SimpleEntry[] customHeaders) { + this(url, customHeaders, false); } - public CollabVMClient(URI url, CollabVMEventHandler eventHandler, AbstractMap.SimpleEntry[] customHeaders, boolean debug) { + public CollabVMClient(URI url, AbstractMap.SimpleEntry[] customHeaders, boolean debug) { _debug = debug; _connected = false; _connectedToNode = false; _username = null; + _rank = Rank.Unregistered; + _permissions = Permissions.None(); + _turnStatus = TurnStatus.None; + _currentTurnQueue = new TurnQueue(null, null, new User[0]); _node = null; _url = url; _framebuffer = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); - _eventHandler = eventHandler; _socket = new CollabVMWebSocket(_url, this); _customHeaders = customHeaders; for (AbstractMap.SimpleEntry header : _customHeaders) _socket.addHeader(header.getKey(), header.getValue()); @@ -116,6 +126,7 @@ public class CollabVMClient { for (int i = 2; i < msgArr.length; i += 2) { String username = msgArr[i]; int rank = Integer.parseInt(msgArr[i + 1]); + if (username.equals(_username)) _rank = rank; _users.removeIf(u -> u.Username.equals(username)); User user = new User(username, rank); _users.add(user); @@ -175,8 +186,56 @@ public class CollabVMClient { _eventHandler.OnRectangle(x, y, rect); break; } + case "turn": { + ArrayList queue = new ArrayList<>(); + // Reset turn data + for (User user : _users) user.TurnStatus = TurnStatus.None; + this._turnStatus = TurnStatus.None; + int queuedUsers = Integer.parseInt(msgArr[2]); + if (queuedUsers == 0) { + this._currentTurnQueue = new TurnQueue(null, null, new User[0]); + _eventHandler.OnTurnUpdate(this._currentTurnQueue); + return; + } + User currentTurnUser = _users.stream().filter(u -> u.Username.equals(msgArr[3])).findFirst().orElse(null); + if (currentTurnUser == null) return; + if (currentTurnUser.Username.equals(_username)) { + this._turnStatus = TurnStatus.HasTurn; + } + currentTurnUser.TurnStatus = TurnStatus.HasTurn; + queue.add(currentTurnUser); + if (queuedUsers > 1) { + for (int i = 1; i < queuedUsers; i++) { + String username = msgArr[i + 3]; + User user = _users.stream().filter(u -> u.Username.equals(username)).findFirst().orElse(null); + if (user == null) continue; + user.TurnStatus = TurnStatus.Waiting; + if (user.Username.equals(_username)) + this._turnStatus = TurnStatus.Waiting; + queue.add(user); + } + } + this._currentTurnQueue = new TurnQueue( + (this._turnStatus == TurnStatus.HasTurn) ? Integer.parseInt(msgArr[1]) : null, + (this._turnStatus == TurnStatus.Waiting) ? Integer.parseInt(msgArr[msgArr.length - 1]) : null, + queue.toArray(new User[0]) + ); + _eventHandler.OnTurnUpdate(this._currentTurnQueue); + break; + } + case "login": { + boolean success = msgArr[1].equals("1"); + this._loginFuture.complete(new AccountLoginResult(success, success ? null : msgArr[2])); + break; + } } } + + public CompletableFuture loginAccount(String token) { + this._loginFuture = new CompletableFuture<>(); + this.sendGuac("login", token); + return this._loginFuture; + } public void onWsClose(int code, String reason, boolean remote) { _connectedToNode = false; _connected = false; @@ -211,4 +270,5 @@ public class CollabVMClient { img.getGraphics().drawImage(_framebuffer, 0, 0, null); return img; } + public void setEventHandler(CollabVMEventHandler handler) { this._eventHandler = handler; } } diff --git a/src/main/java/dev/elijahr/CollabVM4j/CollabVMEventHandler.java b/src/main/java/dev/elijahr/CollabVM4j/CollabVMEventHandler.java index dcff89b..1514624 100644 --- a/src/main/java/dev/elijahr/CollabVM4j/CollabVMEventHandler.java +++ b/src/main/java/dev/elijahr/CollabVM4j/CollabVMEventHandler.java @@ -17,6 +17,6 @@ public interface CollabVMEventHandler { default void OnVoteUpdate() {} default void OnVoteEnded() {} default void OnVoteCooldown(int cooldown) {} - default void OnTurnUpdate() {} + default void OnTurnUpdate(TurnQueue queue) {} default void OnConnectionClosed() {} } diff --git a/src/main/java/dev/elijahr/CollabVM4j/Permissions.java b/src/main/java/dev/elijahr/CollabVM4j/Permissions.java new file mode 100644 index 0000000..50c25d0 --- /dev/null +++ b/src/main/java/dev/elijahr/CollabVM4j/Permissions.java @@ -0,0 +1,30 @@ +package dev.elijahr.CollabVM4j; + +public class Permissions { + public boolean restore; + public boolean reboot; + public boolean ban; + public boolean kick; + public boolean mute; + public boolean forcevote; + public boolean bypassendturn; + public boolean rename; + public boolean getip; + public boolean xss; + + public Permissions(int mask) { + restore = (mask & 1) != 0; + reboot = (mask & 2) != 0; + ban = (mask & 4) != 0; + kick = (mask & 8) != 0; + mute = (mask & 16) != 0; + forcevote = (mask & 32) != 0; + bypassendturn = (mask & 64) != 0; + rename = (mask & 128) != 0; + getip = (mask & 256) != 0; + xss = (mask & 512) != 0; + } + + public static Permissions All() { return new Permissions(65535); } + public static Permissions None() { return new Permissions(0); } +} diff --git a/src/main/java/dev/elijahr/CollabVM4j/Rank.java b/src/main/java/dev/elijahr/CollabVM4j/Rank.java index 2ad56bb..7052876 100644 --- a/src/main/java/dev/elijahr/CollabVM4j/Rank.java +++ b/src/main/java/dev/elijahr/CollabVM4j/Rank.java @@ -2,8 +2,8 @@ package dev.elijahr.CollabVM4j; // java enums suck so we have to use a class instead public class Rank { - public final int Unregistered = 0; - public final int Registered = 1; - public final int Admin = 2; - public final int Moderator = 3; + public static final int Unregistered = 0; + public static final int Registered = 1; + public static final int Admin = 2; + public static final int Moderator = 3; } diff --git a/src/main/java/dev/elijahr/CollabVM4j/TurnQueue.java b/src/main/java/dev/elijahr/CollabVM4j/TurnQueue.java new file mode 100644 index 0000000..3535e5d --- /dev/null +++ b/src/main/java/dev/elijahr/CollabVM4j/TurnQueue.java @@ -0,0 +1,14 @@ +package dev.elijahr.CollabVM4j; + +import java.util.Optional; + +public class TurnQueue { + public Integer TurnTimer; + public Integer QueueTimer; + public User[] Queue; + public TurnQueue(Integer turnTimer, Integer queueTimer, User[] queue) { + TurnTimer = turnTimer; + QueueTimer = queueTimer; + Queue = queue; + } +} diff --git a/src/main/java/dev/elijahr/CollabVM4j/TurnStatus.java b/src/main/java/dev/elijahr/CollabVM4j/TurnStatus.java new file mode 100644 index 0000000..3e2b8d2 --- /dev/null +++ b/src/main/java/dev/elijahr/CollabVM4j/TurnStatus.java @@ -0,0 +1,7 @@ +package dev.elijahr.CollabVM4j; + +public enum TurnStatus { + None, + Waiting, + HasTurn +} diff --git a/src/main/java/dev/elijahr/CollabVM4j/User.java b/src/main/java/dev/elijahr/CollabVM4j/User.java index 32bd822..2b8ed65 100644 --- a/src/main/java/dev/elijahr/CollabVM4j/User.java +++ b/src/main/java/dev/elijahr/CollabVM4j/User.java @@ -3,8 +3,10 @@ package dev.elijahr.CollabVM4j; public class User { public String Username; public int Rank; + public TurnStatus TurnStatus; public User(String username, int rank) { Username = username; Rank = rank; + TurnStatus = dev.elijahr.CollabVM4j.TurnStatus.None; } }