summaryrefslogtreecommitdiff
path: root/NetServer.cs
blob: f275164a35f6d8bbc7e6b9e48a8d0368ca1cb55a (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
113
114
115
116
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.UserInfo && dataReader.AvailableBytes > 40000) return;
            else if (info.Type != PacketType.UserInfo && dataReader.AvailableBytes > 500) return;

            NetDataWriter writer = new();

            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));
                    writer.Put(user.Id);
                    fromPeer.Send(writer, DeliveryMethod.ReliableUnordered);
                    user.Initialized = true;

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

                    foreach (ServerUser toSend in users.Values)
                    {
                        if (!toSend.Initialized || toSend == user) continue;

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

            if (info.Type == PacketType.OnekoState || info.Type == PacketType.MouseState) {
                writer.ResetWithInfo(new PacketInfo(info.Type, fromPeer.Id));
                writer.Put(dataReader.GetRemainingBytes());
                foreach (ServerUser toSend in users.Values) {
                    if (!toSend.Initialized || toSend == user) continue;
                    toSend.Peer.Send(writer, DeliveryMethod);
                }
            }
        };

        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 byte[]? UserInfo;

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