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" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Configuration.cs" />
|
||||
<Compile Include="DAL\Origin.cs" />
|
||||
<Compile Include="DAL\ScapeDb.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'))" />
|
||||
</Target>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>XCOPY "$(ProjectDir)Assets" "$(TargetDir)" /Y</PostBuildEvent>
|
||||
<PostBuildEvent>XCOPY "$(ProjectDir)Assets" "$(TargetDir)" /Y /E
|
||||
COPY "$(ProjectDir)config.ini" "$(TargetDir)" /Y</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<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' " />
|
||||
|
|
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 {
|
||||
class Entrypoint {
|
||||
static void Main(string[] args) {
|
||||
foreach()
|
||||
var server = new Kneesocks.Server<PlayerConnection>(6770, PoolManager.Pending);
|
||||
server.Start();
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ namespace Kneesocks {
|
|||
|
||||
private TcpClient Socket = null;
|
||||
private NetworkStream Stream = null;
|
||||
public Server Server { get; internal set; }
|
||||
|
||||
ReadBuffer Buffer;
|
||||
private byte[] FirstTwoBytes = null;
|
||||
|
@ -93,6 +94,7 @@ namespace Kneesocks {
|
|||
|
||||
Socket = conn.Socket;
|
||||
Stream = conn.Stream;
|
||||
Server = conn.Server;
|
||||
|
||||
Buffer = conn.Buffer;
|
||||
FirstTwoBytes = conn.FirstTwoBytes;
|
||||
|
|
|
@ -7,19 +7,12 @@ using System.Net.Sockets;
|
|||
using System.Net;
|
||||
|
||||
namespace Kneesocks {
|
||||
public class Server<T> where T : Connection, new() {
|
||||
private TcpListener Socket;
|
||||
private Thread Listener = null;
|
||||
private Pool<T> ConnectionPool = null;
|
||||
public bool Started { get; private set; } = false;
|
||||
public UInt16 Port { get; private 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 abstract class Server {
|
||||
protected TcpListener Socket;
|
||||
protected Thread Listener = null;
|
||||
public bool Started { get; protected set; } = false;
|
||||
public UInt16 Port { get; protected set; }
|
||||
public object Configuration { get; protected set; }
|
||||
|
||||
public void Start() {
|
||||
if(!Started) {
|
||||
|
@ -34,13 +27,26 @@ namespace Kneesocks {
|
|||
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();
|
||||
|
||||
while(Started) {
|
||||
if(Socket.Pending()) {
|
||||
var templatedConnection = new T();
|
||||
templatedConnection.Server = this;
|
||||
templatedConnection.Initialize(Socket.AcceptTcpClient());
|
||||
ConnectionPool.AddConnection(templatedConnection);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,43 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Square.INI {
|
||||
class Instance {
|
||||
private Dictionary<string, string> Data { get; set; }
|
||||
public class Instance : IEnumerable<KeyValuePair<string, Value>> {
|
||||
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;
|
||||
|
||||
namespace Square.INI {
|
||||
public class Section : IEnumerable {
|
||||
public class Section : IEnumerable<Instance> {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace Square.INI {
|
||||
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) {
|
||||
var lines = File.ReadAllLines(path);
|
||||
|
||||
string currentSection = null;
|
||||
foreach(var line in lines) {
|
||||
Instance currentInstance = null;
|
||||
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] {
|
||||
|
@ -30,5 +63,9 @@ namespace Square.INI {
|
|||
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\SectionRules.cs" />
|
||||
<Compile Include="INI\SettingsFile.cs" />
|
||||
<Compile Include="INI\Value.cs" />
|
||||
<Compile Include="NumericExtensions.cs" />
|
||||
<Compile Include="RandomContext.cs" />
|
||||
<Compile Include="StringExtensions.cs" />
|
||||
|
|
|
@ -29,5 +29,14 @@ namespace Square {
|
|||
|
||||
public static byte[] Base64DecodeRaw(this string 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