add support for account login
This commit is contained in:
parent
103bad27b6
commit
7117823772
3 changed files with 64 additions and 5 deletions
7
CollabVMSharp/AccountLoginResult.cs
Normal file
7
CollabVMSharp/AccountLoginResult.cs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
namespace CollabVMSharp;
|
||||||
|
|
||||||
|
public class AccountLoginResult
|
||||||
|
{
|
||||||
|
public bool Success { get; set; }
|
||||||
|
public string? Error { get; set; }
|
||||||
|
}
|
|
@ -41,11 +41,13 @@ public class CollabVMClient {
|
||||||
private WebProxy? _proxy;
|
private WebProxy? _proxy;
|
||||||
private Dictionary<string, Action<string, string[]>> commandsSeparatedArgs;
|
private Dictionary<string, Action<string, string[]>> commandsSeparatedArgs;
|
||||||
private Dictionary<string, Action<string, string>> commandsOneArg;
|
private Dictionary<string, Action<string, string>> commandsOneArg;
|
||||||
|
private bool _usesAccountAuth;
|
||||||
// Tasks and related
|
// Tasks and related
|
||||||
private TaskCompletionSource<Node[]> GotNodeList;
|
private TaskCompletionSource<Node[]> GotNodeList;
|
||||||
private TaskCompletionSource<bool> GotConnectionToNode;
|
private TaskCompletionSource<bool> GotConnectionToNode;
|
||||||
private TaskCompletionSource<int> GotTurn;
|
private TaskCompletionSource<int> GotTurn;
|
||||||
private TaskCompletionSource<Rank> GotStaff;
|
private TaskCompletionSource<Rank> GotStaff;
|
||||||
|
private TaskCompletionSource<AccountLoginResult> LoginResult;
|
||||||
private List<GetIPTask> GotIPTasks;
|
private List<GetIPTask> GotIPTasks;
|
||||||
private SemaphoreSlim QEMUMonitorSemaphore;
|
private SemaphoreSlim QEMUMonitorSemaphore;
|
||||||
private TaskCompletionSource<string> QEMUMonitorResult;
|
private TaskCompletionSource<string> QEMUMonitorResult;
|
||||||
|
@ -61,6 +63,7 @@ public class CollabVMClient {
|
||||||
public string Node { get { return this.node; } }
|
public string Node { get { return this.node; } }
|
||||||
|
|
||||||
public string Username { get { return this.username; } }
|
public string Username { get { return this.username; } }
|
||||||
|
public bool UsesAccountAuth { get { return this._usesAccountAuth; } }
|
||||||
// Events
|
// Events
|
||||||
public event EventHandler<ChatMessage> Chat;
|
public event EventHandler<ChatMessage> Chat;
|
||||||
public event EventHandler<ChatMessage[]> ChatHistory;
|
public event EventHandler<ChatMessage[]> ChatHistory;
|
||||||
|
@ -78,6 +81,10 @@ public class CollabVMClient {
|
||||||
public event EventHandler<TurnUpdateEventArgs> TurnUpdate;
|
public event EventHandler<TurnUpdateEventArgs> TurnUpdate;
|
||||||
public event EventHandler ConnectionClosed;
|
public event EventHandler ConnectionClosed;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Fired when the VM requires account authentication. The provided string is the authentication server base URL.
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<string> VMUsesAccountAuth;
|
||||||
|
/// <summary>
|
||||||
/// Client for the CollabVM 1.x Server
|
/// Client for the CollabVM 1.x Server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="url">URL of the CollabVM Server to connect to (Should start with ws:// or wss://)</param>
|
/// <param name="url">URL of the CollabVM Server to connect to (Should start with ws:// or wss://)</param>
|
||||||
|
@ -99,6 +106,7 @@ public class CollabVMClient {
|
||||||
this._perms = Permissions.None;
|
this._perms = Permissions.None;
|
||||||
this._connected = false;
|
this._connected = false;
|
||||||
this._connectedToVM = false;
|
this._connectedToVM = false;
|
||||||
|
this._usesAccountAuth = false;
|
||||||
this.framebuffer = new Image<Rgba32>(1, 1);
|
this.framebuffer = new Image<Rgba32>(1, 1);
|
||||||
this.socket = new();
|
this.socket = new();
|
||||||
this.socket.Options.AddSubProtocol("guacamole");
|
this.socket.Options.AddSubProtocol("guacamole");
|
||||||
|
@ -126,6 +134,7 @@ public class CollabVMClient {
|
||||||
this.GotConnectionToNode = new();
|
this.GotConnectionToNode = new();
|
||||||
this.GotTurn = new();
|
this.GotTurn = new();
|
||||||
this.GotStaff = new();
|
this.GotStaff = new();
|
||||||
|
this.LoginResult = new();
|
||||||
this.GotIPTasks = new();
|
this.GotIPTasks = new();
|
||||||
this.QEMUMonitorResult = new();
|
this.QEMUMonitorResult = new();
|
||||||
this.QEMUMonitorSemaphore = new(1, 1);
|
this.QEMUMonitorSemaphore = new(1, 1);
|
||||||
|
@ -145,6 +154,7 @@ public class CollabVMClient {
|
||||||
VoteCooldown += delegate { };
|
VoteCooldown += delegate { };
|
||||||
TurnUpdate += delegate { };
|
TurnUpdate += delegate { };
|
||||||
ConnectionClosed += delegate { };
|
ConnectionClosed += delegate { };
|
||||||
|
VMUsesAccountAuth += delegate { };
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Connect to the CollabVM Server
|
/// Connect to the CollabVM Server
|
||||||
|
@ -162,11 +172,12 @@ public class CollabVMClient {
|
||||||
this.SendMsg(Guacutils.Encode("rename", this.username));
|
this.SendMsg(Guacutils.Encode("rename", this.username));
|
||||||
else
|
else
|
||||||
this.SendMsg(Guacutils.Encode("rename"));
|
this.SendMsg(Guacutils.Encode("rename"));
|
||||||
if (this.node != null)
|
|
||||||
this.SendMsg(Guacutils.Encode("connect", this.node));
|
|
||||||
this.NOPRecieve.Start();
|
this.NOPRecieve.Start();
|
||||||
this.WebSocketLoop();
|
this.WebSocketLoop();
|
||||||
return;
|
if (this.node == null) return;
|
||||||
|
this.GotConnectionToNode = new();
|
||||||
|
this.SendMsg(Guacutils.Encode("connect", this.node));
|
||||||
|
await this.GotConnectionToNode.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void WebSocketLoop() {
|
private async void WebSocketLoop() {
|
||||||
|
@ -305,7 +316,11 @@ public class CollabVMClient {
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
var user = _users.Find(u => u.Username == msgArr[2]);
|
var user = _users.Find(u => u.Username == msgArr[2]);
|
||||||
user.Username = msgArr[3];
|
// I've no clue why this check is now needed, this has never been a problem before, but now it's causing a NullReferenceException
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
user.Username = msgArr[3];
|
||||||
|
}
|
||||||
this.UserRenamed.Invoke(this, new UserRenamedEventArgs {
|
this.UserRenamed.Invoke(this, new UserRenamedEventArgs {
|
||||||
OldName = msgArr[2],
|
OldName = msgArr[2],
|
||||||
NewName = msgArr[3],
|
NewName = msgArr[3],
|
||||||
|
@ -324,6 +339,7 @@ public class CollabVMClient {
|
||||||
Username = msgArr[i],
|
Username = msgArr[i],
|
||||||
Rank = msgArr[i + 1] switch {
|
Rank = msgArr[i + 1] switch {
|
||||||
"0" => Rank.Unregistered,
|
"0" => Rank.Unregistered,
|
||||||
|
"1" => Rank.Registered,
|
||||||
"2" => Rank.Admin,
|
"2" => Rank.Admin,
|
||||||
"3" => Rank.Moderator,
|
"3" => Rank.Moderator,
|
||||||
_ => Rank.Unregistered
|
_ => Rank.Unregistered
|
||||||
|
@ -411,6 +427,33 @@ public class CollabVMClient {
|
||||||
this.TurnUpdate.Invoke(this, this._currentturn );
|
this.TurnUpdate.Invoke(this, this._currentturn );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "auth":
|
||||||
|
{
|
||||||
|
this._usesAccountAuth = true;
|
||||||
|
VMUsesAccountAuth.Invoke(this, msgArr[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "login":
|
||||||
|
{
|
||||||
|
if (msgArr[1] == "1")
|
||||||
|
{
|
||||||
|
this._rank = Rank.Registered;
|
||||||
|
this.LoginResult.TrySetResult(new()
|
||||||
|
{
|
||||||
|
Success = true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.LoginResult.TrySetResult(new()
|
||||||
|
{
|
||||||
|
Success = false,
|
||||||
|
Error = msgArr[2]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "admin": {
|
case "admin": {
|
||||||
switch (msgArr[1]) {
|
switch (msgArr[1]) {
|
||||||
case "0": {
|
case "0": {
|
||||||
|
@ -625,6 +668,7 @@ public class CollabVMClient {
|
||||||
/// <param name="password">Password to log in with</param>
|
/// <param name="password">Password to log in with</param>
|
||||||
/// <returns>The rank received</returns>
|
/// <returns>The rank received</returns>
|
||||||
public async Task<Rank> Login(string password) {
|
public async Task<Rank> Login(string password) {
|
||||||
|
if (this._usesAccountAuth) throw new InvalidOperationException("This VM requires account authentication. Use the LoginAccount method instead.");
|
||||||
this.GotStaff = new();
|
this.GotStaff = new();
|
||||||
this.SendMsg(Guacutils.Encode("admin", "2", password));
|
this.SendMsg(Guacutils.Encode("admin", "2", password));
|
||||||
return await this.GotStaff.Task;
|
return await this.GotStaff.Task;
|
||||||
|
@ -856,6 +900,13 @@ public class CollabVMClient {
|
||||||
else SendMsg(Guacutils.Encode("rename", newname));
|
else SendMsg(Guacutils.Encode("rename", newname));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<AccountLoginResult> LoginAccount(string token)
|
||||||
|
{
|
||||||
|
this.LoginResult = new();
|
||||||
|
this.SendMsg(Guacutils.Encode("login", token));
|
||||||
|
return await this.LoginResult.Task;
|
||||||
|
}
|
||||||
|
|
||||||
private void ProcessCommand(string username, string cmd) {
|
private void ProcessCommand(string username, string cmd) {
|
||||||
// I stole this from stackoverflow
|
// I stole this from stackoverflow
|
||||||
var re = new Regex("(?<=\")[^\"]*(?=\")|[^\" ]+");
|
var re = new Regex("(?<=\")[^\"]*(?=\")|[^\" ]+");
|
||||||
|
|
|
@ -42,6 +42,7 @@ public class Permissions {
|
||||||
|
|
||||||
public enum Rank {
|
public enum Rank {
|
||||||
Unregistered = 0,
|
Unregistered = 0,
|
||||||
|
Registered = 1,
|
||||||
Moderator = 3,
|
Moderator = 3,
|
||||||
Admin = 2
|
Admin = 2
|
||||||
}
|
}
|
Loading…
Reference in a new issue