mirror of
https://github.com/sbrl/Nibriboard.git
synced 2018-01-10 21:33:49 +00:00
Finish fixing bugs in the core message handling system. It works, more or less! :D
This commit is contained in:
parent
690abc6445
commit
e71ff31ef2
12 changed files with 244 additions and 27 deletions
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
|
||||||
|
using SBRL.Utilities;
|
||||||
|
|
||||||
namespace Nibriboard.Client.Messages
|
namespace Nibriboard.Client.Messages
|
||||||
{
|
{
|
||||||
|
@ -11,7 +12,7 @@ namespace Nibriboard.Client.Messages
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The absolute cursor position.
|
/// The absolute cursor position.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Point AbsCursorPosition;
|
public Vector2 AbsCursorPosition;
|
||||||
|
|
||||||
public CursorPositionMessage()
|
public CursorPositionMessage()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
// TODO: In C# you can either have namespaces or types in a namespace - not both.
|
|
||||||
using Nibriboard.Utilities.JsonConverters;
|
using SBRL.Utilities;
|
||||||
|
using SBRL.Utilities.JsonConverters;
|
||||||
|
|
||||||
namespace Nibriboard.Client.Messages
|
namespace Nibriboard.Client.Messages
|
||||||
{
|
{
|
||||||
|
@ -13,13 +13,12 @@ namespace Nibriboard.Client.Messages
|
||||||
/// The initial visible area on the client's screen.
|
/// The initial visible area on the client's screen.
|
||||||
/// Very useful for determining which chunks we should send a client when they first connect.
|
/// Very useful for determining which chunks we should send a client when they first connect.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonConverter(typeof(RectangleConverter))]
|
public Rectangle InitialViewport = Rectangle.Zero;
|
||||||
public Rectangle InitialViewport = Rectangle.Empty;
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The initial position of the user's cursor.
|
/// The initial position of the user's cursor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonConverter(typeof(RectangleConverter))]
|
public Vector2 InitialAbsCursorPosition = Vector2.Zero;
|
||||||
public Point InitialAbsCursorPosition = Point.Empty;
|
|
||||||
|
|
||||||
public HandshakeRequestMessage()
|
public HandshakeRequestMessage()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,19 +1,23 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
using IotWeb.Common.Http;
|
using IotWeb.Common.Http;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using SBRL.Utilities;
|
using SBRL.Utilities;
|
||||||
using Nibriboard.Client.Messages;
|
using Nibriboard.Client.Messages;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using System.Reflection;
|
|
||||||
using RippleSpace;
|
using RippleSpace;
|
||||||
|
|
||||||
namespace Nibriboard.Client
|
namespace Nibriboard.Client
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A delegate that is used in the event that is fired when a nibri client disconnects.
|
||||||
|
/// </summary>
|
||||||
|
public delegate void NibriDisconnectedEvent(NibriClient disconnectedClient);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a single client connected to the ripple-space on this Nibriboard server.
|
/// Represents a single client connected to the ripple-space on this Nibriboard server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -41,6 +45,12 @@ namespace Nibriboard.Client
|
||||||
["handshakeRequest"] = typeof(HandshakeRequestMessage)
|
["handshakeRequest"] = typeof(HandshakeRequestMessage)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this nibri client is still connected.
|
||||||
|
/// </summary>
|
||||||
|
public bool Connected = true;
|
||||||
|
public event NibriDisconnectedEvent Disconnected;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether this client has completed the handshake yet or not.
|
/// Whether this client has completed the handshake yet or not.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -54,12 +64,12 @@ namespace Nibriboard.Client
|
||||||
/// The current area that this client is looking at.
|
/// The current area that this client is looking at.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The current view port.</value>
|
/// <value>The current view port.</value>
|
||||||
public Rectangle CurrentViewPort { get; private set; } = Rectangle.Empty;
|
public Rectangle CurrentViewPort { get; private set; } = Rectangle.Zero;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The absolute position in plane-space of this client's cursor.
|
/// The absolute position in plane-space of this client's cursor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The absolute cursor position.</value>
|
/// <value>The absolute cursor position.</value>
|
||||||
public Point AbsoluteCursorPosition { get; private set; } = Point.Empty;
|
public Vector2 AbsoluteCursorPosition { get; private set; } = Vector2.Zero;
|
||||||
|
|
||||||
#region Core Setup & Message Routing Logic
|
#region Core Setup & Message Routing Logic
|
||||||
|
|
||||||
|
@ -81,8 +91,8 @@ namespace Nibriboard.Client
|
||||||
|
|
||||||
//Task.Run(async () => await onMessage(frame)).Wait();
|
//Task.Run(async () => await onMessage(frame)).Wait();
|
||||||
};
|
};
|
||||||
|
// Store whether this NibriClient is still connected or not
|
||||||
|
client.ConnectionClosed += (WebSocket socket) => Connected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task handleMessage(string frame)
|
private async Task handleMessage(string frame)
|
||||||
|
@ -107,7 +117,7 @@ namespace Nibriboard.Client
|
||||||
|
|
||||||
string handlerMethodName = "handle" + decodedMessage.GetType().Name;
|
string handlerMethodName = "handle" + decodedMessage.GetType().Name;
|
||||||
Type clientType = this.GetType();
|
Type clientType = this.GetType();
|
||||||
MethodInfo handlerInfo = clientType.GetMethod(handlerMethodName);
|
MethodInfo handlerInfo = clientType.GetMethod(handlerMethodName, BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
await (Task)handlerInfo.Invoke(this, new object[] { decodedMessage });
|
await (Task)handlerInfo.Invoke(this, new object[] { decodedMessage });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +139,10 @@ namespace Nibriboard.Client
|
||||||
/// <param name="message">The message to send.</param>
|
/// <param name="message">The message to send.</param>
|
||||||
public void SendRaw(string message)
|
public void SendRaw(string message)
|
||||||
{
|
{
|
||||||
client.Send(Encoding.UTF8.GetBytes(message));
|
if (!Connected)
|
||||||
|
throw new InvalidOperationException($"[NibriClient]{Id}] Can't send a message as the client has disconnected.");
|
||||||
|
|
||||||
|
client.Send(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -49,10 +49,16 @@ namespace Nibriboard.Client
|
||||||
public void Connected(WebSocket newSocket)
|
public void Connected(WebSocket newSocket)
|
||||||
{
|
{
|
||||||
NibriClient client = new NibriClient(this, newSocket);
|
NibriClient client = new NibriClient(this, newSocket);
|
||||||
|
client.Disconnected += handleDisconnection; // Clean up when the client disconnects
|
||||||
|
|
||||||
Clients.Add(client);
|
Clients.Add(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends a message to all the connected clients, except the one who's sending it.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sendingClient">The client sending the message.</param>
|
||||||
|
/// <param name="message">The message that is to bee sent.</param>
|
||||||
public void Broadcast(NibriClient sendingClient, Message message)
|
public void Broadcast(NibriClient sendingClient, Message message)
|
||||||
{
|
{
|
||||||
foreach(NibriClient client in Clients)
|
foreach(NibriClient client in Clients)
|
||||||
|
@ -64,5 +70,14 @@ namespace Nibriboard.Client
|
||||||
client.Send(message);
|
client.Send(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up after a client disconnects from the server.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disconnectedClient">The client that has disconnected.</param>
|
||||||
|
private void handleDisconnection(NibriClient disconnectedClient)
|
||||||
|
{
|
||||||
|
Clients.Remove(disconnectedClient);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,10 @@ class RippleLink extends EventEmitter$1
|
||||||
this.websocket.addEventListener("message", this.handleMessage.bind(this));
|
this.websocket.addEventListener("message", this.handleMessage.bind(this));
|
||||||
this.websocket.addEventListener("close", this.handleDisconnection.bind(this));
|
this.websocket.addEventListener("close", this.handleDisconnection.bind(this));
|
||||||
|
|
||||||
|
// Close the socket correctly
|
||||||
|
window.addEventListener("beforeunload", (function(event) {
|
||||||
|
this.websocket.close();
|
||||||
|
}).bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
handleConnection(event) {
|
handleConnection(event) {
|
||||||
|
|
|
@ -20,6 +20,10 @@ class RippleLink extends EventEmitter
|
||||||
this.websocket.addEventListener("message", this.handleMessage.bind(this));
|
this.websocket.addEventListener("message", this.handleMessage.bind(this));
|
||||||
this.websocket.addEventListener("close", this.handleDisconnection.bind(this));
|
this.websocket.addEventListener("close", this.handleDisconnection.bind(this));
|
||||||
|
|
||||||
|
// Close the socket correctly
|
||||||
|
window.addEventListener("beforeunload", (function(event) {
|
||||||
|
this.websocket.close();
|
||||||
|
}).bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
handleConnection(event) {
|
handleConnection(event) {
|
||||||
|
|
|
@ -77,8 +77,10 @@
|
||||||
<Compile Include="Client\Messages\CursorPositionMessage.cs" />
|
<Compile Include="Client\Messages\CursorPositionMessage.cs" />
|
||||||
<Compile Include="Client\Messages\ClientStateMessage.cs" />
|
<Compile Include="Client\Messages\ClientStateMessage.cs" />
|
||||||
<Compile Include="RippleSpace\ClientState.cs" />
|
<Compile Include="RippleSpace\ClientState.cs" />
|
||||||
<Compile Include="Utilities\JsonConverters\RectangleConverter.cs" />
|
|
||||||
<Compile Include="Utilities\JsonConverters\PointConverter.cs" />
|
<Compile Include="Utilities\JsonConverters\PointConverter.cs" />
|
||||||
|
<Compile Include="Utilities\JsonConverters\RectangleJsonConverter.cs" />
|
||||||
|
<Compile Include="Utilities\Rectangle.cs" />
|
||||||
|
<Compile Include="Utilities\Vector2.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="ClientFiles\index.html" />
|
<EmbeddedResource Include="ClientFiles\index.html" />
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
|
||||||
|
using SBRL.Utilities;
|
||||||
|
|
||||||
namespace RippleSpace
|
namespace RippleSpace
|
||||||
{
|
{
|
||||||
|
@ -26,11 +27,11 @@ namespace RippleSpace
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The size and position of the client's viewport.
|
/// The size and position of the client's viewport.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Rectangle Viewport = Rectangle.Empty;
|
public Rectangle Viewport = Rectangle.Zero;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The absolute position of the client's cursor.
|
/// The absolute position of the client's cursor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Point AbsCursorPosition = Point.Empty;
|
public Vector2 AbsCursorPosition = Vector2.Zero;
|
||||||
|
|
||||||
public ClientState()
|
public ClientState()
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,7 +4,7 @@ using System.Drawing;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Nibriboard.Utilities.JsonConverters
|
namespace SBRL.Utilities.JsonConverters
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deserialises objects into points from the System.Drawing namespace.
|
/// Deserialises objects into points from the System.Drawing namespace.
|
||||||
|
|
|
@ -4,12 +4,12 @@ using System.Drawing;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Nibriboard.Utilities.JsonConverters
|
namespace SBRL.Utilities.JsonConverters
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deserialises objects into rectangles from the System.Drawing namespace.
|
/// Deserialises objects into rectangles from the System.Drawing namespace.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class RectangleConverter : JsonConverter
|
public class RectangleJsonConverter : JsonConverter
|
||||||
{
|
{
|
||||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||||
{
|
{
|
115
Nibriboard/Utilities/Rectangle.cs
Normal file
115
Nibriboard/Utilities/Rectangle.cs
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace SBRL.Utilities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a rectangle in 2D space.
|
||||||
|
/// </summary>
|
||||||
|
public struct Rectangle
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A rectangle with all it's properties initialised to zero.
|
||||||
|
/// </summary>
|
||||||
|
public static Rectangle Zero = new Rectangle() { X = 0, Y = 0, Width = 0, Height = 0 };
|
||||||
|
|
||||||
|
#region Core Data
|
||||||
|
/// <summary>
|
||||||
|
/// The X coordinate of the rectangle.
|
||||||
|
/// </summary>
|
||||||
|
public int X { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// The Ycoordinateof the rectangle.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The y.</value>
|
||||||
|
public int Y { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// The width of the rectangle.
|
||||||
|
/// </summary>
|
||||||
|
public int Width { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// The height of the rectangle.
|
||||||
|
/// </summary>
|
||||||
|
public int Height { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Corners
|
||||||
|
/// <summary>
|
||||||
|
/// The top-left corner of the rectangle.
|
||||||
|
/// </summary>
|
||||||
|
public Point TopLeft {
|
||||||
|
get {
|
||||||
|
return new Point(X, Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// The top-right corner of the rectangle.
|
||||||
|
/// </summary>
|
||||||
|
public Point TopRight {
|
||||||
|
get {
|
||||||
|
return new Point(X + Width, Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// The bottom-left corner of the rectangle.
|
||||||
|
/// </summary>
|
||||||
|
public Point BottomLeft {
|
||||||
|
get {
|
||||||
|
return new Point(X, Y + Height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// The bottom-right corner of the rectangle.
|
||||||
|
/// </summary>
|
||||||
|
public Point BottomRight {
|
||||||
|
get {
|
||||||
|
return new Point(X + Width, Y + Height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Edges
|
||||||
|
/// <summary>
|
||||||
|
/// The Y coordinate of the top of the rectangle.
|
||||||
|
/// </summary>
|
||||||
|
public int Top {
|
||||||
|
get {
|
||||||
|
return Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// The Y coordinate of the bottom of the rectangle.
|
||||||
|
/// </summary>
|
||||||
|
public int Bottom {
|
||||||
|
get {
|
||||||
|
return Y + Width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// The X coordinate of the left side of the rectangle.
|
||||||
|
/// </summary>
|
||||||
|
public int Left {
|
||||||
|
get {
|
||||||
|
return X;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// The X coordinate of the right side of the rectangle.
|
||||||
|
/// </summary>
|
||||||
|
public int Right {
|
||||||
|
get {
|
||||||
|
return X + Width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public Rectangle(int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
Width = width;
|
||||||
|
Height = height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
63
Nibriboard/Utilities/Vector2.cs
Normal file
63
Nibriboard/Utilities/Vector2.cs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace SBRL.Utilities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a single point in 2D space.
|
||||||
|
/// May also be used to represent a direction with a magnitude.
|
||||||
|
/// </summary>
|
||||||
|
public struct Vector2
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A Vector 2 with all it's proeprties initialised to zero.
|
||||||
|
/// </summary>
|
||||||
|
public static Vector2 Zero = new Vector2() { X = 0, Y = 0 };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The X coordinate.
|
||||||
|
/// </summary>
|
||||||
|
public int X { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// The Y coordinate.
|
||||||
|
/// </summary>
|
||||||
|
public int Y { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public Vector2(int x, int y)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Vector2 Add(Vector2 b)
|
||||||
|
{
|
||||||
|
return new Vector2(
|
||||||
|
X + b.X,
|
||||||
|
Y + b.X
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public Vector2 Subtract(Vector2 b)
|
||||||
|
{
|
||||||
|
return new Vector2(
|
||||||
|
X - b.X,
|
||||||
|
Y - b.X
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public Vector2 Divide(int b)
|
||||||
|
{
|
||||||
|
return new Vector2(
|
||||||
|
X / b,
|
||||||
|
Y / b
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public Vector2 Multiply(int b)
|
||||||
|
{
|
||||||
|
return new Vector2(
|
||||||
|
X * b,
|
||||||
|
Y * b
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue