summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Drawable.cs8
-rw-r--r--Main.cs6
-rw-r--r--Mouse.cs23
-rw-r--r--MouseLocal.cs29
-rw-r--r--MouseNet.cs35
-rw-r--r--Net.cs5
-rw-r--r--NetClient.cs16
-rw-r--r--NetServer.cs65
-rw-r--r--Oneko.cs18
-rw-r--r--OnekoLocal.cs6
-rw-r--r--OnekoNet.cs4
11 files changed, 135 insertions, 80 deletions
diff --git a/Drawable.cs b/Drawable.cs
index 0f74a1c..f01c478 100644
--- a/Drawable.cs
+++ b/Drawable.cs
@@ -6,6 +6,7 @@ namespace OnekoOnline;
abstract class Drawable : IDisposable
{
protected int DrawOrder = 0;
+ public bool Visible = true;
public Vector2 Position {
get => _position;
@@ -16,13 +17,16 @@ abstract class Drawable : IDisposable
public Vector2 Size;
public float Rotation = 0f;
- public static readonly List<Drawable> Drawables = [];
+ public static readonly HashSet<Drawable> Drawables = [];
+
+ public Drawable() => Drawables.Add(this);
public static void DrawAll()
{
float delta = Raylib.GetFrameTime();
foreach (Drawable drawable in Drawables.OrderBy(d => d.Position.Y + d.DrawOrder*1000)) {
drawable?.Update(delta);
+ if (drawable == null || !drawable.Visible) continue;
drawable?.Draw();
}
}
@@ -36,5 +40,5 @@ abstract class Drawable : IDisposable
public abstract void Update(float delta);
- public abstract void Dispose();
+ public virtual void Dispose() => Drawables.Remove(this);
} \ No newline at end of file
diff --git a/Main.cs b/Main.cs
index 0194169..79db391 100644
--- a/Main.cs
+++ b/Main.cs
@@ -28,7 +28,7 @@ static class OnekoOnline
Raylib.HideCursor();
OnekoLocal LocalOneko = new();
- Mouse LocalMouse = new();
+ MouseLocal LocalMouse = new();
RenderTexture2D RenderTexture = Raylib.LoadRenderTexture(WindowX, WindowY);
@@ -53,8 +53,8 @@ static class OnekoOnline
Raylib.BeginTextureMode(RenderTexture);
Raylib.ClearBackground(Color.GRAY);
- Raylib.DrawTextEx(DefaultFont, "こんにちは", new(32,32), 11, 0, Color.WHITE);
- Raylib.DrawText("Oneko Online", 12, 12, 8, Color.WHITE);
+ Raylib.DrawTextEx(DefaultFont, "こんにちは", new(17,18), 11, 0, Color.WHITE);
+ Raylib.DrawText("Oneko Online", 10, 9, 8, Color.WHITE);
Drawable.DrawAll();
diff --git a/Mouse.cs b/Mouse.cs
index bec6eec..d316ea2 100644
--- a/Mouse.cs
+++ b/Mouse.cs
@@ -1,32 +1,33 @@
-using System.Numerics;
-using OnekoOnline.Net;
using Raylib_cs;
+using System.Collections.ObjectModel;
+using System.Numerics;
namespace OnekoOnline;
-class Mouse : Drawable
+abstract class Mouse : Drawable
{
+ public string Name = "Mouse";
+
Texture2D CursorTex = Raylib.LoadTexture("misc/cursor.png");
- public Mouse()
- {
- DrawOrder = 100;
- Drawables.Add(this);
- }
+ protected static List<Mouse> allMice = [];
+ public static ReadOnlyCollection<Mouse> AllMice => allMice.AsReadOnly();
- public override void Update(float delta)
+ public Mouse() : base()
{
- Position = Raylib.GetMousePosition()/OnekoOnline.WindowScale;
+ DrawOrder = 100;
+ allMice.Add(this);
}
public override void Draw()
{
- if (Raylib.IsCursorOnScreen())
Raylib.DrawTexture(CursorTex, (int)Position.X, (int)Position.Y, Color.WHITE);
}
public override void Dispose()
{
Raylib.UnloadTexture(CursorTex);
+ allMice.Remove(this);
+ base.Dispose();
}
} \ No newline at end of file
diff --git a/MouseLocal.cs b/MouseLocal.cs
new file mode 100644
index 0000000..6a84731
--- /dev/null
+++ b/MouseLocal.cs
@@ -0,0 +1,29 @@
+using System.Numerics;
+using OnekoOnline.Net;
+using LiteNetLib.Utils;
+using Raylib_cs;
+
+namespace OnekoOnline;
+
+class MouseLocal : Mouse
+{
+ public MouseLocal() : base()
+ {
+ Client.UserConnected += user => {
+ MouseNet NewNetMouse = new(user);
+ };
+ }
+
+ public override void Update(float delta)
+ {
+ Visible = Raylib.IsCursorOnScreen() && Raylib.IsWindowFocused();
+ Position = Raylib.GetMousePosition()/OnekoOnline.WindowScale;
+
+ if (Visible && OnekoOnline.Client!.Connected) {
+ NetDataWriter writer = new();
+ writer.Put(new PacketInfo(PacketType.MousePosition, OnekoOnline.Client.Id));
+ writer.Put(Position);
+ OnekoOnline.Client?.ConnectedServer.Send(writer, LiteNetLib.DeliveryMethod.Unreliable);
+ }
+ }
+} \ No newline at end of file
diff --git a/MouseNet.cs b/MouseNet.cs
new file mode 100644
index 0000000..9521a25
--- /dev/null
+++ b/MouseNet.cs
@@ -0,0 +1,35 @@
+using OnekoOnline.Net;
+
+namespace OnekoOnline;
+
+class MouseNet : Mouse
+{
+ readonly User MyUser;
+
+ float InvisibleTimer;
+
+ public MouseNet(User user) : base()
+ {
+ MyUser = user;
+ Name = user.Username!;
+
+ Client.UserDisconnected += disconnectedUser => {
+ if (disconnectedUser == MyUser) Dispose();
+ };
+
+ Client.PacketRecived += (reader, user, packetType) => {
+ if (user != MyUser || packetType != PacketType.MousePosition) return;
+
+ Position = reader.GetVector2();
+ InvisibleTimer = 0f;
+ };
+
+ Client.ServerDisconnected += Dispose;
+ }
+
+ public override void Update(float delta)
+ {
+ InvisibleTimer += delta;
+ Visible = InvisibleTimer < 0.3f;
+ }
+} \ No newline at end of file
diff --git a/Net.cs b/Net.cs
index 83b6b26..3fa5f8a 100644
--- a/Net.cs
+++ b/Net.cs
@@ -52,8 +52,7 @@ public enum PacketType : byte
{
MousePosition,
OnekoTargetPosition,
- OnekoSpritesheet,
- Username,
+ UserInfo,
UserId,
Disconnect,
Invalid
@@ -103,6 +102,4 @@ class User(int id)
//Oneko Stuff
public byte[]? SpriteSheet;
public string? Username;
-
- public bool ExchangedData => SpriteSheet != null && Username != null;
} \ No newline at end of file
diff --git a/NetClient.cs b/NetClient.cs
index ce7d8fe..da287df 100644
--- a/NetClient.cs
+++ b/NetClient.cs
@@ -36,12 +36,9 @@ class Client
Console.WriteLine("Connected to the Server!");
NetDataWriter writer = new();
- writer.Put(new PacketInfo(PacketType.OnekoSpritesheet, Id));
- writer.Put(OnekoLocal.Instance!.SpriteSheet.Serialize());
- peer.Send(writer, DeliveryMethod.ReliableUnordered);
-
- writer.ResetWithInfo(new PacketInfo(PacketType.Username, Id));
+ writer.Put(new PacketInfo(PacketType.UserInfo, Id));
writer.Put(UserName);
+ writer.PutBytesWithLength(OnekoLocal.Instance!.SpriteSheet.Serialize());
peer.Send(writer, DeliveryMethod.ReliableUnordered);
};
@@ -74,14 +71,13 @@ class Client
return;
}
- else if (info.Type == PacketType.OnekoSpritesheet) from.SpriteSheet = reader.GetRemainingBytes();
- else if (info.Type == PacketType.Username) from.Username = reader.GetString();
-
- if (from.ExchangedData && !from.Initialized) {
- //Announce user connection
+ else if (info.Type == PacketType.UserInfo) {
+ from.Username = reader.GetString();
+ from.SpriteSheet = reader.GetBytesWithLength();
Console.WriteLine($"User {from.Username} joined!");
from.Initialized = true;
UserConnected?.Invoke(from);
+ return;
}
NetDataReader newReader = new(reader.GetRemainingBytes());
diff --git a/NetServer.cs b/NetServer.cs
index c2c626a..5ff35f1 100644
--- a/NetServer.cs
+++ b/NetServer.cs
@@ -45,44 +45,41 @@ class Server
ServerUser user = users[fromPeer.Id];
//Size limits for packet types
- if (info.Type == PacketType.OnekoSpritesheet && dataReader.AvailableBytes > 30000) return;
- else if (info.Type != PacketType.OnekoSpritesheet && dataReader.AvailableBytes > 500) return;
-
- if (info.Type == PacketType.OnekoSpritesheet) user.SpriteSheet = dataReader.GetRemainingBytes();
- else if (info.Type == PacketType.Username) user.Username = dataReader.GetString(64);
+ if (info.Type == PacketType.UserInfo && dataReader.AvailableBytes > 40000) return;
+ else if (info.Type != PacketType.UserInfo && dataReader.AvailableBytes > 500) return;
NetDataWriter writer = new();
- if (user.ExchangedData && !user.Initialized) {
- //Send ID
- writer.ResetWithInfo(new PacketInfo(PacketType.UserId, -1));
- writer.Put(user.Id);
- fromPeer.Send(writer, DeliveryMethod.ReliableUnordered);
- user.Initialized = true;
-
- Console.WriteLine($"{fromPeer.EndPoint} is {user.Username}!");
+ if (info.Type == PacketType.UserInfo) {
+ user.Username = dataReader.GetString();
+ if (user.Username.Length > 40) user.Username = user.Username[0..40]; //Clamp username length
+ user.SpriteSheet = dataReader.GetBytesWithLength();
- foreach (ServerUser toSend in users.Values)
- {
- if (!toSend.ExchangedData || toSend == user) continue;
-
- //Send all current users spritesheets to this user.
- writer.ResetWithInfo(new PacketInfo(PacketType.OnekoSpritesheet, toSend.Id), toSend.SpriteSheet!.Length);
- writer.Put(toSend.SpriteSheet);
+ if (!user.Initialized) {
+ //Send ID
+ writer.ResetWithInfo(new PacketInfo(PacketType.UserId, -1));
+ writer.Put(user.Id);
fromPeer.Send(writer, DeliveryMethod.ReliableUnordered);
-
- writer.ResetWithInfo(new PacketInfo(PacketType.Username, toSend.Id));
- writer.Put(toSend.Username);
- fromPeer.Send(writer, DeliveryMethod.ReliableUnordered);
-
- //Send all current users this users spritesheet
- writer.ResetWithInfo(new PacketInfo(PacketType.OnekoSpritesheet, user.Id), user.SpriteSheet!.Length);
- writer.Put(user.SpriteSheet);
- toSend.Peer.Send(writer, DeliveryMethod.ReliableUnordered);
-
- writer.ResetWithInfo(new PacketInfo(PacketType.Username, user.Id));
- writer.Put(user.Username);
- toSend.Peer.Send(writer, DeliveryMethod.ReliableUnordered);
+ user.Initialized = true;
+
+ Console.WriteLine($"{fromPeer.EndPoint} is {user.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.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.PutBytesWithLength(user.SpriteSheet);
+ toSend.Peer.Send(writer, DeliveryMethod.ReliableUnordered);
+ }
}
}
@@ -90,7 +87,7 @@ class Server
writer.ResetWithInfo(new PacketInfo(info.Type, fromPeer.Id));
writer.Put(dataReader.GetRemainingBytes());
foreach (ServerUser toSend in users.Values) {
- if (!toSend.ExchangedData || toSend == user) continue;
+ if (!toSend.Initialized || toSend == user) continue;
toSend.Peer.Send(writer, DeliveryMethod);
}
}
diff --git a/Oneko.cs b/Oneko.cs
index 361a6e2..742d8c0 100644
--- a/Oneko.cs
+++ b/Oneko.cs
@@ -19,7 +19,7 @@ class Oneko : Drawable
public string Name = "Oneko";
- public Oneko()
+ public Oneko() : base()
{
Size = new(32,32);
Position = new(320/2, 240/2);
@@ -32,27 +32,21 @@ class Oneko : Drawable
Console.WriteLine("Path to spritesheet was invalid, using the default.");
SpriteSheet = Bitmap.FromPNGMemory(EmbeddedResources.GetResource("nekos.oneko.png"));
}
-
- Drawables.Add(this);
}
- public Oneko(Bitmap spriteSheet)
+ public Oneko(Bitmap spriteSheet) : base()
{
Size = new(32,32);
Position = new(0, 0);
SpriteSheet = spriteSheet;
-
- Drawables.Add(this);
}
public override void Draw()
{
//Nametag
- if (Vector2.Distance(Raylib.GetMousePosition()/OnekoOnline.WindowScale, Position) < 20f) {
- Vector2 NametagPosition = new(Position.X-(Name.Length*3)+4, Position.Y-28);
- Raylib.DrawTextEx(OnekoOnline.DefaultFont, Name, NametagPosition+Directions.Down, 11, 0, Color.BLACK); //Shadow
- Raylib.DrawTextEx(OnekoOnline.DefaultFont, Name, NametagPosition, 11, 0, Color.WHITE);
- }
+ Vector2 NametagPosition = new(Position.X-(Name.Length*3)+4, Position.Y-28);
+ Raylib.DrawTextEx(OnekoOnline.DefaultFont, Name, NametagPosition+Directions.Down, 11, 0, Color.BLACK); //Shadow
+ Raylib.DrawTextEx(OnekoOnline.DefaultFont, Name, NametagPosition, 11, 0, Color.WHITE);
//The neko
Raylib.DrawTexturePro(SpriteSheet.Texture, Animation.GetFrame(Frame), new Rectangle(Position.X, Position.Y, Size.X, Size.Y), Size/2, Rotation, Color.WHITE);
@@ -88,7 +82,7 @@ class Oneko : Drawable
public override void Dispose()
{
SpriteSheet.Dispose();
- Drawables.Remove(this);
+ base.Dispose();
}
struct OnekoAnimation(Rectangle frame1, Rectangle frame2)
diff --git a/OnekoLocal.cs b/OnekoLocal.cs
index b33f376..00eaf82 100644
--- a/OnekoLocal.cs
+++ b/OnekoLocal.cs
@@ -16,15 +16,15 @@ class OnekoLocal : Oneko
Instance ??= this;
Client.UserConnected += OnekoNet.SpawnNetNeko;
- Client.ServerDisconnected += OnekoNet.DisconnectAll;
Name = Client.UserName;
}
public override void OnekoUpdate()
{
- if (Raylib.IsWindowFocused() && Raylib.IsCursorOnScreen()) TargetPosition = Raylib.GetMousePosition()/OnekoOnline.WindowScale;
- else TargetPosition = new Vector2(320/2, 240/2);
+ Mouse? NearestMouse = Mouse.AllMice.Where(m => m.Visible).MinBy(m => Vector2.Distance(m.Position, Position));
+ if (NearestMouse != null) TargetPosition = NearestMouse.Position;
+ else TargetPosition = new Vector2(Math.Clamp((Id+1)*40, 20, 300), 240/2);
if (OnekoOnline.Client!.Connected) {
NetDataWriter writer = new();
diff --git a/OnekoNet.cs b/OnekoNet.cs
index b7cd595..27d6187 100644
--- a/OnekoNet.cs
+++ b/OnekoNet.cs
@@ -24,11 +24,13 @@ class OnekoNet : Oneko
if (packetType == PacketType.OnekoTargetPosition) TargetPosition = reader.GetVector2();
};
+
+ Client.ServerDisconnected += Dispose;
}
public static void SpawnNetNeko(User user)
{
- if (user.ExchangedData && !NetNekos.ContainsKey(user.Id)) {
+ if (!NetNekos.ContainsKey(user.Id)) {
Bitmap spriteSheet = Bitmap.Deserialize(user.SpriteSheet);
NetNekos.Add(user.Id, new OnekoNet(spriteSheet, user));
}