Skip to content

Instantly share code, notes, and snippets.

@alpox
Created March 24, 2018 00:24
Show Gist options
  • Save alpox/0dcec34db87e6b591569f4c63556170a to your computer and use it in GitHub Desktop.
Save alpox/0dcec34db87e6b591569f4c63556170a to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Collections;
using System.Threading;
using System.Threading.Tasks;
using System.Reflection;
namespace UNIMotor
{
public class ConnectEventArgs: EventArgs
{
public Connection Connection { get; private set; }
public ConnectEventArgs(Connection con)
{
Connection = con;
}
}
public class Server
{
public static List<Connection> Connections = new List<Connection>();
public event EventHandler<ConnectEventArgs> OnConnect;
public Socket srv;
public const int Port = 3333;
const int BacklogSize = 1;
bool stop;
public void AddConnection(Connection con)
{
if(OnConnect != null)
OnConnect(this, new ConnectEventArgs(con));
Connections.Add(con);
}
public void RemoveConnection(Connection con)
{
Connections.Remove(con);
}
public void Start()
{
stop = false;
srv = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
srv.Bind(new IPEndPoint(IPAddress.Any, Port));
srv.Listen(BacklogSize);
Task.Factory.StartNew(() =>
{
while (true)
{
if (stop) break;
try
{
Socket conn = srv.Accept();
new Connection(conn, this);
}
catch (SocketException) { }
catch (Exception ex)
{
Console.WriteLine(ex.Message + ": " + ex.StackTrace);
}
}
});
}
public void Stop()
{
stop = true;
try
{
srv.Close();
}
catch (Exception) { }
foreach (var con in Connections)
{
con.Stop();
}
}
}
public class Connection
{
public event EventHandler<InputEventArgs> OnInput;
public UniClient UNIClient { get; private set; }
public IPlugin[] AssignedPlugins { get; set; }
static object BigLock = new object();
Socket socket;
public StreamReader Reader;
public StreamWriter Writer;
Server server;
public bool Busy { get; set; }
bool stop;
public void Stop()
{
stop = true;
UNIClient.Stop();
}
public IEnumerable<IPlugin> GetAllPlugins()
{
var plugins = new List<IPlugin>();
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
{
if (type.GetInterfaces().Contains(typeof(IPlugin)))
plugins.Add(Activator.CreateInstance(type) as IPlugin);
}
return plugins;
}
public Connection(Socket socket, Server server)
{
this.server = server;
this.socket = socket;
Reader = new StreamReader(new NetworkStream(socket, false), Encoding.ASCII);
Writer = new StreamWriter(new NetworkStream(socket, true), Encoding.ASCII);
new Thread(ClientLoop).Start();
UNIClient = new UniClient(this);
UNIClient.OnMessage += (s, ev) =>
{
try
{
if(!String.IsNullOrEmpty(ev.Input))
{
var goOn = true;
foreach (var plugin in AssignedPlugins)
if (!plugin.Input(InputType.Unitopia, ev.Input))
goOn = false;
if (goOn)
{
Writer.Write(ev.Input);
try
{
Writer.Flush();
}
catch (Exception) { }
}
}
}
catch (Exception ex) {
Console.WriteLine(ex.Message + ": " + ex.StackTrace); }
};
var plugins = GetAllPlugins();
AssignedPlugins = plugins.ToArray();
foreach (var plugin in plugins)
plugin.Create(this);
OnInput += (ss, ee) =>
{
try
{
var goOn = true;
foreach (var plugin in plugins)
if (!plugin.Input(InputType.Client, ee.Input))
goOn = false;
if (goOn) UNIClient.Send(ee.Input);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + ": " + ex.StackTrace);
}
};
UNIClient.Start();
}
void ClientLoop()
{
try
{
lock (BigLock)
{
OnConnect();
}
while (true)
{
if (stop) break;
lock (BigLock)
{
foreach (Connection conn in Server.Connections)
{
conn.Writer.Flush();
}
}
string line = Reader.ReadLine();
if (line == null)
{
break;
}
lock (BigLock)
{
if (Busy)
{
Writer.WriteLine("UNIMotor is working! Please wait until UNIMotor finished it's actions");
continue;
}
if (line.Trim().ToLower() == "ende")
break;
if(OnInput != null)
OnInput(this, new InputEventArgs(line));
}
}
}
finally
{
lock (BigLock)
{
Console.WriteLine("Client with IP " + ((IPEndPoint)socket.RemoteEndPoint).Address.ToString() + " has disconnected!");
socket.Close();
OnDisconnect();
}
}
}
void OnConnect()
{
Writer.WriteLine("Welcome to UNIMotor!");
server.AddConnection(this);
Console.WriteLine("Client with IP " + ((IPEndPoint)socket.RemoteEndPoint).Address.ToString() + " has connected!");
}
void OnDisconnect()
{
server.RemoveConnection(this);
}
}
public class InputEventArgs : EventArgs
{
public string Input { get; private set; }
public InputEventArgs(string str)
{
Input = str;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment