1
0
Fork 0

Ajout du server

This commit is contained in:
sheychen 2016-10-09 14:27:08 +02:00
parent 8e7de18c53
commit 6d87af0376
23 changed files with 1136 additions and 21 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
</startup>
</configuration>
</configuration>

View File

@ -0,0 +1,23 @@
using System;
using System.Net.Sockets;
namespace Galactic_Colors_Control_Server.Commands
{
public class ClearCommand : ICommand
{
public string Name { get { return "clear"; } }
public string DescText { get { return "Clears the console screen."; } }
public string HelpText { get { return "Use /clear to execute Console.Clear()."; } }
public bool IsServer { get { return true; } }
public bool IsClient { get { return true; } }
public bool IsNoConnect { get { return true; } }
public int minArgs { get { return 0; } }
public int maxArgs { get { return 0; } }
public void Execute(string[] args, Socket soc, bool server = false)
{
Console.Clear();
Console.Write(">");
}
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Net.Sockets;
namespace Galactic_Colors_Control_Server.Commands
{
public class CloseCommand : ICommand
{
public string Name { get { return "close"; } }
public string DescText { get { return "Closes server from connections."; } }
public string HelpText { get { return "Use /close to stop connection process"; } }
public bool IsServer { get { return true; } }
public bool IsClient { get { return false; } }
public bool IsNoConnect { get { return false; } }
public int minArgs { get { return 0; } }
public int maxArgs { get { return 0; } }
public void Execute(string[] args, Socket soc, bool server = false)
{
if (Program._open)
{
Program._open = false;
Logger.Write("Server closed", Logger.logType.warm);
}
else
{
Utilities.ConsoleWrite("Server already close");
}
}
}
}

View File

@ -0,0 +1,37 @@
using System;
using System.Net;
using System.Net.Sockets;
namespace Galactic_Colors_Control_Server.Commands
{
public class ConnectCommand : ICommand
{
public string Name { get { return "connect"; } }
public string DescText { get { return "Gets an username."; } }
public string HelpText { get { return "Use /connect [username] to start identification"; } }
public bool IsServer { get { return false; } }
public bool IsClient { get { return true; } }
public bool IsNoConnect { get { return true; } }
public int minArgs { get { return 1; } }
public int maxArgs { get { return 1; } }
public void Execute(string[] args, Socket soc, bool server = false)
{
if (!Utilities.IsConnect(soc))
{
Logger.Write("Identifiaction request from " + Utilities.GetName(soc), Logger.logType.debug);
Program.clients[soc].status = 0;
//args[1] = args[1][0].ToString().ToUpper()[0] + args[1].Substring(1);
Program.clients[soc].pseudo = args[1];
Utilities.Send(soc, "Identified as " + args[1], Utilities.dataType.message);
Utilities.Broadcast(args[1] + "joined the server", Utilities.dataType.message);
Logger.Write("Identified as " + Utilities.GetName(soc) + " form " + ((IPEndPoint)soc.LocalEndPoint).Address.ToString(), Logger.logType.info);
}
else
{
Utilities.Send(soc, "You are allready " + Utilities.GetName(soc), Utilities.dataType.message);
}
}
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Net.Sockets;
namespace Galactic_Colors_Control_Server.Commands
{
public class CountCommand : ICommand
{
public string Name { get { return "count"; } }
public string DescText { get { return "Counts connected clients."; } }
public string HelpText { get { return "Use /count to show connected clients count and size"; } }
public bool IsServer { get { return true; } }
public bool IsClient { get { return false; } }
public bool IsNoConnect { get { return false; } }
public int minArgs { get { return 0; } }
public int maxArgs { get { return 0; } }
public void Execute(string[] args, Socket soc, bool server = false)
{
Utilities.ConsoleWrite(Program.clients.Count + "/" + Program.config.size);
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Net.Sockets;
namespace Galactic_Colors_Control_Server.Commands
{
public class ExitCommand : ICommand
{
public string Name { get { return "exit"; } }
public string DescText { get { return "Leave the program."; } }
public string HelpText { get { return "Use /exit to stop actual program."; } }
public bool IsServer { get { return true; } }
public bool IsClient { get { return true; } }
public bool IsNoConnect { get { return true; } }
public int minArgs { get { return 0; } }
public int maxArgs { get { return 0; } }
public void Execute(string[] args, Socket soc, bool server = false)
{
if (server)
{
Program._run = false;
Utilities.ConsoleWrite("Exit server");
}
else
{
soc.Shutdown(SocketShutdown.Both);
Logger.Write("Client disconnected from " + Utilities.GetName(soc), Logger.logType.info);
soc.Close();
Program.clients.Remove(soc);
Logger.Write("Size: " + Program.clients.Count + "/" + Program.config.size, Logger.logType.debug);
}
}
}
}

View File

@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
namespace Galactic_Colors_Control_Server.Commands
{
public class HelpCommand : ICommand
{
public string Name { get { return "help"; } }
public string DescText { get { return "Shows the help."; } }
public string HelpText { get { return "Use /help [command] to display command help."; } }
public bool IsServer { get { return true; } }
public bool IsClient { get { return false; } }
public bool IsNoConnect { get { return true; } }
public int minArgs { get { return 0; } }
public int maxArgs { get { return 1; } }
public void Execute(string[] args, Socket soc, bool server = false)
{
if(args.Length == 1)
{
List<string> list = new List<string>();
int maxLen = 0;
foreach (string com in Manager.commands.Keys)
{
if(Manager.CanAccess(Manager.commands[com], soc, server))
{
list.Add(com);
if(com.Length > maxLen) { maxLen = com.Length; }
}
}
list.Sort();
string text = "Use /help [command] for more informations." + Environment.NewLine + "Available commands:" + Environment.NewLine;
foreach (var key in list)
{
text += (" " + key + new string(' ', maxLen - key.Length) + " : " + Manager.commands[key].DescText + Environment.NewLine);
}
Utilities.Return(text, soc, server);
}
else
{
if (Manager.commands.ContainsKey(args[1]))
{
if (Manager.CanAccess(Manager.commands[args[1]], soc, server))
{
Utilities.Return(Manager.commands[args[1]].HelpText, soc, server);
}
else
{
Utilities.Return("Any help for " + args[1], soc, server);
}
}
else
{
Utilities.Return("Any help for " + args[1], soc, server);
}
}
}
}
}

View File

@ -0,0 +1,18 @@
using System.Net.Sockets;
namespace Galactic_Colors_Control_Server.Commands
{
public interface ICommand
{
string Name { get; }
string DescText { get; }
string HelpText { get; }
bool IsServer { get; }
bool IsClient { get; }
bool IsNoConnect { get; }
int minArgs { get; }
int maxArgs { get; }
void Execute(string[] args, Socket soc = null, bool server = false);
}
}

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
namespace Galactic_Colors_Control_Server.Commands
{
public class KickCommand : ICommand
{
public string Name { get { return "kick"; } }
public string DescText { get { return "Kicks selected client."; } }
public string HelpText { get { return "Use /kick [username] <reason> to kick client from server."; } }
public bool IsServer { get { return true; } }
public bool IsClient { get { return false; } }
public bool IsNoConnect { get { return true; } }
public int minArgs { get { return 1; } }
public int maxArgs { get { return 2; } }
public void Execute(string[] args, Socket soc, bool server = false)
{
Socket target = null;
foreach(Socket client in Program.clients.Keys)
{
if(Utilities.GetName(client) == args[1]) { target = client; }
}
if (target != null)
{
Logger.Write(args[1] + " was kick by server.", Logger.logType.info);
if (args.Length > 2)
{
Utilities.Send(target, "/kick " + args[2], Utilities.dataType.message);
Logger.Write("because" + args[1], Logger.logType.debug);
}
else {
Utilities.Send(target, "/kick", Utilities.dataType.message);
}
}
else
{
Utilities.Return("Can't find " + args[1], soc, server);
}
}
}
}

View File

@ -0,0 +1,28 @@
using System;
using System.Net.Sockets;
namespace Galactic_Colors_Control_Server.Commands
{
public class ListCommand : ICommand
{
public string Name { get { return "list"; } }
public string DescText { get { return "Lists connected clients."; } }
public string HelpText { get { return "Use /list to display all connected client username or IP."; } }
public bool IsServer { get { return true; } }
public bool IsClient { get { return false; } }
public bool IsNoConnect { get { return false; } }
public int minArgs { get { return 0; } }
public int maxArgs { get { return 0; } }
public void Execute(string[] args, Socket soc, bool server = false)
{
string text = " ";
foreach (Socket socket in Program.clients.Keys)
{
text += (Utilities.GetName(socket) + ", ");
}
text = text.Remove(text.Length - 2, 2);
Utilities.ConsoleWrite(text);
}
}
}

View File

@ -0,0 +1,29 @@
using System;
using System.Net.Sockets;
namespace Galactic_Colors_Control_Server.Commands
{
public class LogLevelCommand : ICommand
{
public string Name { get { return "loglevel"; } }
public string DescText { get { return "Change console loglevel."; } }
public string HelpText { get { return "Use /loglevel [loglevel] to change Loglevel."; } }
public bool IsServer { get { return true; } }
public bool IsClient { get { return false; } }
public bool IsNoConnect { get { return false; } }
public int minArgs { get { return 1; } }
public int maxArgs { get { return 1; } }
public void Execute(string[] args, Socket soc, bool server = false)
{
if (Enum.TryParse(args[1], true, out Program.config.logLevel))
{
Utilities.ConsoleWrite("LogLevel: " + Program.config.logLevel.ToString());
}
else
{
Utilities.ConsoleWrite("Incorrect argument (debug, info, important, error, fatal)");
}
}
}
}

View File

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Reflection;
namespace Galactic_Colors_Control_Server.Commands
{
class Manager
{
public static Dictionary<string, ICommand> commands { get; private set; } = new Dictionary<string, ICommand>();
public static void Load()
{
IEnumerable<ICommand> coms = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.GetInterfaces().Contains(typeof(ICommand)) && x.GetConstructor(Type.EmptyTypes) != null).Select(x => Activator.CreateInstance(x) as ICommand);
foreach (ICommand com in coms)
{
commands.Add(com.Name, com);
Logger.Write("Added command " + com.GetType().Name, Logger.logType.debug);
}
}
public static void Execute(string[] args, Socket soc = null, bool server = false)
{
if (commands.ContainsKey(args[0]))
{
ICommand command = commands[args[0]];
if (CanAccess(command,soc,server))
{
if(args.Length > command.minArgs)
{
if(args.Length - 1 <= command.maxArgs)
{
command.Execute(args, soc, server);
}
else
{
Utilities.Return("Command " + command.Name + " require at most " + command.minArgs + " argument(s).", soc, server);
}
}
else
{
Utilities.Return("Command " + command.Name + " require at least " + command.minArgs + " argument(s).", soc, server);
}
}
else
{
Utilities.Return("Unknown command", soc, server);
}
}
else
{
Utilities.Return("Unknown command", soc, server);
}
}
public static bool CanAccess(ICommand command, Socket soc = null, bool server = false)
{
if (server)
{
return command.IsServer;
}
else
{
if (command.IsClient)
{
if(Utilities.IsConnect(soc))
{
return command.IsNoConnect;
}
else
{
return true;
}
}
else
{
return false;
}
}
}
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Net.Sockets;
namespace Galactic_Colors_Control_Server.Commands
{
public class OpenCommand : ICommand
{
public string Name { get { return "open"; } }
public string DescText { get { return "Opens server for connections."; } }
public string HelpText { get { return "Use /open to restart connection process"; } }
public bool IsServer { get { return true; } }
public bool IsClient { get { return false; } }
public bool IsNoConnect { get { return false; } }
public int minArgs { get { return 0; } }
public int maxArgs { get { return 0; } }
public void Execute(string[] args, Socket soc, bool server = false)
{
if (!Program._open)
{
Program._open = true;
Logger.Write("Server opened", Logger.logType.warm);
}
else
{
Utilities.ConsoleWrite("Server already open");
}
}
}
}

View File

@ -0,0 +1,28 @@
using System;
using System.Net.Sockets;
namespace Galactic_Colors_Control_Server.Commands
{
public class StatusCommand : ICommand
{
public string Name { get { return "status"; } }
public string DescText { get { return "Shows server status."; } }
public string HelpText { get { return "Use /status to display server actual status."; } }
public bool IsServer { get { return true; } }
public bool IsClient { get { return false; } }
public bool IsNoConnect { get { return false; } }
public int minArgs { get { return 0; } }
public int maxArgs { get { return 0; } }
public void Execute(string[] args, Socket soc, bool server = false)
{
if (Program._open)
{
Utilities.ConsoleWrite("Server open");
}
else {
Utilities.ConsoleWrite("Server close");
}
}
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Net.Sockets;
namespace Galactic_Colors_Control_Server.Commands
{
public class TimeCommand : ICommand
{
public string Name { get { return "time"; } }
public string DescText { get { return "Gives server time."; } }
public string HelpText { get { return "Use /time to display server time. (format is server dependent)"; } }
public bool IsServer { get { return true; } }
public bool IsClient { get { return true; } }
public bool IsNoConnect { get { return false; } }
public int minArgs { get { return 0; } }
public int maxArgs { get { return 0; } }
public void Execute(string[] args, Socket soc, bool server = false)
{
Utilities.Return(DateTime.Now.ToLongTimeString(), soc, server);
}
}
}

View File

@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
namespace Galactic_Colors_Control_Server
{
[XmlRoot("config")]
public class Config
{
public string logPath = AppDomain.CurrentDomain.BaseDirectory + "Logs";
public Logger.logType logLevel = Logger.logType.info;
public int port = 25001;
public int size = 20;
public ConsoleColor[] logForeColor = new ConsoleColor[5] {ConsoleColor.Gray , ConsoleColor.White, ConsoleColor.Yellow, ConsoleColor.Red, ConsoleColor.White};
public ConsoleColor[] logBackColor = new ConsoleColor[5] { ConsoleColor.Black, ConsoleColor.Black, ConsoleColor.Black, ConsoleColor.Black, ConsoleColor.Red };
public Config Load()
{
Logger.Write("Loading config", Logger.logType.info);
Config config = new Config();
if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + "Config.xml"))
{
if (CorrectConfig())
{
XmlSerializer xs = new XmlSerializer(typeof(Config));
using (StreamReader re = new StreamReader(AppDomain.CurrentDomain.BaseDirectory + "Config.xml"))
{
config = xs.Deserialize(re) as Config;
};
}
else
{
Logger.Write("Old config in Config.xml.old", Logger.logType.warm);
File.Move(AppDomain.CurrentDomain.BaseDirectory + "Config.xml", AppDomain.CurrentDomain.BaseDirectory + "Config.xml.old");
config.Save();
}
}
else
{
Logger.Write("Any config file", Logger.logType.error);
config.Save();
}
if (Program._debug) { config.logLevel = Logger.logType.debug; }
return config;
}
public void Save()
{
XmlSerializer xs = new XmlSerializer(typeof(Config));
if (Program._debug) { logLevel = Logger.logType.info; }
using (StreamWriter st = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "Config.xml"))
{
xs.Serialize(st,this);
};
if (Program._debug) { logLevel = Logger.logType.debug; }
}
public bool CorrectConfig()
{
bool isCorrect = false;
using (Stream fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + "Config.xml", FileMode.Open))
{
XmlReader re = new XmlTextReader(fs);
XmlSerializer xs = new XmlSerializer(typeof(Config));
try
{
isCorrect = xs.CanDeserialize(re);
}
catch (XmlException e)
{
isCorrect = false;
Logger.Write("Error: " + e.Message, Logger.logType.error);
}
}
if (isCorrect)
{
try
{
XmlDocument d = new XmlDocument();
d.Load(AppDomain.CurrentDomain.BaseDirectory + "Config.xml");
d.Schemas.Add("", XmlReader.Create("ConfigSchema.xsd"));
d.Validate((o, e) =>
{
Logger.Write("Error: " + e.Message, Logger.logType.error);
isCorrect = false;
});
}
catch (XmlException e)
{
isCorrect = false;
Logger.Write("Error: " + e.Message, Logger.logType.error);
}
}
return isCorrect;
}
}
}

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified">
<xsd:element name="config">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="logPath" type="xsd:string" />
<xsd:element name="logLevel" type="xsd:string" />
<xsd:element name="port" type="xsd:unsignedShort" />
<xsd:element name="size" type="xsd:unsignedShort" />
<xsd:element name="logForeColor">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="ConsoleColor" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="logBackColor">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="ConsoleColor" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xs:schema>

View File

@ -0,0 +1,11 @@
using System.Net.Sockets;
namespace Galactic_Colors_Control_Server
{
public class Data
{
public int id;
public int status = -1;
public string pseudo = "";
}
}

View File

@ -12,6 +12,21 @@
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<PublishUrl>publier\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>1</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -34,20 +49,47 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="System.XML" />
</ItemGroup>
<ItemGroup>
<Compile Include="Commands\ClearCommand.cs" />
<Compile Include="Commands\CloseCommand.cs" />
<Compile Include="Commands\ConnectCommand.cs" />
<Compile Include="Commands\CountCommand.cs" />
<Compile Include="Commands\ExitCommand.cs" />
<Compile Include="Commands\HelpCommand.cs" />
<Compile Include="Commands\ICommand.cs" />
<Compile Include="Commands\KickCommand.cs" />
<Compile Include="Commands\ListCommand.cs" />
<Compile Include="Commands\LogLevelCommand.cs" />
<Compile Include="Commands\Manager.cs" />
<Compile Include="Commands\OpenCommand.cs" />
<Compile Include="Commands\StatusCommand.cs" />
<Compile Include="Commands\TimeCommand.cs" />
<Compile Include="Config.cs" />
<Compile Include="Data.cs" />
<Compile Include="Logger.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utilities.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="ConfigSchema.xsd">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.5.2">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.5.2 %28x86 et x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
namespace Galactic_Colors_Control_Server
{
public class Logger
{
public enum logType { debug, info, warm, error, fatal }
private static List<Log> toWriteLogs = new List<Log>();
private static string logPath;
public static Thread Updater;
public static bool _run = true;
public struct Log
{
public string text;
public logType type;
public Log(string p1, logType p2)
{
text = p1;
type = p2;
}
}
public static void Initialise()
{
if (!Directory.Exists(Program.config.logPath)) {
Directory.CreateDirectory(Program.config.logPath);
Write("Log Directory Created" ,logType.info);
}
else
{
string[] files = Directory.GetFiles(Program.config.logPath);
foreach(string file in files)
{
if (Path.GetExtension(file) == ".log")
{
string name = Path.GetFileName(file);
name = name.Substring(0, Math.Min(name.Length, 10));
if (name.Length == 10)
{
if (name != DateTime.UtcNow.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture))
{
int y;
int m;
int d;
if(int.TryParse(new string(name.Take(4).ToArray()), out y) && int.TryParse(new string(name.Skip(5).Take(2).ToArray()), out m) && int.TryParse(new string(name.Skip(8).Take(2).ToArray()), out d))
{
if (!Directory.Exists(Program.config.logPath + "/" + y + "/" + m + "/" + d))
{
Directory.CreateDirectory(Program.config.logPath + "/" + y + "/" + m + "/" + d);
}
File.Move(file, Program.config.logPath + "/" + y + "/" + m + "/" + d + "/" + Path.GetFileName(file));
}
}
}
}
}
}
int i = 0;
while(File.Exists(Program.config.logPath + "/" + DateTime.UtcNow.ToString("yyyy-MM-dd-", CultureInfo.InvariantCulture) + i + ".log")) { i++; }
logPath = Program.config.logPath + "/" + DateTime.UtcNow.ToString("yyyy-MM-dd-", CultureInfo.InvariantCulture) + i + ".log";
Write("Log path:" + logPath, logType.debug);
Updater = new Thread(new ThreadStart(UpdaterLoop));
Updater.Start();
}
public static void Write(string text, logType type)
{
Write(new Log(text, type));
}
public static void Write(Log log)
{
if (log.type != logType.debug || Program.config.logLevel == logType.debug)
{
if(Program._debug)
{
log.text = "[" + new StackTrace().GetFrame(2).GetMethod().Name + "]: " + log.text;
}
toWriteLogs.Add(log);
}
}
public static void UpdaterLoop()
{
while (_run || toWriteLogs.Count > 0)
{
while(toWriteLogs.Count > 0)
{
Log log = toWriteLogs[0];
File.AppendAllText(logPath,DateTime.UtcNow.ToString("[yyyy-MM-dd]", CultureInfo.InvariantCulture) + " [" + log.type.ToString().ToUpper() + "]: " + log.text + Environment.NewLine);
if(log.type >= Program.config.logLevel) {
Console.BackgroundColor = Program.config.logBackColor[(int)log.type];
Console.ForegroundColor = Program.config.logForeColor[(int)log.type];
Console.Write("\b");
Console.WriteLine(DateTime.UtcNow.ToString("[yyyy-MM-dd]", CultureInfo.InvariantCulture) + ": " + log.text);
Utilities.ConsoleResetColor();
Console.Write(">");
}
toWriteLogs.Remove(log);
}
Thread.Sleep(200);
}
}
}
}

View File

@ -1,15 +1,217 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Galactic_Colors_Control_Server
{
class Program
{
static void Main(string[] args)
{
}
}
}
internal class Program
{
private const int BUFFER_SIZE = 2048;
private static readonly Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public static bool _debug = false;
public static bool _run = true;
public static bool _open = true;
private static readonly byte[] buffer = new byte[BUFFER_SIZE];
public static Dictionary<Socket, Data> clients { get; private set; } = new Dictionary<Socket, Data>();
public static Config config = new Config();
private static void Main(string[] args)
{
Console.Title = "Galactic Colors Control Server";
Logger.Write("Galactic Colors Control Server " + Assembly.GetEntryAssembly().GetName().Version.ToString(), Logger.logType.fatal);
if (args.Length > 0)
{
switch (args[0])
{
case "--debug":
_debug = true;
Logger.Write("SERVER IS IN DEBUG MODE !", Logger.logType.error);
break;
default:
Utilities.ConsoleWrite("Use --debug or any argument");
break;
}
}
if(Type.GetType("Mono.Runtime") != null) { Logger.Write("Using Mono", Logger.logType.warm); }
Console.Write(">");
SetupServer();
ConsoleLoop();
CloseAllSockets();
}
private static void SetupServer()
{
config = config.Load();
Logger.Initialise();
Commands.Manager.Load();
Logger.Write("Setting up server on *:" + config.port, Logger.logType.warm);
Logger.Write("Size:" + config.size, Logger.logType.debug);
serverSocket.Bind(new IPEndPoint(IPAddress.Any, config.port));
serverSocket.Listen(0);
serverSocket.BeginAccept(AcceptCallback, null);
Logger.Write("Server setup complete", Logger.logType.info);
}
private static void ConsoleLoop()
{
while (_run)
{
string ConsoleInput = Console.ReadLine();
Console.Write(">");
ExecuteMessage(ConsoleInput, null, true);
ConsoleInput = null;
}
}
/// <summary>
/// Close all connected client (we do not need to shutdown the server socket as its connections
/// are already closed with the clients).
/// </summary>
private static void CloseAllSockets()
{
Logger.Write("Stoping server", Logger.logType.warm);
config.Save();
foreach (Socket socket in clients.Keys)
{
socket.Shutdown(SocketShutdown.Both);
Logger.Write("Shutdown " + Utilities.GetName(socket),Logger.logType.debug);
//socket.Close();
}
serverSocket.Close();
Logger.Write("Server stoped", Logger.logType.info);
Logger._run = false;
Logger.Updater.Join();
}
private static void AcceptCallback(IAsyncResult AR)
{
Socket socket;
try
{
socket = serverSocket.EndAccept(AR);
}
catch (ObjectDisposedException) // I cannot seem to avoid this (on exit when properly closing sockets)
{
return;
}
if (_open)
{
if (clients.Count < Program.config.size)
{
AddClient(socket);
}
else
{
Logger.Write("Client can't join from " + ((IPEndPoint)socket.LocalEndPoint).Address.ToString() + " no more space", Logger.logType.warm);
Utilities.Send(socket, "/kick can't_join_no_more_space", Utilities.dataType.message);
socket.Close();
}
}
else
{
Logger.Write("Client can't join from " + ((IPEndPoint)socket.LocalEndPoint).Address.ToString() + " server closed", Logger.logType.info);
Utilities.Send(socket, "/kick can't_join_server_closed", Utilities.dataType.message);
socket.Close();
}
serverSocket.BeginAccept(AcceptCallback, null);
}
private static void AddClient(Socket socket)
{
clients.Add(socket, new Data());
socket.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, socket);
Logger.Write("Client connection from " + Utilities.GetName(socket), Logger.logType.info);
Logger.Write("Size: " + clients.Count + "/" + config.size, Logger.logType.debug);
if (clients.Count >= config.size)
{
Logger.Write("Server full", Logger.logType.warm);
}
}
private static void ReceiveCallback(IAsyncResult AR)
{
Socket current = (Socket)AR.AsyncState;
int received;
try
{
received = current.EndReceive(AR);
}
catch (SocketException)
{
Logger.Write("Client forcefully disconnected from " + Utilities.GetName(current), Logger.logType.info);
Logger.Write("Size: " + clients.Count + "/" + config.size, Logger.logType.debug);
current.Close(); // Don't shutdown because the socket may be disposed and its disconnected anyway.
clients.Remove(current);
return;
}
var data = new byte[received];
Array.Copy(buffer, data, received);
byte[] type = new byte[4];
type = data.Take(4).ToArray();
type.Reverse();
Utilities.dataType dtype = (Utilities.dataType)BitConverter.ToInt32(type, 0);
byte[] bytes = null;
bytes = data.Skip(4).ToArray();
switch (dtype)
{
case Utilities.dataType.message:
string text = Encoding.ASCII.GetString(bytes);
ExecuteMessage(text, current);
break;
case Utilities.dataType.data:
Console.WriteLine("data");
break;
default:
Logger.Write("Unknow type data form" + Utilities.GetName(current), Logger.logType.error);
break;
}
if (clients.ContainsKey(current)) { current.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current); }
}
private static void ExecuteMessage(string text, Socket soc = null, bool server = false)
{
if (text.Length > 0)
{
if (text[0] == '/')
{
text = text.Substring(1);
text = text.ToLower();
string[] array = text.Split(new char[1] { ' ' }, 4, StringSplitOptions.RemoveEmptyEntries);
if (array.Length > 0)
{
Commands.Manager.Execute(array, soc, server);
}
else
{
Utilities.Return("Any command",soc , server);
}
}
else
{
if (!Utilities.IsConnect(soc))
{
Utilities.Send(soc, "Only identified clients can talk.", Utilities.dataType.message);
}
else
{
Logger.Write(Utilities.GetName(soc) + " : " + text, Logger.logType.info);
Utilities.Broadcast(Utilities.GetName(soc) + " : " + text, Utilities.dataType.message);
}
}
}
}
}
}

View File

@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Galactic Colors Control Server")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyCompany("sheychen")]
[assembly: AssemblyProduct("Galactic Colors Control Server")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut
// en utilisant '*', comme indiqué ci-dessous :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.1")]
[assembly: AssemblyFileVersion("1.0.0.1")]

View File

@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.IO;
//using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
namespace Galactic_Colors_Control_Server
{
class Utilities
{
public enum dataType { message, data };
public static bool IsConnect(Socket soc)
{
if(soc == null)
{
return true;
}
else
{
if (Program.clients.ContainsKey(soc))
{
return Program.clients[soc].status != -1;
}
else
{
Logger.Write("IsConnect : Unknown client", Logger.logType.error);
return true;
}
}
}
public static string GetName(Socket soc)
{
if (soc != null)
{
if (Program.clients.ContainsKey(soc))
{
string res = Program.clients[soc].pseudo;
if (res == "") { res = ((IPEndPoint)soc.LocalEndPoint).Address.ToString(); }
return res;
}
else
{
return "?";
}
}
else
{
return "Server";
}
}
public static void ConsoleWrite(string v)
{
Console.Write("\b");
Console.ForegroundColor = ConsoleColor.White;
Console.BackgroundColor = ConsoleColor.Black;
Console.WriteLine(v);
ConsoleResetColor();
Console.Write(">");
}
public static void ConsoleResetColor()
{
Console.ResetColor();
Console.BackgroundColor = ConsoleColor.Black;
}
public static void Send(Socket soc, object data, dataType dtype)
{
byte[] type = new byte[4];
type = BitConverter.GetBytes((int)dtype);
byte[] bytes = null;
switch (dtype)
{
case dataType.message:
bytes = Encoding.ASCII.GetBytes((string)data);
break;
case dataType.data:
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, data);
bytes = ms.ToArray();
}
break;
default:
bytes = new byte[] { 1 };
break;
}
byte[] final = new byte[type.Length + bytes.Length];
type.CopyTo(final, 0);
bytes.CopyTo(final, type.Length);
soc.Send(final);
}
public static void Broadcast(object data, dataType dtype)
{
foreach (Socket soc in Program.clients.Keys)
{
Send(soc, data, dtype);
}
}
public static void Return(string message, Socket soc = null, bool server = false)
{
if (server)
{
ConsoleWrite(message);
}
else
{
Send(soc, message, dataType.message);
}
}
}
}