From ff3cbc5b49f8618531c5778d69b49c0aa4a9442a Mon Sep 17 00:00:00 2001 From: Sarah B Date: Mon, 25 Dec 2023 00:02:12 -0800 Subject: Changed how server handles UserInfo, and started work on networking the cursor's sprite. --- Extensions.cs | 40 ++++++++++++++++++++++++++++++++++++++++ MathExtensions.cs | 31 ------------------------------- Mouse.cs | 22 +++++++++++++++++++--- MouseLocal.cs | 4 +--- MouseNet.cs | 8 +++++++- Net.cs | 7 +------ NetClient.cs | 35 +++++++++++++++++++++++------------ NetServer.cs | 33 +++++++++++++-------------------- Oneko.cs | 2 +- OnekoNet.cs | 4 ++-- OnekoOnline.csproj | 3 ++- 11 files changed, 109 insertions(+), 80 deletions(-) create mode 100644 Extensions.cs delete mode 100644 MathExtensions.cs diff --git a/Extensions.cs b/Extensions.cs new file mode 100644 index 0000000..e6368c3 --- /dev/null +++ b/Extensions.cs @@ -0,0 +1,40 @@ +using System.Numerics; + +namespace OnekoOnline; + +static class MathExtensions +{ + public static Vector2 LimitLength(this Vector2 toLimit, float lengthLimit) + { + float length = toLimit.Length(); + if (toLimit == Vector2.Zero) return Vector2.Zero; + return Vector2.Normalize(toLimit) * MathF.Min(length, lengthLimit); + } + + public static Vector2 Round(this Vector2 toRound) + { + return new(MathF.Round(toRound.X), MathF.Round(toRound.Y)); + } +} + +static class StringExtensions +{ + public static string LimitLength(this string value, int maxLength) + { + if (string.IsNullOrEmpty(value)) return value; + return value.Length <= maxLength ? value : value[..maxLength]; + } +} + +public static class Directions +{ + public static readonly Vector2 Up = new(0,-1); + public static readonly Vector2 Down = new(0,1); + public static readonly Vector2 Left = new(-1,0); + public static readonly Vector2 Right = new(1,0); + + public static readonly Vector2 UpLeft = Vector2.Normalize(Up+Left); + public static readonly Vector2 UpRight = Vector2.Normalize(Up+Right); + public static readonly Vector2 DownLeft = Vector2.Normalize(Down+Left); + public static readonly Vector2 DownRight = Vector2.Normalize(Down+Right); +} \ No newline at end of file diff --git a/MathExtensions.cs b/MathExtensions.cs deleted file mode 100644 index 2e74442..0000000 --- a/MathExtensions.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Numerics; - -namespace OnekoOnline; - -static class MathExtensions -{ - public static Vector2 LimitLength(this Vector2 toLimit, float lengthLimit) - { - float length = toLimit.Length(); - if (toLimit == Vector2.Zero) return Vector2.Zero; - return Vector2.Normalize(toLimit) * MathF.Min(length, lengthLimit); - } - - public static Vector2 Round(this Vector2 toRound) - { - return new(MathF.Round(toRound.X), MathF.Round(toRound.Y)); - } -} - -public static class Directions -{ - public static readonly Vector2 Up = new(0,-1); - public static readonly Vector2 Down = new(0,1); - public static readonly Vector2 Left = new(-1,0); - public static readonly Vector2 Right = new(1,0); - - public static readonly Vector2 UpLeft = Vector2.Normalize(Up+Left); - public static readonly Vector2 UpRight = Vector2.Normalize(Up+Right); - public static readonly Vector2 DownLeft = Vector2.Normalize(Down+Left); - public static readonly Vector2 DownRight = Vector2.Normalize(Down+Right); -} \ No newline at end of file diff --git a/Mouse.cs b/Mouse.cs index a23d784..fad056e 100644 --- a/Mouse.cs +++ b/Mouse.cs @@ -8,7 +8,7 @@ abstract class Mouse : Drawable { public string Name = "Mouse"; - Texture2D CursorTex = Raylib.LoadTexture("misc/cursor.png"); + public Bitmap Cursor; protected static List allMice = []; public static ReadOnlyCollection AllMice => allMice.AsReadOnly(); @@ -19,6 +19,22 @@ abstract class Mouse : Drawable { DrawOrder = 100; allMice.Add(this); + + string CursorPath = "mddisc/cursor.png"; + + if (File.Exists(CursorPath) && new FileInfo(CursorPath).Length < 12*19*3) { + Cursor = Bitmap.FromPNGMemory(File.ReadAllBytes(CursorPath)); + } else { + Console.WriteLine("Path to cursor png was invalid or the file was too big, using the default."); + Cursor = Bitmap.FromPNGMemory(EmbeddedResources.GetResource("misc.cursor.png")); + } + } + + public Mouse(Bitmap cursor) : base() + { + DrawOrder = 100; + allMice.Add(this); + Cursor = cursor; } public override void Draw() @@ -27,12 +43,12 @@ abstract class Mouse : Drawable Raylib.DrawTextEx(OnekoOnline.DefaultFont, Name, NametagPosition+Directions.Down, 11, 0, Color.BLACK); //Shadow Raylib.DrawTextEx(OnekoOnline.DefaultFont, Name, NametagPosition, 11, 0, Color.WHITE); - Raylib.DrawTexture(CursorTex, (int)Position.X, (int)Position.Y, Color.WHITE); + Raylib.DrawTexture(Cursor.Texture, (int)Position.X, (int)Position.Y, Color.WHITE); } public override void Dispose() { - Raylib.UnloadTexture(CursorTex); + Cursor.Dispose(); allMice.Remove(this); base.Dispose(); } diff --git a/MouseLocal.cs b/MouseLocal.cs index 2b36ff3..a731ffb 100644 --- a/MouseLocal.cs +++ b/MouseLocal.cs @@ -9,9 +9,7 @@ class MouseLocal : Mouse { public MouseLocal() : base() { - Client.UserConnected += user => { - MouseNet NewNetMouse = new(user); - }; + Client.UserConnected += MouseNet.SpawnNetMouse; Name = Client.UserName; } diff --git a/MouseNet.cs b/MouseNet.cs index 1588dd0..bb2987b 100644 --- a/MouseNet.cs +++ b/MouseNet.cs @@ -8,7 +8,7 @@ class MouseNet : Mouse float InvisibleTimer; - public MouseNet(User user) : base() + MouseNet(ClientUser user, Bitmap cursor) : base(cursor) { MyUser = user; Name = user.Username!; @@ -34,4 +34,10 @@ class MouseNet : Mouse InvisibleTimer += delta; Visible = InvisibleTimer < 0.3f; } + + public static void SpawnNetMouse(ClientUser user) + { + Bitmap cursor = Bitmap.Deserialize(user.CursorSprite); + MouseNet NewMouse = new(user, cursor); + } } \ No newline at end of file diff --git a/Net.cs b/Net.cs index 8384482..8ade4e8 100644 --- a/Net.cs +++ b/Net.cs @@ -88,13 +88,8 @@ public struct PacketInfo(PacketType type, int id) } } -class User(int id) +abstract class User(int id) { public readonly int Id = id; public bool Initialized = false; - - //Oneko Stuff - public byte[]? SpriteSheet; - public string? Username; - public string? Nekoname; } \ No newline at end of file diff --git a/NetClient.cs b/NetClient.cs index 492c459..804be86 100644 --- a/NetClient.cs +++ b/NetClient.cs @@ -14,12 +14,12 @@ class Client readonly NetManager NetClient; public NetPeer ConnectedServer => NetClient.FirstPeer; - readonly Dictionary users = []; - public ReadOnlyDictionary Users => users.AsReadOnly(); + readonly Dictionary users = []; + public ReadOnlyDictionary Users => users.AsReadOnly(); - static public Action? UserConnected; - static public Action? UserDisconnected; - static public Action? PacketRecived; + static public Action? UserConnected; + static public Action? UserDisconnected; + static public Action? PacketRecived; static public Action? ServerDisconnected; public Client(string ServerAddress, int port, string ServerPassword) @@ -37,9 +37,10 @@ class Client NetDataWriter writer = new(); writer.Put(new PacketInfo(PacketType.UserInfo, Id)); - writer.Put(UserName); - writer.Put(OnekoLocal.Instance!.Name); + writer.Put(UserName.LimitLength(40)); + writer.Put(OnekoLocal.Instance!.Name.LimitLength(40)); writer.PutBytesWithLength(OnekoLocal.Instance!.SpriteSheet.Serialize()); + //TODO: NETWORK THE CURSOR HERE peer.Send(writer, DeliveryMethod.ReliableUnordered); }; @@ -50,7 +51,7 @@ class Client }; Listener.NetworkReceiveEvent += (fromPeer, reader, channel, DeliveryMethod) => { - if (reader.AvailableBytes < PacketInfo.SizeOf) return; + if (reader.AvailableBytes < PacketInfo.SizeOf || reader.AvailableBytes > 40000) return; PacketInfo info = reader.GetPacketInfo(); if (info.Type == PacketType.UserId) { @@ -58,7 +59,7 @@ class Client return; } - User? from; + ClientUser? from; if (!users.TryGetValue(info.FromId, out from)) { from = new(info.FromId); users.Add(from.Id, from); @@ -73,15 +74,17 @@ class Client } else if (info.Type == PacketType.UserInfo) { - from.Username = reader.GetString(); - from.Nekoname = reader.GetString(); + from.Username = reader.GetString().LimitLength(40); + from.Nekoname = reader.GetString().LimitLength(40); from.SpriteSheet = reader.GetBytesWithLength(); - Console.WriteLine($"User {from.Username} joined!"); + Console.WriteLine($"User {from.Username} joined with {from.Nekoname}!"); from.Initialized = true; UserConnected?.Invoke(from); return; } + if (reader.AvailableBytes > 500) return; + NetDataReader newReader = new(reader.GetRemainingBytes()); PacketRecived?.Invoke(newReader, from, info.Type); }; @@ -96,4 +99,12 @@ class Client { NetClient.DisconnectAll(); } +} + +class ClientUser(int id) : User(id) +{ + public byte[]? SpriteSheet; + public byte[]? CursorSprite; + public string? Username; + public string? Nekoname; } \ No newline at end of file diff --git a/NetServer.cs b/NetServer.cs index 875ddfd..f275164 100644 --- a/NetServer.cs +++ b/NetServer.cs @@ -50,13 +50,13 @@ class Server NetDataWriter writer = new(); - if (info.Type == PacketType.UserInfo) { - user.Username = dataReader.GetString(); - if (user.Username.Length > 40) user.Username = user.Username[0..40]; //Clamp username length - user.Nekoname = dataReader.GetString(); - if (user.Nekoname.Length > 40) user.Nekoname = user.Nekoname[0..40]; //Clamp nekoname length - user.SpriteSheet = dataReader.GetBytesWithLength(); + if (info.Type == PacketType.UserInfo) + { + user.UserInfo = dataReader.RawData; + new PacketInfo(PacketType.UserInfo, user.Id).Serialize(user.UserInfo); + string Username = dataReader.GetString().LimitLength(40); + if (!user.Initialized) { //Send ID writer.ResetWithInfo(new PacketInfo(PacketType.UserId, -1)); @@ -64,25 +64,17 @@ class Server fromPeer.Send(writer, DeliveryMethod.ReliableUnordered); user.Initialized = true; - Console.WriteLine($"{fromPeer.EndPoint} is {user.Username}!"); + Console.WriteLine($"{fromPeer.EndPoint} is {Username}!"); foreach (ServerUser toSend in users.Values) { if (!toSend.Initialized || toSend == user) continue; - //Send all current users spritesheets to this user. - writer.ResetWithInfo(new PacketInfo(PacketType.UserInfo, toSend.Id)); - writer.Put(toSend.Username); - writer.Put(toSend.Nekoname); - writer.PutBytesWithLength(toSend.SpriteSheet); - fromPeer.Send(writer, DeliveryMethod.ReliableUnordered); - - //Send all current users this users spritesheet - writer.ResetWithInfo(new PacketInfo(PacketType.UserInfo, user.Id)); - writer.Put(user.Username); - writer.Put(user.Nekoname); - writer.PutBytesWithLength(user.SpriteSheet); - toSend.Peer.Send(writer, DeliveryMethod.ReliableUnordered); + //Send all current users info to the new user. + fromPeer.Send(toSend.UserInfo, DeliveryMethod.ReliableUnordered); + + //Send all previous users this new users info + toSend.Peer.Send(user.UserInfo, DeliveryMethod.ReliableUnordered); } } } @@ -115,6 +107,7 @@ class ServerUser(int id, NetPeer peer) : User(id), IDisposable { //Network public readonly NetPeer Peer = peer; + public byte[]? UserInfo; public void Dispose() { diff --git a/Oneko.cs b/Oneko.cs index 31652ed..7a1e3ac 100644 --- a/Oneko.cs +++ b/Oneko.cs @@ -27,7 +27,7 @@ abstract class Oneko : Drawable if (File.Exists(SpriteSheetPath) && new FileInfo(SpriteSheetPath).Length < 128*256*3) { SpriteSheet = Bitmap.FromPNGMemory(File.ReadAllBytes(SpriteSheetPath)); } else { - Console.WriteLine("Path to spritesheet was invalid, using the default."); + Console.WriteLine("Path to spritesheet was invalid or the file was too big, using the default."); SpriteSheet = Bitmap.FromPNGMemory(EmbeddedResources.GetResource("nekos.oneko.png")); } } diff --git a/OnekoNet.cs b/OnekoNet.cs index d01bff3..ee780c6 100644 --- a/OnekoNet.cs +++ b/OnekoNet.cs @@ -12,7 +12,7 @@ class OnekoNet : Oneko float NetworkIssueTimer = 0f; - public OnekoNet(Bitmap bitmap, User user) : base(bitmap) + public OnekoNet(Bitmap bitmap, ClientUser user) : base(bitmap) { MyUser = user; Name = user.Nekoname!; @@ -41,7 +41,7 @@ class OnekoNet : Oneko else ColorTint = Color.WHITE with {A = 120}; } - public static void SpawnNetNeko(User user) + public static void SpawnNetNeko(ClientUser user) { if (!NetNekos.ContainsKey(user.Id)) { Bitmap spriteSheet = Bitmap.Deserialize(user.SpriteSheet); diff --git a/OnekoOnline.csproj b/OnekoOnline.csproj index 1d88aa6..8559b1b 100644 --- a/OnekoOnline.csproj +++ b/OnekoOnline.csproj @@ -8,7 +8,7 @@ enable enable true - false + true @@ -17,6 +17,7 @@ + -- cgit