Everything provided will be in C#, but it's for the fact most here is coding in C#.
Before you start to code on your private server, then it's important you understand the C# language itself. You will never get anywhere, if you just jump directly into the private server coding. Lucky for you there is a tons of resource available for C# on the internet and there is a lot forums that you can get help and tutorials in, but a good idea is to take 1-2 months just focusing on learning the actual C# language and after that time you can start to look into coding a private server. It might be a long time and you think making a private server is just 2 steps and then having it running, but if you want a proper server, then you need to put effort into it. Not only will this help you coding a private server, but programming can get you long in life and you can also use it to code a lot other things. In fact there is not a lot limits, if you know how to code.
First of all a good idea would be to understand what a programming language is, so please take the time to read this:
Computer programming - Wikipedia, the free encyclopedia
If you do not understand it, then don't panic. You can either read it again or lookup on it later. It's not neccessary to know it right now and I don't expect you to know any coding at all, when you start reading all this.
Next thing is choosing a language that you want to design your server in, but in this case we will choose C#.
If you want to know what C# exactly is, then here isa wikipedia page for it:
C Sharp (programming language) - Wikipedia, the free encyclopedia)
Learning the actualy language is not something that takes 1 day, 2days, 1 week or a month, but it takes very long time to get advanced in it.
A good idea would be reading some e-books or watching videos at youtube.
I will provide some links to some.
There is a lot books here:

C# for dummies:

Hybrids:

New bostons video tutorials: (This is the first, just continue to rest.)
MSDN:




Other sites and communities:






Now that might be a lot information at ones, but take the time you need to actually understand the language and so. You don't have to rush making a server. Some are learning faster than others, but we all got the same goal basically.
Now ones you understand the language and be HONEST to yourself. Do not try cheat or skip things. If you don't understand it, you might reread and learn some more, because it's important you understand the language, because I will not provide copy-paste neither a lot codes.
I will also only learn you how to communicate with the client and about server/client things, but not exactly how to code a private server. There is more than enough resources on that already.
Well first of all we need to make a new project. Choose console application, because having a GUI or using a form application is just a waste. No others are gonna see your server other than you.
The first thing you code for your server is the socket system. The socket system is the connection between the client and server. It's also where you send the data through.
When I'm coding a socket system, then I'm using a 3 way prencip.
Most people might actually do it this way and what so ever. Well let me explain the system.
The global socket wrapper
This is where everything is going to be handled. You can call this a kernel of our socket system. It's where we create our listener, our connections, our events that's going to be raised upon connections and receiving data from the clients. It will handle basically everything with our socket system.
The socket handlers
There is mainly 3 handlers that will be used and then a wrapper around it. The handlers or events are where we will handle the actual data received and every connection.
The socket client
This is the wrapper for the client and where you handle the client itself, but also the data that's going to be send back to the client.
First thing you gotta do, when coding the socket system is making a new folder, because we want to have a namespace for our sockets. Call the folder Network, because sockets have to do with the network. Once you have done that, then create a new class called ServerSocket, which will be our global socket wrapper or the 'kernel socket'.
The socket system we're going to use is an asynchronus socket system, which means it will not wait on the other events to be done, where it would if we used a synchronus socket system.
Read more about it here:

The socket class, we're going to use is the System.Net.Sockets, which you can read more about here:

The first thing we're going to code is our listener. Which will listen on a specific port. In this case it's the authserver and that's port 9959.
We need some global fields in our socket wrapper, which are the following.
(Read comments, because I explain what they are used for there.)
Code:
//This is the max buffer size of a packet. The default value is 1024 and it's also what we're going to use. public int BufferSize; //This is the actual socket, which will handle everything we do. The wrapper is basically just handling the methods within this class. public System.Net.Sockets.Socket Socket; //This is the port the gameserver have and for a co server it's 5816 public int Port;
Within this method we create our socket, binds it to an endpoint and then starts to listen after connections.
First thing we gotta do is coding the actual listener. We start making a method called Listen.
Code:
public void Listen()
{
}
We have to create an address family, a socket type and a protocol.
The address family we're going to use is InterNetwork, becuase it has to do with the actual network.
The socket type will be stream, because that's what's normal to use when working with a 2 way connection system, which we do, because it's a client/server connection.
The protocol is tcp, because that's what the conquer client uses. I don't want to explain about the difference of tcp and udp, but basically udp is about speed and it can loose packets easy and when it do, then it will not report back and it will just think, whatever, then continue its work. Tcp will always report back if there was an error when sending/receiving a packet. Usually udp is used for streaming and such things, where tcp is better when working with server/client stuff, but it doesn't mean you cannot use it. If I'm correct HoN uses udp.
Code:
Socket = new System.Net.Sockets.Socket(
System.Net.Sockets.AddressFamily.InterNetwork,
System.Net.Sockets.SocketType.Stream,
System.Net.Sockets.ProtocolType.Tcp);
In this method we will use the field we created before for the Port. The return type of it should be System.Net.IPEndPoint. We will just create a new IPEndPoint.
We will use IPAddress.Any, but I don't want to explain why, but you can read up on it yourself.
Then we will use the Port field we defined earlier.
Code:
public System.Net.IPEndPoint GetEndPoint()
{
return new System.Net.IPEndPoint(System.Net.IPAddress.Any, Port);
}
Code:
Socket.Bind(GetEndPoint());

