add reset votes, add documentation, and move some things around

This commit is contained in:
Elijah R 2024-05-01 16:24:00 -04:00
parent de5b6cf703
commit 96f12f36f2
5 changed files with 152 additions and 39 deletions

View file

@ -31,6 +31,8 @@ public class CollabVMClient {
private BufferedImage _framebuffer; private BufferedImage _framebuffer;
private TurnQueue _currentTurnQueue; private TurnQueue _currentTurnQueue;
private TurnStatus _turnStatus; private TurnStatus _turnStatus;
private ResetVote _currentVote;
private boolean _usesAccountAuth;
// Futures // Futures
private CompletableFuture<AccountLoginResult> _loginFuture; private CompletableFuture<AccountLoginResult> _loginFuture;
@ -47,10 +49,12 @@ public class CollabVMClient {
_debug = debug; _debug = debug;
_connected = false; _connected = false;
_connectedToNode = false; _connectedToNode = false;
_usesAccountAuth = false;
_username = null; _username = null;
_rank = Rank.Unregistered; _rank = Rank.Unregistered;
_permissions = Permissions.None(); _permissions = Permissions.None();
_turnStatus = TurnStatus.None; _turnStatus = TurnStatus.None;
_currentVote = new ResetVote(0, 0, ResetVoteStatus.None, 0);
_currentTurnQueue = new TurnQueue(null, null, new User[0]); _currentTurnQueue = new TurnQueue(null, null, new User[0]);
_node = null; _node = null;
_url = url; _url = url;
@ -62,14 +66,95 @@ public class CollabVMClient {
_socket.addHeader("Origin", "https://computernewb.com"); _socket.addHeader("Origin", "https://computernewb.com");
} }
// Public methods // Public methods
/**
* Connects to the CollabVM server
*/
public void connect() { public void connect() {
_socket.connect(); _socket.connect();
} }
/**
* Encode and send a Guacamole instruction to the server
* @param args The arguments to send to the server
*/
public void sendGuac(String... args) {
if (_debug) System.out.println("Sending message: " + Guacutils.Encode(args));
_socket.send(Guacutils.Encode(args));
}
/**
* Log in to an account using a token
* @param token The token to use to log in
* @return A CompletableFuture that will complete when the login attempt is finished
*/
public CompletableFuture<AccountLoginResult> loginAccount(String token) {
this._loginFuture = new CompletableFuture<>();
this.sendGuac("login", token);
return this._loginFuture;
}
// Getters and setters
/**
* If not connected, sets the username to request when connecting.
* If connected, sends a rename instruction to the server
* @param username The username to rename to
*/
public void setUsername(String username) {
if (_connected)
this.sendGuac("rename", username);
// Don't set the username if we're connected until the server confirms the rename
else
this._username = username;
}
/**
* @return The current username of the client
*/
public String getUsername() { return this._username; }
/**
* Sets the node to connect to during the handshake
* @param node The node to connect to
* @throws IllegalStateException if the client is already connected to a node
*/
public void setNode(String node) {
if (this._node != null) throw new IllegalStateException("Cannot switch nodes after connecting. Disconnect the client first.");
if (_connected)
this.sendGuac("connect", node);
this._node = node;
}
/**
* @return The current node the client is connected to
*/
public String getNode() { return this._node; }
/**
* @return A list of users currently in the VM
*/
public User[] getUsers() { return this._users.toArray(new User[0]); }
/**
* @return A copy of the entire VM screen
*/
public BufferedImage getFramebuffer() {
BufferedImage img = new BufferedImage(_framebuffer.getWidth(), _framebuffer.getHeight(), BufferedImage.TYPE_INT_ARGB);
img.getGraphics().drawImage(_framebuffer, 0, 0, null);
return img;
}
/**
* Sets the event handler for the client
* @param handler The event handler to set
*/
public void setEventHandler(CollabVMEventHandler handler) { this._eventHandler = handler; }
// WebSocket event handlers // WebSocket event handlers
public void onWsOpen(ServerHandshake serverHandshake) { void onWsOpen(ServerHandshake serverHandshake) {
_connected = true; _connected = true;
if (_username != null) if (_username != null)
this.sendGuac("rename", this._username); this.sendGuac("rename", this._username);
@ -80,7 +165,7 @@ public class CollabVMClient {
_eventHandler.OnOpen(); _eventHandler.OnOpen();
} }
public void onWsMessage(String msg) { void onWsMessage(String msg) {
String[] msgArr; String[] msgArr;
try { try {
msgArr = Guacutils.Decode(msg); msgArr = Guacutils.Decode(msg);
@ -228,47 +313,50 @@ public class CollabVMClient {
this._loginFuture.complete(new AccountLoginResult(success, success ? null : msgArr[2])); this._loginFuture.complete(new AccountLoginResult(success, success ? null : msgArr[2]));
break; break;
} }
case "auth": {
this._usesAccountAuth = true;
_eventHandler.OnUsesAccountAuth(msgArr[1]);
} }
case "vote": {
switch (msgArr[1]) {
case "0":
if (msgArr.length < 4) return;
// Intentional fallthrough
case "1":
this._currentVote = new ResetVote(
Integer.parseInt(msgArr[3]),
Integer.parseInt(msgArr[4]), msgArr[1].equals("0") ? ResetVoteStatus.Started : ResetVoteStatus.Update,
Integer.parseInt(msgArr[2])
);
this._eventHandler.OnVoteUpdate(this._currentVote);
break;
case "2":
this._currentVote = new ResetVote(0, 0, ResetVoteStatus.None, 0);
this._eventHandler.OnVoteEnded();
break;
case "3":
this._eventHandler.OnVoteCooldown(Integer.parseInt(msgArr[2]));
break;
} }
break;
}
case "admin": {
switch (msgArr[1]) {
public CompletableFuture<AccountLoginResult> loginAccount(String token) {
this._loginFuture = new CompletableFuture<>();
this.sendGuac("login", token);
return this._loginFuture;
} }
public void onWsClose(int code, String reason, boolean remote) { break;
}
}
}
void onWsClose(int code, String reason, boolean remote) {
_connectedToNode = false; _connectedToNode = false;
_connected = false; _connected = false;
_usesAccountAuth = false;
_eventHandler.OnConnectionClosed(); _eventHandler.OnConnectionClosed();
} }
public void onWsError(Exception ex) { void onWsError(Exception ex) {
_connected = false; _connected = false;
_connectedToNode = false;
_usesAccountAuth = false;
} }
public void sendGuac(String... args) {
if (_debug) System.out.println("Sending message: " + Guacutils.Encode(args));
_socket.send(Guacutils.Encode(args));
}
// Getters and setters
public void setUsername(String username) {
if (_connected)
this.sendGuac("rename", username);
// Don't set the username if we're connected until the server confirms the rename
else
this._username = username;
}
public String getUsername() { return this._username; }
public void setNode(String node) {
if (this._node != null) throw new RuntimeException("Cannot switch nodes after connecting. Disconnect the client first.");
if (_connected)
this.sendGuac("connect", node);
this._node = node;
}
public String getNode() { return this._node; }
public User[] getUsers() { return this._users.toArray(new User[0]); }
public BufferedImage getFramebuffer() {
BufferedImage img = new BufferedImage(_framebuffer.getWidth(), _framebuffer.getHeight(), BufferedImage.TYPE_INT_ARGB);
img.getGraphics().drawImage(_framebuffer, 0, 0, null);
return img;
}
public void setEventHandler(CollabVMEventHandler handler) { this._eventHandler = handler; }
} }

