a lot of errors don't look
not done
This commit is contained in:
parent
f4e34c84bd
commit
5a54d0c834
13 changed files with 261 additions and 23 deletions
|
@ -71,6 +71,7 @@
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Configuration.cs" />
|
||||||
<Compile Include="DAL\Origin.cs" />
|
<Compile Include="DAL\Origin.cs" />
|
||||||
<Compile Include="DAL\ScapeDb.cs" />
|
<Compile Include="DAL\ScapeDb.cs" />
|
||||||
<Compile Include="DAL\Session.cs" />
|
<Compile Include="DAL\Session.cs" />
|
||||||
|
@ -140,7 +141,8 @@
|
||||||
<Error Condition="!Exists('packages\Costura.Fody.1.4.0\build\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Costura.Fody.1.4.0\build\Costura.Fody.targets'))" />
|
<Error Condition="!Exists('packages\Costura.Fody.1.4.0\build\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Costura.Fody.1.4.0\build\Costura.Fody.targets'))" />
|
||||||
</Target>
|
</Target>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent>XCOPY "$(ProjectDir)Assets" "$(TargetDir)" /Y</PostBuildEvent>
|
<PostBuildEvent>XCOPY "$(ProjectDir)Assets" "$(TargetDir)" /Y /E
|
||||||
|
COPY "$(ProjectDir)config.ini" "$(TargetDir)" /Y</PostBuildEvent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="packages\Fody.2.0.4\build\dotnet\Fody.targets" Condition=" '$(Configuration)' == 'Release' " />
|
<Import Project="packages\Fody.2.0.4\build\dotnet\Fody.targets" Condition=" '$(Configuration)' == 'Release' " />
|
||||||
<Import Project="packages\Costura.Fody.1.4.0\build\Costura.Fody.targets" Condition=" '$(Configuration)' == 'Release' " />
|
<Import Project="packages\Costura.Fody.1.4.0\build\Costura.Fody.targets" Condition=" '$(Configuration)' == 'Release' " />
|
||||||
|
|
56
server/Configuration.cs
Normal file
56
server/Configuration.cs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Square.INI;
|
||||||
|
|
||||||
|
namespace CircleScape {
|
||||||
|
public static class Configuration {
|
||||||
|
private static SettingsFile Settings;
|
||||||
|
|
||||||
|
static Configuration() {
|
||||||
|
Settings = new SettingsFile(
|
||||||
|
"config.ini",
|
||||||
|
new List<SectionRules> {
|
||||||
|
new SectionRules {
|
||||||
|
Name = "General",
|
||||||
|
Required = true,
|
||||||
|
RequiredFields = new string[] {
|
||||||
|
"Run Master",
|
||||||
|
"Master Port",
|
||||||
|
"Master Addr",
|
||||||
|
"Max Users"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
new SectionRules {
|
||||||
|
Name = "Server",
|
||||||
|
AllowMultiple = true,
|
||||||
|
Required = true,
|
||||||
|
RequiredFields = new string[] {
|
||||||
|
"Id",
|
||||||
|
"Port"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Section Get(string section) {
|
||||||
|
return Settings[section];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Section General {
|
||||||
|
get {
|
||||||
|
return Settings["General"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Section Servers {
|
||||||
|
get {
|
||||||
|
return Settings["Server"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ using System.Net;
|
||||||
namespace CircleScape {
|
namespace CircleScape {
|
||||||
class Entrypoint {
|
class Entrypoint {
|
||||||
static void Main(string[] args) {
|
static void Main(string[] args) {
|
||||||
|
foreach()
|
||||||
var server = new Kneesocks.Server<PlayerConnection>(6770, PoolManager.Pending);
|
var server = new Kneesocks.Server<PlayerConnection>(6770, PoolManager.Pending);
|
||||||
server.Start();
|
server.Start();
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace Kneesocks {
|
||||||
|
|
||||||
private TcpClient Socket = null;
|
private TcpClient Socket = null;
|
||||||
private NetworkStream Stream = null;
|
private NetworkStream Stream = null;
|
||||||
|
public Server Server { get; internal set; }
|
||||||
|
|
||||||
ReadBuffer Buffer;
|
ReadBuffer Buffer;
|
||||||
private byte[] FirstTwoBytes = null;
|
private byte[] FirstTwoBytes = null;
|
||||||
|
@ -93,6 +94,7 @@ namespace Kneesocks {
|
||||||
|
|
||||||
Socket = conn.Socket;
|
Socket = conn.Socket;
|
||||||
Stream = conn.Stream;
|
Stream = conn.Stream;
|
||||||
|
Server = conn.Server;
|
||||||
|
|
||||||
Buffer = conn.Buffer;
|
Buffer = conn.Buffer;
|
||||||
FirstTwoBytes = conn.FirstTwoBytes;
|
FirstTwoBytes = conn.FirstTwoBytes;
|
||||||
|
|
|
@ -7,19 +7,12 @@ using System.Net.Sockets;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
namespace Kneesocks {
|
namespace Kneesocks {
|
||||||
public class Server<T> where T : Connection, new() {
|
public abstract class Server {
|
||||||
private TcpListener Socket;
|
protected TcpListener Socket;
|
||||||
private Thread Listener = null;
|
protected Thread Listener = null;
|
||||||
private Pool<T> ConnectionPool = null;
|
public bool Started { get; protected set; } = false;
|
||||||
public bool Started { get; private set; } = false;
|
public UInt16 Port { get; protected set; }
|
||||||
public UInt16 Port { get; private set; }
|
public object Configuration { get; protected set; }
|
||||||
|
|
||||||
public Server(UInt16 port, Pool<T> pool) {
|
|
||||||
Port = port;
|
|
||||||
Socket = new TcpListener(IPAddress.Any, port);
|
|
||||||
Listener = new Thread(new ThreadStart(ListenThread));
|
|
||||||
ConnectionPool = pool;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Start() {
|
public void Start() {
|
||||||
if(!Started) {
|
if(!Started) {
|
||||||
|
@ -34,13 +27,26 @@ namespace Kneesocks {
|
||||||
Listener.Join();
|
Listener.Join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ListenThread() {
|
public class Server<T> : Server where T : Connection, new() {
|
||||||
|
protected Pool<T> ConnectionPool = null;
|
||||||
|
|
||||||
|
public Server(UInt16 port, Pool<T> pool, object config = null) {
|
||||||
|
Port = port;
|
||||||
|
Socket = new TcpListener(IPAddress.Any, port);
|
||||||
|
Listener = new Thread(new ThreadStart(ListenThread));
|
||||||
|
ConnectionPool = pool;
|
||||||
|
Configuration = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void ListenThread() {
|
||||||
Socket.Start();
|
Socket.Start();
|
||||||
|
|
||||||
while(Started) {
|
while(Started) {
|
||||||
if(Socket.Pending()) {
|
if(Socket.Pending()) {
|
||||||
var templatedConnection = new T();
|
var templatedConnection = new T();
|
||||||
|
templatedConnection.Server = this;
|
||||||
templatedConnection.Initialize(Socket.AcceptTcpClient());
|
templatedConnection.Initialize(Socket.AcceptTcpClient());
|
||||||
ConnectionPool.AddConnection(templatedConnection);
|
ConnectionPool.AddConnection(templatedConnection);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,43 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Square.INI {
|
namespace Square.INI {
|
||||||
class Instance {
|
public class Instance : IEnumerable<KeyValuePair<string, Value>> {
|
||||||
private Dictionary<string, string> Data { get; set; }
|
private Dictionary<string, Value> Data
|
||||||
|
= new Dictionary<string, Value>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
internal Instance() { }
|
||||||
|
|
||||||
|
internal void Push(string line) {
|
||||||
|
if(line.Contains('=')) {
|
||||||
|
var parts = line.Split(new char[] { '=' }, 2);
|
||||||
|
Data.Add(parts[0].Trim(), new Value(parts[1].Trim()));
|
||||||
|
} else
|
||||||
|
throw new FormatException("Line is not a key-value pair delimited by an equals sign.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Value this[string key] {
|
||||||
|
get {
|
||||||
|
if(Data.ContainsKey(key))
|
||||||
|
return Data[key];
|
||||||
|
else return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ContainsKey(string key) {
|
||||||
|
return Data.ContainsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() {
|
||||||
|
return Data.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator<KeyValuePair<string, Value>> IEnumerable<KeyValuePair<string, Value>>.GetEnumerator() {
|
||||||
|
return Data.GetEnumerator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,39 @@ using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Square.INI {
|
namespace Square.INI {
|
||||||
public class Section : IEnumerable {
|
public class Section : IEnumerable<Instance> {
|
||||||
private List<Instance> Instances;
|
private List<Instance> Instances;
|
||||||
|
|
||||||
public IEnumerator GetEnumerator() {
|
internal Section() { }
|
||||||
|
|
||||||
|
internal Instance Push() {
|
||||||
|
Instances.Add(new Instance());
|
||||||
|
return Instances[Instances.Count - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public string this[string key] {
|
||||||
|
get {
|
||||||
|
return Instances[0][key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instance this[int i] {
|
||||||
|
get {
|
||||||
|
return Instances[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Count {
|
||||||
|
get {
|
||||||
|
return Instances.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() {
|
||||||
|
return Instances.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator<Instance> IEnumerable<Instance>.GetEnumerator() {
|
||||||
return Instances.GetEnumerator();
|
return Instances.GetEnumerator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,9 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Square.INI {
|
namespace Square.INI {
|
||||||
public class SectionRules {
|
public class SectionRules {
|
||||||
|
public string Name { get; set; }
|
||||||
|
public bool Required { get; set; } = true;
|
||||||
|
public bool AllowMultiple { get; set; } = false;
|
||||||
|
public string[] RequiredFields { get; set; } = new string[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,47 @@ namespace Square.INI {
|
||||||
public SettingsFile(string path) {
|
public SettingsFile(string path) {
|
||||||
var lines = File.ReadAllLines(path);
|
var lines = File.ReadAllLines(path);
|
||||||
|
|
||||||
string currentSection = null;
|
Instance currentInstance = null;
|
||||||
foreach(var line in lines) {
|
foreach(var rawLine in lines) {
|
||||||
|
var line = rawLine.Trim();
|
||||||
|
if(line.StartsWith("!", "#", ";"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(line.StartsWith("[") && line.EndsWith("]")) {
|
||||||
|
var section = line.Substring(1, line.Length - 2);
|
||||||
|
if(!Sections.ContainsKey(section))
|
||||||
|
Sections.Add(section, new Section());
|
||||||
|
|
||||||
|
currentInstance = Sections[section].Push();
|
||||||
|
} else {
|
||||||
|
if(currentInstance != null)
|
||||||
|
currentInstance.Push(line);
|
||||||
|
else
|
||||||
|
throw new FormatException("Non-section line before any define sections in '"+ path +"'");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SettingsFile(string path, List<SectionRules> rules) {
|
public SettingsFile(string path, List<SectionRules> rules) : this(path) {
|
||||||
|
foreach(var rule in rules) {
|
||||||
|
var name = rule.Name;
|
||||||
|
|
||||||
|
if(ContainsSection(name)) {
|
||||||
|
var section = Sections[name];
|
||||||
|
if(!rule.AllowMultiple && section.Count > 1)
|
||||||
|
throw new FormatException("Section '"+ name +"' is not allowed to have multiple declarations in '"+ path +"'");
|
||||||
|
|
||||||
|
if(rule.RequiredFields.Length > 0) {
|
||||||
|
foreach(var instance in section) {
|
||||||
|
foreach(var field in rule.RequiredFields) {
|
||||||
|
if(instance.ContainsKey(field))
|
||||||
|
throw new FormatException("Expected field '"+ field +"' in section '" + name + "' was not found in '" + path + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(rule.Required)
|
||||||
|
throw new FormatException("Expected section '"+ name +"' was not found in '"+ path +"'");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Section this[string section] {
|
public Section this[string section] {
|
||||||
|
@ -30,5 +63,9 @@ namespace Square.INI {
|
||||||
else return null;
|
else return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool ContainsSection(string section) {
|
||||||
|
return Sections.ContainsKey(section);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
37
server/Libraries/Square/INI/Value.cs
Normal file
37
server/Libraries/Square/INI/Value.cs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Square.INI {
|
||||||
|
public class Value {
|
||||||
|
private string Raw;
|
||||||
|
|
||||||
|
public Value(string raw) {
|
||||||
|
Raw = raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator string(Value value) {
|
||||||
|
return value.Raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator bool(Value value) {
|
||||||
|
return Boolean.TryParse(value.Raw, out bool retval)
|
||||||
|
? retval
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator int(Value value) {
|
||||||
|
return Int32.TryParse(value.Raw, out int retval)
|
||||||
|
? retval
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator double(Value value) {
|
||||||
|
return Double.TryParse(value.Raw, out double retval)
|
||||||
|
? retval
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,6 +48,7 @@
|
||||||
<Compile Include="INI\Section.cs" />
|
<Compile Include="INI\Section.cs" />
|
||||||
<Compile Include="INI\SectionRules.cs" />
|
<Compile Include="INI\SectionRules.cs" />
|
||||||
<Compile Include="INI\SettingsFile.cs" />
|
<Compile Include="INI\SettingsFile.cs" />
|
||||||
|
<Compile Include="INI\Value.cs" />
|
||||||
<Compile Include="NumericExtensions.cs" />
|
<Compile Include="NumericExtensions.cs" />
|
||||||
<Compile Include="RandomContext.cs" />
|
<Compile Include="RandomContext.cs" />
|
||||||
<Compile Include="StringExtensions.cs" />
|
<Compile Include="StringExtensions.cs" />
|
||||||
|
|
|
@ -29,5 +29,14 @@ namespace Square {
|
||||||
|
|
||||||
public static byte[] Base64DecodeRaw(this string str)
|
public static byte[] Base64DecodeRaw(this string str)
|
||||||
=> Convert.FromBase64String(str);
|
=> Convert.FromBase64String(str);
|
||||||
|
|
||||||
|
public static bool StartsWith(this string str, params string[] strings) {
|
||||||
|
foreach(var checkString in strings) {
|
||||||
|
if(str.StartsWith(checkString))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
25
server/config.ini
Normal file
25
server/config.ini
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
[General]
|
||||||
|
; determines if this server instance should run the master server
|
||||||
|
Run Master = false
|
||||||
|
|
||||||
|
; address and port of the master server
|
||||||
|
;; if master server is in this instance, addr should be localhost
|
||||||
|
;; and port determines what port the master server runs on
|
||||||
|
Master Addr = localhost
|
||||||
|
Master Port = 16670
|
||||||
|
|
||||||
|
; this value used if the max users isn't specified in a server instance
|
||||||
|
Max Users = 100
|
||||||
|
|
||||||
|
[Server]
|
||||||
|
Id = 1
|
||||||
|
Port = 6770
|
||||||
|
Max Users = 300
|
||||||
|
|
||||||
|
[Server]
|
||||||
|
Id = 2
|
||||||
|
Port = 6780
|
||||||
|
|
||||||
|
[Server]
|
||||||
|
Id = 3
|
||||||
|
Port = 6790
|
Loading…
Reference in a new issue