Introduction
Hello, this is not anything to get overly excited about nor is it me showing off the next best thing. This is simply enhancing on the previous editions of a RSPS C# Framework to look at stability along with understanding the concept of RSPS through the idea of converting from one language to another.
I am simply giving a snippet of what I have done with this current project.
Features
- Server / Client Communication
- Player Saving / Loading
- Connection Logging
- Item Dropping
- Wearable Equipment
- Multiple Connections
Changes
- Changed SocketListener.cs to allow multiple connections at once.
- Missing packets have been causing issues,
Code
Will add snippets of other code segments later, once I finish doing some adjustment to a lot of classes.
SocketListener.cs
[SPOIL]
Code:
using Server.Net.Connection;
using Server.Util;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Server.Net
{
public class SocketListener : ConnectionManager
{
private bool serverRunning = true;
public ConnectionHandler handler { get; private set; }
private string[] bannedHosts = new string[500];
public SocketListener(ushort port)
{
// Server details
handler = new ConnectionHandler("127.0.0.1", port, 200);
Misc.WriteLine("Starting server on port: " + port);
LoadBannedHosts();
}
public void run()
{
handler.Listener.Start(true, true);
while (serverRunning)
{
TcpClient client = handler.Listener.listener.AcceptTcpClient();
ThreadPool.QueueUserWorkItem(new WaitCallback(CreateClient), client);
}
}
private void CreateClient(object tcpClientObject)
{
TcpClient tClient = (TcpClient)tcpClientObject;
Client client = null;
uint id = (uint)GetFreeId();
client = new Client(id, tClient.Client);
client.Start();
AppendConnection(client.IPAddress);
if (CheckBanned(client.IPAddress))
{
handler.ConnectionClosed(client);
return;
}
clients[id] = client;
Server.GetSingleton().engine.AddConnection(client, (int)id);
Server.GetSingleton().engine.CurrentPlayers++;
handler.Listener.LastSocket = null;
}
public void AppendConnection(string host)
{
Server.GetSingleton().engine.fileManager.AppendData("connections/" + host + ".txt", "[" + Misc.GetDate() + "] " + host + ": connection recieved.");
}
public bool CheckBanned(string hostname)
{
if (hostname == null)
return true;
for (int i = 0; i < bannedHosts.Length; i++)
{
if (bannedHosts[i] != null && (hostname.StartsWith(bannedHosts[i]) || hostname.Equals(bannedHosts[i])))
return true;
}
return false;
}
private void LoadBannedHosts()
{
int index = 0;
try
{
StreamReader input = new StreamReader("data/banned/bannedhosts.dat");
string loggedIPS = null;
while ((loggedIPS = input.ReadLine()) != null)
{
bannedHosts[index] = loggedIPS;
index++;
}
} catch (Exception e)
{
Misc.WriteLine("Error loading banned hosts list.");
}
}
}
}
[/SPOIL]
Client.cs
[SPOIL]
Code:
using Server.Players;
using Server.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Server.Net.Connection
{
public delegate void DataRouteEventHandler(byte[] data);
public delegate void DisconnectEventHandler();
public class Client
{
public uint Id { get; private set; }
public Socket Socket { get; private set; }
public NetworkStream stream { get; set; }
public DateTime CreateTime { get; private set; }
public DateTime LastDataRecievedOn { get; private set; }
public Client(uint id, Socket socket)
{
this.Id = id;
this.Socket = socket;
this.CreateTime = DateTime.Now;
this.LastDataRecievedOn = DateTime.Now;
}
public void Start()
{
stream = new NetworkStream(this.Socket);
}
public void Write(byte b)
{
if (Socket == null)
return;
stream.WriteByte(b);
}
public void Write(Player p, byte[] data, int offset, int length)
{
if (Socket == null)
return;
this.stream.Write(data, offset, length);
}
public void WriteBuffer(Player p)
{
if (p == null || !p.Online || p.Disconnected[0])
return;
try
{
if (p.Stream.OutOffset > 0)
stream.Write(p.Stream.OutBuffer, 0, p.Stream.OutOffset);
p.Stream.OutOffset = 0;
stream.Flush();
}
catch (Exception e)
{
p.Disconnected[0] = true;
}
}
public int Read(Player p)
{
if (Socket == null || Socket.Available < 1)
return -1;
return stream.Read(p.Stream.InBuffer, p.Stream.InOffset, p.Stream.InBuffer.Length);
}
public int Read(Player p, int read)
{
if (Socket == null)
return -1;
return stream.Read(p.Stream.InBuffer, 0, read);
}
public int Avail()
{
if (stream == null)
return 0;
return Socket.Available;
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
if (this.Socket != null)
this.Socket.Close(0);
}
public TimeSpan Age
{
get
{
TimeSpan span = DateTime.Now - this.CreateTime;
if (span <= TimeSpan.Zero)
return TimeSpan.Zero;
return span;
}
}
public string IPAddress
{
get
{
try
{
return this.Socket.RemoteEndPoint.ToString().Split(':')[0];
}
catch (Exception)
{
return "";
}
}
}
public bool Connected
{
get { return this.Socket.Connected; }
}
}
}
[/SPOIL]
Media
Credits
I based the whole project of an old topic I found just to get started and so that progress would not be hindered by code which I was not capable of converting to c#.
Server, Client and Source -
Myuria