View file

@ -14,9 +14,10 @@ public interface CollabVMEventHandler {
default void OnUserRenamed(String oldName, String newName, User user) {} default void OnUserRenamed(String oldName, String newName, User user) {}
default void OnUserJoined(User user) {} default void OnUserJoined(User user) {}
default void OnUserLeft(User user) {} default void OnUserLeft(User user) {}
default void OnVoteUpdate() {} default void OnVoteUpdate(ResetVote vote) {}
default void OnVoteEnded() {} default void OnVoteEnded() {}
default void OnVoteCooldown(int cooldown) {} default void OnVoteCooldown(int cooldown) {}
default void OnTurnUpdate(TurnQueue queue) {} default void OnTurnUpdate(TurnQueue queue) {}
default void OnConnectionClosed() {} default void OnConnectionClosed() {}
default void OnUsesAccountAuth(String authServerURL) {}
} }

View file

@ -8,6 +8,9 @@ import org.java_websocket.protocols.Protocol;
import java.net.URI; import java.net.URI;
import java.util.Collections; import java.util.Collections;
/**
* Wrapper class to avoid having CollabVMClient directly extend WebSocketClient
*/
class CollabVMWebSocket extends WebSocketClient { class CollabVMWebSocket extends WebSocketClient {
private CollabVMClient _owner; private CollabVMClient _owner;

View file

@ -0,0 +1,14 @@
package dev.elijahr.CollabVM4j;
public class ResetVote {
public Integer Yes;
public Integer No;
public ResetVoteStatus Status;
public Integer TimeToVoteEnd;
public ResetVote(Integer yes, Integer no, ResetVoteStatus status, Integer timeToVoteEnd) {
Yes = yes;
No = no;
Status = status;
TimeToVoteEnd = timeToVoteEnd;
}
}

View file

@ -0,0 +1,7 @@
package dev.elijahr.CollabVM4j;
public enum ResetVoteStatus {
Started,
Update,
None
}