forked from FICTURE7/CoCSharp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCoCServer.cs
118 lines (101 loc) · 3.78 KB
/
CoCServer.cs
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
117
118
using CoCSharp.Networking;
using CoCSharp.Server.Core;
using CoCSharp.Server.Handlers;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
namespace CoCSharp.Server
{
public class CoCServer
{
public CoCServer()
{
_settings = new NetworkManagerAsyncSettings(50, 50);
_listener = new Socket(SocketType.Stream, ProtocolType.Tcp);
_acceptPool = new SocketAsyncEventArgsPool(100);
AvatarManager = new AvatarManager();
DataManager = new DataManager();
Clients = new List<CoCRemoteClient>();
MessageHandlers = new Dictionary<ushort, MessageHandler>();
CommandHandlers = new Dictionary<int, CommandHandler>();
LoginMessageHandlers.RegisterLoginMessageHandlers(this);
InGameMessageHandlers.RegisterInGameMessageHandlers(this);
BuildingCommandHandlers.RegisterBuildingCommandHandlers(this);
AvatarManager.LoadAllAvatars();
}
public AvatarManager AvatarManager { get; private set; }
public DataManager DataManager { get; private set; }
public Dictionary<int, CommandHandler> CommandHandlers { get; private set; }
public Dictionary<ushort, MessageHandler> MessageHandlers { get; private set; }
public List<CoCRemoteClient> Clients { get; private set; }
private readonly Socket _listener;
private readonly SocketAsyncEventArgsPool _acceptPool;
private readonly NetworkManagerAsyncSettings _settings;
public void Start()
{
_listener.Bind(new IPEndPoint(IPAddress.Any, 9339));
_listener.Listen(100);
StartAccept();
}
public void RegisterMessageHandler(Message message, MessageHandler handler)
{
MessageHandlers.Add(message.ID, handler);
}
public void RegisterCommandHandler(Command command, CommandHandler handler)
{
CommandHandlers.Add(command.ID, handler);
}
private void StartAccept()
{
var acceptArgs = (SocketAsyncEventArgs)null;
if (_acceptPool.Count > 1)
{
try
{
acceptArgs = _acceptPool.Pop();
acceptArgs.Completed += AcceptOperationCompleted;
}
catch
{
acceptArgs = CreateNewAcceptArgs();
}
}
else
{
acceptArgs = CreateNewAcceptArgs();
}
if (!_listener.AcceptAsync(acceptArgs))
ProcessAccept(acceptArgs);
}
private SocketAsyncEventArgs CreateNewAcceptArgs()
{
var args = new SocketAsyncEventArgs();
args.Completed += AcceptOperationCompleted;
return args;
}
private void ProcessAccept(SocketAsyncEventArgs args)
{
args.Completed -= AcceptOperationCompleted;
if (args.SocketError != SocketError.Success)
{
StartAccept(); // start accept asap
ProcessBadAccept(args);
}
StartAccept(); // start accept asap
Console.WriteLine("Accepted new connection: {0}", args.AcceptSocket.RemoteEndPoint);
Clients.Add(new CoCRemoteClient(this, args.AcceptSocket, _settings));
args.AcceptSocket = null;
_acceptPool.Push(args);
}
private void ProcessBadAccept(SocketAsyncEventArgs args)
{
args.AcceptSocket.Close();
_acceptPool.Push(args);
}
private void AcceptOperationCompleted(object sender, SocketAsyncEventArgs e)
{
ProcessAccept(e);
}
}
}