And in the actual Listen document:

Code:
Socket.Listen(100);
Before we create it, then we will make 2 new methods with the parameter IAsyncResult. One called AcceptCallback and one called ReceiveCallback.
Code:
public void AcceptCallback(IAsyncResult result)
{
}
public void ReceiveCallback(IAsyncResult result)
{
}
Code:
public class SocketClient
{
}
Code:
public void BeginAccept()
{
Socket.BeginAccept(new AsyncCallback(AcceptCallback), new SocketClient());
}
So far our socket wrapper should look like this:
Code:
public class ServerSocket
{
public int BufferSize;
public System.Net.Sockets.Socket Socket;
public int Port;
public void Listen()
{
Socket = new System.Net.Sockets.Socket(
System.Net.Sockets.AddressFamily.InterNetwork,
System.Net.Sockets.SocketType.Stream,
System.Net.Sockets.ProtocolType.Tcp);
Socket.Bind(GetEndPoint());
Socket.Listen(100);
}
public void BeginAccept()
{
Socket.BeginAccept(new AsyncCallback(AcceptCallback), new SocketClient());
}
public System.Net.IPEndPoint GetEndPoint()
{
return new System.Net.IPEndPoint(System.Net.IPAddress.Any, Port);
}
public void AcceptCallback(IAsyncResult result)
{
}
public void ReceiveCallback(IAsyncResult result)
{
}
}
Code:
try
{
}
catch
{
}
Code:
public SocketClient Get(IAsyncResult result)
{
}
I'm just using a try/catch block.
Code:
public SocketClient Get(IAsyncResult result)
{
try
{
return result.AsyncState as SocketClient;
}
catch
{
return null;
}
}
Now what we do is calling this method in our AcceptCallback to get the SocketClient.
Code:
public void AcceptCallback(IAsyncResult result)
{
try
{
SocketClient Client = Get(result);
}
catch
{
}
}
First thing we have to do is making a field as a byte array called Buffer. Which is the packet we're receiving from the client.
Code:
public byte[] Buffer;
Code:
public int BufferLen
{
get
{
return Buffer.Length;
}
}
Code:
public System.Net.Sockets.Socket Socket;
Code:
public bool Connected
{
get { return Socket.Connected; }
}
We do that converting the RemoteEndPoint to an IPAddress and then returning the Address as a string.
Code:
public string IP
{
get
{
try
{
return (this.Socket.RemoteEndPoint as System.Net.IPEndPoint).Address.ToString();
}
catch { return "127.0.0.1"; }
}
}
A Disconnection method and an EndAccept method.
The disconnection method should call Socket.Disconnect() and we will put the reuse to false, because otherwise we're not allowed to reuse the socket. I don't want to go in details with it.
Code:
public void Disconnect()
{
Socket.Disconnect(false);
}
Within this method we will set our client socket using Socket.EndAccept from the socket in the parameter and the async result.
Code:
public void EndAccept(System.Net.Sockets.Socket socket, IAsyncResult result)
{
Socket = socket.EndAccept(result);
}
Look at the AcceptCallback again and the next thing we do is creating the buffer using the buffersize in our wrapper.
Code:
Client.Buffer = new byte[BufferSize];
We will make a try/catch block and in the catch we put a return false, because then it's not accepted. In the try block we will call the EndAccept method from the client in the parameter. Then we return it true after.
Code:
private bool Accepted(SocketClient Client, IAsyncResult result)
{
try
{
Client.EndAccept(Socket, result);
return true;
}
catch
{
return false;
}
}
Code:
public SocketEvents Events;
2 with the parameter SocketClient only and they should be called OnConnection and OnDisconnection, then another one with 2 parameters SocketClient and a byte array as Buffer called OnReceive.
Code:
public delegate void OnConnection(SocketClient Client);
public delegate void OnDisconnection(SocketClient Client);
public delegate void OnReceive(SocketClient Client, byte[] Buffer);
Code:
public OnConnection Connection;
public OnDisconnection Disconnection;
public OnReceive Receive;
Code:
public void BeginReceive(SocketClient Client)
{
}
First parameter is the buffer from our Client.
Next parameter is how many buffers and it should just be 0.
Next parameter is the max buffer size and we already specified that as a parameter.
Next parameter is socket flags and we don't want any, so choose None.
Now we need an AsyncCallback and it's of course to the ReceiveCallback.
The last thing is an object we want to send through the async event and it's the client.
Code:
Client.Socket.BeginReceive(Client.Buffer, 0, BufferSize, System.Net.Sockets.SocketFlags.None, new AsyncCallback(ReceiveCallback), Client);
Code:
public void AcceptCallback(IAsyncResult result)
{
try
{
SocketClient Client = Get(result);
Client.Buffer = new byte[BufferSize];
bool accepted;
if (accepted = Accepted(Client, result))
Events.Connection.Invoke(Client);
BeginAccept();
if (accepted)
BeginReceive(Client);
}
catch
{
}
}
Okay you can either use memcpy or Buffer.BlockCopy later, but I will just use Buffer.BlockCopy. However using msvcrt would be more efficient.
Well the first thing we do in the ReceiveCallback is calling the Get method again. Then we make a check if the client is not null. If it's null we call the disconnect event.
Code:
SocketClient Client = Get(result);
if (Client != null)
{
}
else
{
Events.Disconnection.Invoke(Client);
}
Code:
try
{
Events.Disconnection.Invoke(Client);
}
catch
{
Events.Disconnection.Invoke(Client);
}
Now we check if the client is connected calling the field from before. Client.Connected.
Code:
if (Client.Connected)
{
}
Code:
System.Net.Sockets.SocketError error;
We will return Socket.EndReceive in it and basically what it does is returning the length of the buffer and giving us a callback on how it all went. We will only use Socket.Success tho.
Code:
public int EndReceive(IAsyncResult result, out System.Net.Sockets.SocketError SE)
{
return Socket.EndReceive(result, out SE);
}
Code:
int BufferLength = Client.EndReceive(result, out error);
Code:
if (error == System.Net.Sockets.SocketError.Success)
{
}
Code:
if (BufferLength > 0)
{
}
Code:
byte[] rBuffer = new byte[BufferLength];
Code:
Buffer.BlockCopy(Client.Buffer, 0, rBuffer, 0, Client.BufferLen);

