summaryrefslogtreecommitdiff
path: root/NetServer.cs
blob: a0910ba7ebf2193e15d6056c8b9e0dfadecde150 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
using LiteNetLib;
using LiteNetLib.Utils;

namespace OnekoOnline.Net;

class Server
{
    public static bool ServerRunning = false;

    readonly Dictionary<int, ServerUser> users = [];
    readonly EventBasedNetListener Listener;
    readonly NetManager NetServer;

    public Server(int Port, int MaxConnections, string ServerPassword = "")
    {
        Listener = new();
        NetServer = new(Listener);
        ServerRunning = NetServer.Start(Port);

        if (!ServerRunning) return;

        Listener.ConnectionRequestEvent += request => {
            if (NetServer.ConnectedPeersCount < MaxConnections) request.AcceptIfKey(ServerPassword);
            else request.Reject();
        };

        Listener.PeerConnectedEvent += peer => {
            Console.WriteLine($"New connection from {peer.EndPoint}!");
            users.Add(peer.Id, new ServerUser(peer.Id, peer));
        };

        Listener.PeerDisconnectedEvent += (peer, info) => {
            Console.WriteLine($"{peer.EndPoint} Disconnected! Reason: {info.Reason}");
            users.Remove(peer.Id);

            NetDataWriter writer = new();
            //Send all users a disconnect message
            foreach (ServerUser user in users.Values) {
                user.Peer.Send(new PacketInfo(PacketType.Disconnect, peer.Id).Serialize(), DeliveryMethod.ReliableUnordered);
            }
        };

        Listener.NetworkReceiveEvent += (fromPeer, dataReader, channel, DeliveryMethod) => {
            PacketInfo info = dataReader.GetPacketInfo();
            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 (user.ExchangedData && !user.sentId) {
                NetDataWriter writer = new();
                //Send ID
                writer.Put(user.Id);
                fromPeer.Send(writer, DeliveryMethod.ReliableUnordered);
                user.sentId = true;

                Console.WriteLine($"{fromPeer.EndPoint} is {user.Username}!");

                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);
                    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);
                }
            }
        };

        Console.WriteLine("Server Initialized!");
    }

    public void Poll()
    {
        NetServer.PollEvents();
    }

    public void Disconnect()
    {
        NetServer.DisconnectAll();
    }
}

class ServerUser(int id, NetPeer peer) : User(id), IDisposable
{
    //Network
    public readonly NetPeer Peer = peer;
    public bool sentId = false;

    public void Dispose()
    {
        Peer.Disconnect();
    }
}