Now what we do is invoking the receive event and then calling beginreceive again. When that's done we just put a return to avoid the disconnection.
Code:
Events.Receive.Invoke(Client, rBuffer);
BeginReceive(Client);
return;
Code:
public void ReceiveCallback(IAsyncResult result)
{
SocketClient Client = Get(result);
if (Client != null)
{
try
{
if (Client.Connected)
{
System.Net.Sockets.SocketError error;
int BufferLength = Client.EndReceive(result, out error);
if (error == System.Net.Sockets.SocketError.Success)
{
if (BufferLength > 0)
{
byte[] rBuffer = new byte[BufferLength];
Buffer.BlockCopy(Client.Buffer, 0, rBuffer, 0, Client.BufferLen);
Events.Receive.Invoke(Client, rBuffer);
BeginReceive(Client);
return;
}
}
}
Events.Disconnection.Invoke(Client);
}
catch
{
Events.Disconnection.Invoke(Client);
}
}
else
{
Events.Disconnection.Invoke(Client);
}
}
Go to program.cs, because we will create our connection now and the handlers for our auth server.
First thing we do is creating our sockets. Basically we just create the events calling the delegates and then making our own static methods. Then we just call the Listen() within our wrapper.
Code:
ServerSocket socket = new ServerSocket();
socket.Events = new SocketEvents();
socket.Events.Connection = new OnConnection(Auth_Connection);
socket.Events.Disconnection = new OnDisconnection(Auth_Disconnection);
socket.Events.Receive = new OnReceive(Auth_Receive);
socket.BufferSize = 1024;
socket.Port = 9959;
socket.Listen();
Code:
static void Auth_Connection(SocketClient Client)
{
}
static void Auth_Disconnection(SocketClient Client)
{
}
static void Auth_Receive(SocketClient Client, byte[] Buffer)
{
}
In Auth_Disconnection you handle all disconnections from server.
In Auth_Receive you handle all datas from the client, this is also where the packethandler should be called. This is basically the packethandler, but the reason you split it to a new method is for a better structure, because it does nothing performance wise.
Basically you do same for Game Server.
I will not really provide much more information, because it's now up to yourself to study, but now you have a socket system to work of to make your own server from scratch.
Other threads you should read:





I think that's it. I'm aware there might be a few grammar mistakes, but English is not my main language. I hope this will be useful for some and if you got questions feel free to ask.
Please don't ask how to fix errors or ask for codes here.
Good luck
Then to have your server working fully, you must have Arco bless your server with Holy Water






