SOON
PLEASE
This commit is contained in:
parent
ebe6fff43f
commit
c8d100da96
12 changed files with 167 additions and 70 deletions
File diff suppressed because one or more lines are too long
|
@ -1,2 +1 @@
|
||||||
!function(n){"use strict";function t(n,t){var r=(65535&n)+(65535&t),e=(n>>16)+(t>>16)+(r>>16);return e<<16|65535&r}function r(n,t){return n<<t|n>>>32-t}function e(n,e,o,u,c,f){return t(r(t(t(e,n),t(u,f)),c),o)}function o(n,t,r,o,u,c,f){return e(t&r|~t&o,n,t,u,c,f)}function u(n,t,r,o,u,c,f){return e(t&o|r&~o,n,t,u,c,f)}function c(n,t,r,o,u,c,f){return e(t^r^o,n,t,u,c,f)}function f(n,t,r,o,u,c,f){return e(r^(t|~o),n,t,u,c,f)}function i(n,r){n[r>>5]|=128<<r%32,n[(r+64>>>9<<4)+14]=r;var e,i,a,h,d,l=1732584193,g=-271733879,v=-1732584194,m=271733878;for(e=0;e<n.length;e+=16)i=l,a=g,h=v,d=m,l=o(l,g,v,m,n[e],7,-680876936),m=o(m,l,g,v,n[e+1],12,-389564586),v=o(v,m,l,g,n[e+2],17,606105819),g=o(g,v,m,l,n[e+3],22,-1044525330),l=o(l,g,v,m,n[e+4],7,-176418897),m=o(m,l,g,v,n[e+5],12,1200080426),v=o(v,m,l,g,n[e+6],17,-1473231341),g=o(g,v,m,l,n[e+7],22,-45705983),l=o(l,g,v,m,n[e+8],7,1770035416),m=o(m,l,g,v,n[e+9],12,-1958414417),v=o(v,m,l,g,n[e+10],17,-42063),g=o(g,v,m,l,n[e+11],22,-1990404162),l=o(l,g,v,m,n[e+12],7,1804603682),m=o(m,l,g,v,n[e+13],12,-40341101),v=o(v,m,l,g,n[e+14],17,-1502002290),g=o(g,v,m,l,n[e+15],22,1236535329),l=u(l,g,v,m,n[e+1],5,-165796510),m=u(m,l,g,v,n[e+6],9,-1069501632),v=u(v,m,l,g,n[e+11],14,643717713),g=u(g,v,m,l,n[e],20,-373897302),l=u(l,g,v,m,n[e+5],5,-701558691),m=u(m,l,g,v,n[e+10],9,38016083),v=u(v,m,l,g,n[e+15],14,-660478335),g=u(g,v,m,l,n[e+4],20,-405537848),l=u(l,g,v,m,n[e+9],5,568446438),m=u(m,l,g,v,n[e+14],9,-1019803690),v=u(v,m,l,g,n[e+3],14,-187363961),g=u(g,v,m,l,n[e+8],20,1163531501),l=u(l,g,v,m,n[e+13],5,-1444681467),m=u(m,l,g,v,n[e+2],9,-51403784),v=u(v,m,l,g,n[e+7],14,1735328473),g=u(g,v,m,l,n[e+12],20,-1926607734),l=c(l,g,v,m,n[e+5],4,-378558),m=c(m,l,g,v,n[e+8],11,-2022574463),v=c(v,m,l,g,n[e+11],16,1839030562),g=c(g,v,m,l,n[e+14],23,-35309556),l=c(l,g,v,m,n[e+1],4,-1530992060),m=c(m,l,g,v,n[e+4],11,1272893353),v=c(v,m,l,g,n[e+7],16,-155497632),g=c(g,v,m,l,n[e+10],23,-1094730640),l=c(l,g,v,m,n[e+13],4,681279174),m=c(m,l,g,v,n[e],11,-358537222),v=c(v,m,l,g,n[e+3],16,-722521979),g=c(g,v,m,l,n[e+6],23,76029189),l=c(l,g,v,m,n[e+9],4,-640364487),m=c(m,l,g,v,n[e+12],11,-421815835),v=c(v,m,l,g,n[e+15],16,530742520),g=c(g,v,m,l,n[e+2],23,-995338651),l=f(l,g,v,m,n[e],6,-198630844),m=f(m,l,g,v,n[e+7],10,1126891415),v=f(v,m,l,g,n[e+14],15,-1416354905),g=f(g,v,m,l,n[e+5],21,-57434055),l=f(l,g,v,m,n[e+12],6,1700485571),m=f(m,l,g,v,n[e+3],10,-1894986606),v=f(v,m,l,g,n[e+10],15,-1051523),g=f(g,v,m,l,n[e+1],21,-2054922799),l=f(l,g,v,m,n[e+8],6,1873313359),m=f(m,l,g,v,n[e+15],10,-30611744),v=f(v,m,l,g,n[e+6],15,-1560198380),g=f(g,v,m,l,n[e+13],21,1309151649),l=f(l,g,v,m,n[e+4],6,-145523070),m=f(m,l,g,v,n[e+11],10,-1120210379),v=f(v,m,l,g,n[e+2],15,718787259),g=f(g,v,m,l,n[e+9],21,-343485551),l=t(l,i),g=t(g,a),v=t(v,h),m=t(m,d);return[l,g,v,m]}function a(n){var t,r="",e=32*n.length;for(t=0;t<e;t+=8)r+=String.fromCharCode(n[t>>5]>>>t%32&255);return r}function h(n){var t,r=[];for(r[(n.length>>2)-1]=void 0,t=0;t<r.length;t+=1)r[t]=0;var e=8*n.length;for(t=0;t<e;t+=8)r[t>>5]|=(255&n.charCodeAt(t/8))<<t%32;return r}function d(n){return a(i(h(n),8*n.length))}function l(n,t){var r,e,o=h(n),u=[],c=[];for(u[15]=c[15]=void 0,o.length>16&&(o=i(o,8*n.length)),r=0;r<16;r+=1)u[r]=909522486^o[r],c[r]=1549556828^o[r];return e=i(u.concat(h(t)),512+8*t.length),a(i(c.concat(e),640))}function g(n){var t,r,e="0123456789abcdef",o="";for(r=0;r<n.length;r+=1)t=n.charCodeAt(r),o+=e.charAt(t>>>4&15)+e.charAt(15&t);return o}function v(n){return unescape(encodeURIComponent(n))}function m(n){return d(v(n))}function p(n){return g(m(n))}function s(n,t){return l(v(n),v(t))}function C(n,t){return g(s(n,t))}function A(n,t,r){return t?r?s(t,n):C(t,n):r?m(n):p(n)}"function"==typeof define&&define.amd?define(function(){return A}):"object"==typeof module&&module.exports?module.exports=A:n.md5=A}(this);
|
!function(n){"use strict";function t(n,t){var r=(65535&n)+(65535&t),e=(n>>16)+(t>>16)+(r>>16);return e<<16|65535&r}function r(n,t){return n<<t|n>>>32-t}function e(n,e,o,u,c,f){return t(r(t(t(e,n),t(u,f)),c),o)}function o(n,t,r,o,u,c,f){return e(t&r|~t&o,n,t,u,c,f)}function u(n,t,r,o,u,c,f){return e(t&o|r&~o,n,t,u,c,f)}function c(n,t,r,o,u,c,f){return e(t^r^o,n,t,u,c,f)}function f(n,t,r,o,u,c,f){return e(r^(t|~o),n,t,u,c,f)}function i(n,r){n[r>>5]|=128<<r%32,n[(r+64>>>9<<4)+14]=r;var e,i,a,h,d,l=1732584193,g=-271733879,v=-1732584194,m=271733878;for(e=0;e<n.length;e+=16)i=l,a=g,h=v,d=m,l=o(l,g,v,m,n[e],7,-680876936),m=o(m,l,g,v,n[e+1],12,-389564586),v=o(v,m,l,g,n[e+2],17,606105819),g=o(g,v,m,l,n[e+3],22,-1044525330),l=o(l,g,v,m,n[e+4],7,-176418897),m=o(m,l,g,v,n[e+5],12,1200080426),v=o(v,m,l,g,n[e+6],17,-1473231341),g=o(g,v,m,l,n[e+7],22,-45705983),l=o(l,g,v,m,n[e+8],7,1770035416),m=o(m,l,g,v,n[e+9],12,-1958414417),v=o(v,m,l,g,n[e+10],17,-42063),g=o(g,v,m,l,n[e+11],22,-1990404162),l=o(l,g,v,m,n[e+12],7,1804603682),m=o(m,l,g,v,n[e+13],12,-40341101),v=o(v,m,l,g,n[e+14],17,-1502002290),g=o(g,v,m,l,n[e+15],22,1236535329),l=u(l,g,v,m,n[e+1],5,-165796510),m=u(m,l,g,v,n[e+6],9,-1069501632),v=u(v,m,l,g,n[e+11],14,643717713),g=u(g,v,m,l,n[e],20,-373897302),l=u(l,g,v,m,n[e+5],5,-701558691),m=u(m,l,g,v,n[e+10],9,38016083),v=u(v,m,l,g,n[e+15],14,-660478335),g=u(g,v,m,l,n[e+4],20,-405537848),l=u(l,g,v,m,n[e+9],5,568446438),m=u(m,l,g,v,n[e+14],9,-1019803690),v=u(v,m,l,g,n[e+3],14,-187363961),g=u(g,v,m,l,n[e+8],20,1163531501),l=u(l,g,v,m,n[e+13],5,-1444681467),m=u(m,l,g,v,n[e+2],9,-51403784),v=u(v,m,l,g,n[e+7],14,1735328473),g=u(g,v,m,l,n[e+12],20,-1926607734),l=c(l,g,v,m,n[e+5],4,-378558),m=c(m,l,g,v,n[e+8],11,-2022574463),v=c(v,m,l,g,n[e+11],16,1839030562),g=c(g,v,m,l,n[e+14],23,-35309556),l=c(l,g,v,m,n[e+1],4,-1530992060),m=c(m,l,g,v,n[e+4],11,1272893353),v=c(v,m,l,g,n[e+7],16,-155497632),g=c(g,v,m,l,n[e+10],23,-1094730640),l=c(l,g,v,m,n[e+13],4,681279174),m=c(m,l,g,v,n[e],11,-358537222),v=c(v,m,l,g,n[e+3],16,-722521979),g=c(g,v,m,l,n[e+6],23,76029189),l=c(l,g,v,m,n[e+9],4,-640364487),m=c(m,l,g,v,n[e+12],11,-421815835),v=c(v,m,l,g,n[e+15],16,530742520),g=c(g,v,m,l,n[e+2],23,-995338651),l=f(l,g,v,m,n[e],6,-198630844),m=f(m,l,g,v,n[e+7],10,1126891415),v=f(v,m,l,g,n[e+14],15,-1416354905),g=f(g,v,m,l,n[e+5],21,-57434055),l=f(l,g,v,m,n[e+12],6,1700485571),m=f(m,l,g,v,n[e+3],10,-1894986606),v=f(v,m,l,g,n[e+10],15,-1051523),g=f(g,v,m,l,n[e+1],21,-2054922799),l=f(l,g,v,m,n[e+8],6,1873313359),m=f(m,l,g,v,n[e+15],10,-30611744),v=f(v,m,l,g,n[e+6],15,-1560198380),g=f(g,v,m,l,n[e+13],21,1309151649),l=f(l,g,v,m,n[e+4],6,-145523070),m=f(m,l,g,v,n[e+11],10,-1120210379),v=f(v,m,l,g,n[e+2],15,718787259),g=f(g,v,m,l,n[e+9],21,-343485551),l=t(l,i),g=t(g,a),v=t(v,h),m=t(m,d);return[l,g,v,m]}function a(n){var t,r="",e=32*n.length;for(t=0;t<e;t+=8)r+=String.fromCharCode(n[t>>5]>>>t%32&255);return r}function h(n){var t,r=[];for(r[(n.length>>2)-1]=void 0,t=0;t<r.length;t+=1)r[t]=0;var e=8*n.length;for(t=0;t<e;t+=8)r[t>>5]|=(255&n.charCodeAt(t/8))<<t%32;return r}function d(n){return a(i(h(n),8*n.length))}function l(n,t){var r,e,o=h(n),u=[],c=[];for(u[15]=c[15]=void 0,o.length>16&&(o=i(o,8*n.length)),r=0;r<16;r+=1)u[r]=909522486^o[r],c[r]=1549556828^o[r];return e=i(u.concat(h(t)),512+8*t.length),a(i(c.concat(e),640))}function g(n){var t,r,e="0123456789abcdef",o="";for(r=0;r<n.length;r+=1)t=n.charCodeAt(r),o+=e.charAt(t>>>4&15)+e.charAt(15&t);return o}function v(n){return unescape(encodeURIComponent(n))}function m(n){return d(v(n))}function p(n){return g(m(n))}function s(n,t){return l(v(n),v(t))}function C(n,t){return g(s(n,t))}function A(n,t,r){return t?r?s(t,n):C(t,n):r?m(n):p(n)}"function"==typeof define&&define.amd?define(function(){return A}):"object"==typeof module&&module.exports?module.exports=A:n.md5=A}(this);
|
||||||
//# sourceMappingURL=md5.min.js.map
|
|
1
client/lib/utf8.js
Normal file
1
client/lib/utf8.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
!function(a){function f(a){for(var e,f,b=[],c=0,d=a.length;c<d;)e=a.charCodeAt(c++),e>=55296&&e<=56319&&c<d?(f=a.charCodeAt(c++),56320==(64512&f)?b.push(((1023&e)<<10)+(1023&f)+65536):(b.push(e),c--)):b.push(e);return b}function g(a){for(var d,b=a.length,c=-1,f="";++c<b;)d=a[c],d>65535&&(d-=65536,f+=e(d>>>10&1023|55296),d=56320|1023&d),f+=e(d);return f}function h(a){if(a>=55296&&a<=57343)throw Error("Lone surrogate U+"+a.toString(16).toUpperCase()+" is not a scalar value")}function i(a,b){return e(a>>b&63|128)}function j(a){if(0==(4294967168&a))return e(a);var b="";return 0==(4294965248&a)?b=e(a>>6&31|192):0==(4294901760&a)?(h(a),b=e(a>>12&15|224),b+=i(a,6)):0==(4292870144&a)&&(b=e(a>>18&7|240),b+=i(a,12),b+=i(a,6)),b+=e(63&a|128)}function k(a){for(var e,b=f(a),c=b.length,d=-1,g="";++d<c;)e=b[d],g+=j(e);return g}function l(){if(p>=o)throw Error("Invalid byte index");var a=255&n[p];if(p++,128==(192&a))return 63&a;throw Error("Invalid continuation byte")}function m(){var a,b,c,d,e;if(p>o)throw Error("Invalid byte index");if(p==o)return!1;if(a=255&n[p],p++,0==(128&a))return a;if(192==(224&a)){var b=l();if((e=(31&a)<<6|b)>=128)return e;throw Error("Invalid continuation byte")}if(224==(240&a)){if(b=l(),c=l(),(e=(15&a)<<12|b<<6|c)>=2048)return h(e),e;throw Error("Invalid continuation byte")}if(240==(248&a)&&(b=l(),c=l(),d=l(),(e=(15&a)<<18|b<<12|c<<6|d)>=65536&&e<=1114111))return e;throw Error("Invalid UTF-8 detected")}function q(a){n=f(a),o=n.length,p=0;for(var c,b=[];!1!==(c=m());)b.push(c);return g(b)}var b="object"==typeof exports&&exports,c="object"==typeof module&&module&&module.exports==b&&module,d="object"==typeof global&&global;d.global!==d&&d.window!==d||(a=d);var n,o,p,e=String.fromCharCode,r={version:"2.0.0",encode:k,decode:q};if("function"==typeof define&&"object"==typeof define.amd&&define.amd)define(function(){return r});else if(b&&!b.nodeType)if(c)c.exports=r;else{var s={},t=s.hasOwnProperty;for(var u in r)t.call(r,u)&&(b[u]=r[u])}else a.utf8=r}(this);
|
5
client/src/UTF8.d.ts
vendored
Normal file
5
client/src/UTF8.d.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
declare class utf8 {
|
||||||
|
public static encode(str: string): string;
|
||||||
|
public static decode(byteStr: string): string;
|
||||||
|
public static version: string;
|
||||||
|
}
|
|
@ -9,10 +9,13 @@ using CircleScape.DAL;
|
||||||
namespace CircleScape {
|
namespace CircleScape {
|
||||||
class Entrypoint {
|
class Entrypoint {
|
||||||
static void Main(string[] args) {
|
static void Main(string[] args) {
|
||||||
var server = new Kneesocks.Server<PendingConnection>(6770, PoolManager.Pool);
|
var server = new Kneesocks.Server<PendingConnection>(6770, PoolManager.Pending);
|
||||||
server.Start();
|
server.Start();
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
|
var send = Console.ReadLine();
|
||||||
|
PoolManager.Pending.Broadcast(Encoding.UTF8.GetBytes(send));
|
||||||
|
|
||||||
// logic processing loop
|
// logic processing loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Square;
|
using Square;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace Kneesocks {
|
namespace Kneesocks {
|
||||||
public class Connection {
|
public class Connection {
|
||||||
|
@ -29,7 +30,10 @@ namespace Kneesocks {
|
||||||
private byte[] FirstTwoBytes = null;
|
private byte[] FirstTwoBytes = null;
|
||||||
private int ExtraHeaderSize = 0;
|
private int ExtraHeaderSize = 0;
|
||||||
private byte[] FrameHeader = null;
|
private byte[] FrameHeader = null;
|
||||||
private List<Frame> FrameBuffer = new List<Frame>();
|
private List<Frame> ReceiveFrameBuffer = new List<Frame>();
|
||||||
|
private List<Frame> SendFrameBuffer = new List<Frame>();
|
||||||
|
|
||||||
|
private DateTime LastPing;
|
||||||
|
|
||||||
public bool Disconnected { get; private set; } = false;
|
public bool Disconnected { get; private set; } = false;
|
||||||
public string DisconnectReason { get; private set; } = null;
|
public string DisconnectReason { get; private set; } = null;
|
||||||
|
@ -59,7 +63,7 @@ namespace Kneesocks {
|
||||||
FirstTwoBytes = conn.FirstTwoBytes;
|
FirstTwoBytes = conn.FirstTwoBytes;
|
||||||
ExtraHeaderSize = conn.ExtraHeaderSize;
|
ExtraHeaderSize = conn.ExtraHeaderSize;
|
||||||
FrameHeader = conn.FrameHeader;
|
FrameHeader = conn.FrameHeader;
|
||||||
FrameBuffer = conn.FrameBuffer;
|
ReceiveFrameBuffer = conn.ReceiveFrameBuffer;
|
||||||
|
|
||||||
Disconnected = conn.Disconnected;
|
Disconnected = conn.Disconnected;
|
||||||
DisconnectReason = conn.DisconnectReason;
|
DisconnectReason = conn.DisconnectReason;
|
||||||
|
@ -68,27 +72,89 @@ namespace Kneesocks {
|
||||||
ClientHandshake = conn.ClientHandshake;
|
ClientHandshake = conn.ClientHandshake;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReadIfNotNull(ref byte[] buffer, int length) {
|
private const int MaximumFrameSize = 0xFFFFF;
|
||||||
|
private void _Send(byte[] message, bool isFinal = true, bool singleFrame = false, bool first = false) {
|
||||||
|
int frameCount = singleFrame ? 0 : (message.Length / MaximumFrameSize);
|
||||||
|
for(var i = 0; i <= frameCount; ++i) {
|
||||||
|
SendFrameBuffer.Add(new Frame {
|
||||||
|
IsFinal = (i == frameCount && isFinal) ? true : false,
|
||||||
|
IsMasked = false,
|
||||||
|
Opcode = (i == 0 || (singleFrame && first)) ? Frame.kOpcode.BinaryFrame : Frame.kOpcode.Continuation,
|
||||||
|
Content = message.Subset(i * (MaximumFrameSize + 1), MaximumFrameSize)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Send(byte[] message) {
|
||||||
|
lock(SendFrameBuffer) {
|
||||||
|
_Send(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _Send(Stream stream, bool startingFrame = true) {
|
||||||
|
if(!Socket.Connected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool firstRead = true;
|
||||||
|
byte[] byteBuffer = new byte[MaximumFrameSize];
|
||||||
|
while(true) {
|
||||||
|
var bytesRead = stream.Read(byteBuffer, 0, MaximumFrameSize);
|
||||||
|
|
||||||
|
if(stream.Position == stream.Length) {
|
||||||
|
_Send(bytesRead == MaximumFrameSize ? byteBuffer : byteBuffer.Take(bytesRead).ToArray(), true, true, firstRead);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
_Send(bytesRead == MaximumFrameSize ? byteBuffer : byteBuffer.Take(bytesRead).ToArray(), false, true, firstRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
firstRead = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Send(Stream stream) {
|
||||||
|
lock(SendFrameBuffer) {
|
||||||
|
_Send(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Send(byte[] preamble, Stream stream) {
|
||||||
|
lock(SendFrameBuffer) {
|
||||||
|
_Send(preamble, false);
|
||||||
|
_Send(stream, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReadIfNotNull(ref byte[] buffer, int length) {
|
||||||
buffer = buffer == null ? Buffer.AttemptRead(length)
|
buffer = buffer == null ? Buffer.AttemptRead(length)
|
||||||
: buffer;
|
: buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReadIfNotNull(ref byte[] buffer, string terminator) {
|
private void ReadIfNotNull(ref byte[] buffer, string terminator) {
|
||||||
buffer = buffer == null ? Buffer.AttemptRead(terminator)
|
buffer = buffer == null ? Buffer.AttemptRead(terminator)
|
||||||
: buffer;
|
: buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Parse() {
|
public void Parse() {
|
||||||
if(!Stream.CanRead) {
|
if(Handshaked) {
|
||||||
Disconnected = true;
|
lock(SendFrameBuffer) {
|
||||||
return;
|
if(SendFrameBuffer.Count > 0) {
|
||||||
|
foreach(var frame in SendFrameBuffer) {
|
||||||
|
var frameBytes = frame.GetBytes();
|
||||||
|
Stream.Write(frameBytes, 0, frameBytes.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
SendFrameBuffer = new List<Frame>();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OnParse();
|
||||||
|
|
||||||
byte[] readBuffer = null;
|
byte[] readBuffer = null;
|
||||||
if(Buffer.IsReading) {
|
if(Buffer.IsReading) {
|
||||||
readBuffer = Buffer.AttemptRead();
|
readBuffer = Buffer.AttemptRead();
|
||||||
if(readBuffer == null) {
|
if(readBuffer == null) {
|
||||||
if(Buffer.ElapsedReadTime.Seconds > (Handshaked ? 300 : 30))
|
if((!Handshaked || (Handshaked && FirstTwoBytes != null)) && Buffer.ElapsedReadTime.Seconds > (Handshaked ? 300 : 30))
|
||||||
Disconnect(Frame.kClosingReason.ProtocolError, "Timed out waiting for a full response");
|
Disconnect(Frame.kClosingReason.ProtocolError, "Timed out waiting for a full response");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -106,6 +172,7 @@ namespace Kneesocks {
|
||||||
Stream.Write(response, 0, response.Length);
|
Stream.Write(response, 0, response.Length);
|
||||||
ClientHandshake = request;
|
ClientHandshake = request;
|
||||||
Handshaked = true;
|
Handshaked = true;
|
||||||
|
LastPing = DateTime.UtcNow;
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
Disconnect(Frame.kClosingReason.ProtocolError, e.Message);
|
Disconnect(Frame.kClosingReason.ProtocolError, e.Message);
|
||||||
return;
|
return;
|
||||||
|
@ -115,8 +182,6 @@ namespace Kneesocks {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OnParse();
|
|
||||||
|
|
||||||
if(FirstTwoBytes == null) {
|
if(FirstTwoBytes == null) {
|
||||||
ReadIfNotNull(ref readBuffer, 2);
|
ReadIfNotNull(ref readBuffer, 2);
|
||||||
if(readBuffer == null)
|
if(readBuffer == null)
|
||||||
|
@ -165,22 +230,38 @@ namespace Kneesocks {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameBuffer.Add(tempFrame);
|
ReceiveFrameBuffer.Add(tempFrame);
|
||||||
FirstTwoBytes = null;
|
FirstTwoBytes = null;
|
||||||
ExtraHeaderSize = 0;
|
ExtraHeaderSize = 0;
|
||||||
FrameHeader = null;
|
FrameHeader = null;
|
||||||
|
|
||||||
if(tempFrame.IsFinal) {
|
if(tempFrame.IsFinal) {
|
||||||
|
switch(tempFrame.Opcode) {
|
||||||
|
case Frame.kOpcode.Ping:
|
||||||
|
LastPing = DateTime.Now;
|
||||||
|
|
||||||
|
tempFrame.Opcode = Frame.kOpcode.Pong;
|
||||||
|
var pingBuffer = tempFrame.GetBytes();
|
||||||
|
Stream.Write(pingBuffer, 0, pingBuffer.Length);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Frame.kOpcode.Pong:
|
||||||
|
LastPing = DateTime.Now;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Frame.kOpcode.Close:
|
||||||
|
Disconnect(Frame.kClosingReason.Normal, "Connection closed.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
byte[] byteBuffer = new byte[0];
|
byte[] byteBuffer = new byte[0];
|
||||||
foreach(var frame in FrameBuffer)
|
foreach(var frame in ReceiveFrameBuffer)
|
||||||
byteBuffer = byteBuffer.Concat(frame.Content).ToArray();
|
byteBuffer = byteBuffer.Concat(frame.Content).ToArray();
|
||||||
|
|
||||||
FrameBuffer = new List<Frame>();
|
ReceiveFrameBuffer = new List<Frame>();
|
||||||
OnReceive(byteBuffer);
|
OnReceive(byteBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Disconnect(string reason = null) {
|
public void Disconnect(string reason = null) {
|
||||||
|
@ -194,7 +275,7 @@ namespace Kneesocks {
|
||||||
if(Socket.Connected) {
|
if(Socket.Connected) {
|
||||||
Socket.SendTimeout = 1000;
|
Socket.SendTimeout = 1000;
|
||||||
var raw = Handshaked ? Frame.Closing(status, reason).GetBytes()
|
var raw = Handshaked ? Frame.Closing(status, reason).GetBytes()
|
||||||
: Handshake.DenyRequest().ToString().GetBytes();
|
: Handshake.DenyRequest(message: reason).ToString().GetBytes();
|
||||||
Stream.Write(raw, 0, raw.Length);
|
Stream.Write(raw, 0, raw.Length);
|
||||||
Socket.Close();
|
Socket.Close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,15 +33,15 @@ namespace Kneesocks {
|
||||||
= new List<ThreadContext>();
|
= new List<ThreadContext>();
|
||||||
|
|
||||||
private long InternalCounter = 0;
|
private long InternalCounter = 0;
|
||||||
private Dictionary<UInt64, Connection> Connections
|
private Dictionary<UInt64, T> Connections
|
||||||
= new Dictionary<UInt64, Connection>();
|
= new Dictionary<UInt64, T>();
|
||||||
|
|
||||||
public Pool() {
|
public Pool() {
|
||||||
for(var i = 0; i < InitialCount; ++i)
|
for(var i = 0; i < InitialCount; ++i)
|
||||||
CreateThread(runWithNoClients: true);
|
CreateThread(runWithNoClients: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void IndexConnection(UInt64 id, Connection connection) {
|
private void IndexConnection(UInt64 id, T connection) {
|
||||||
lock(Connections) {
|
lock(Connections) {
|
||||||
if(id == 0)
|
if(id == 0)
|
||||||
id = (ulong)Interlocked.Increment(ref InternalCounter);
|
id = (ulong)Interlocked.Increment(ref InternalCounter);
|
||||||
|
@ -57,7 +57,14 @@ namespace Kneesocks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AddConnection(Connection connection, UInt64 id = 0) {
|
public void Broadcast(byte[] message) {
|
||||||
|
lock(Connections) {
|
||||||
|
foreach(var conn in Connections)
|
||||||
|
conn.Value.Send(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AddConnection(T connection, UInt64 id = 0) {
|
||||||
lock(Threads) {
|
lock(Threads) {
|
||||||
foreach(var thread in Threads) {
|
foreach(var thread in Threads) {
|
||||||
if(thread.Stack.Count < FullThreadSize) {
|
if(thread.Stack.Count < FullThreadSize) {
|
||||||
|
@ -87,7 +94,7 @@ namespace Kneesocks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ThreadContext CreateThread(Connection initialConnection = null, bool runWithNoClients = false) {
|
private ThreadContext CreateThread(T initialConnection = null, bool runWithNoClients = false) {
|
||||||
var stack = new Stack<T>(this, runWithNoClients, initialConnection);
|
var stack = new Stack<T>(this, runWithNoClients, initialConnection);
|
||||||
var ctx = new ThreadContext {
|
var ctx = new ThreadContext {
|
||||||
Stack = stack,
|
Stack = stack,
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace Kneesocks {
|
||||||
|
|
||||||
public TimeSpan ElapsedReadTime {
|
public TimeSpan ElapsedReadTime {
|
||||||
get {
|
get {
|
||||||
return DateTime.Now - StartTime;
|
return DateTime.UtcNow - StartTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ namespace Kneesocks {
|
||||||
IsReading = true;
|
IsReading = true;
|
||||||
ExpectedLength = length;
|
ExpectedLength = length;
|
||||||
ExpectedString = null;
|
ExpectedString = null;
|
||||||
StartTime = DateTime.Now;
|
StartTime = DateTime.UtcNow;
|
||||||
|
|
||||||
return AttemptRead();
|
return AttemptRead();
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ namespace Kneesocks {
|
||||||
|
|
||||||
IsReading = true;
|
IsReading = true;
|
||||||
ExpectedString = terminator;
|
ExpectedString = terminator;
|
||||||
StartTime = DateTime.Now;
|
StartTime = DateTime.UtcNow;
|
||||||
|
|
||||||
return AttemptRead();
|
return AttemptRead();
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace Kneesocks {
|
||||||
|
|
||||||
while(Started) {
|
while(Started) {
|
||||||
if(Socket.Pending())
|
if(Socket.Pending())
|
||||||
ConnectionPool.AddConnection(new Connection(Socket.AcceptTcpClient()));
|
ConnectionPool.AddConnection((T)new Connection(Socket.AcceptTcpClient()));
|
||||||
|
|
||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,23 +8,23 @@ using System.Threading;
|
||||||
namespace Kneesocks {
|
namespace Kneesocks {
|
||||||
public class Stack<T> where T : Connection {
|
public class Stack<T> where T : Connection {
|
||||||
private Pool<T> PoolRef = null;
|
private Pool<T> PoolRef = null;
|
||||||
private List<Connection> Clients = new List<Connection>();
|
private List<T> Clients = new List<T>();
|
||||||
private bool RunWithNoClients = false;
|
private bool RunWithNoClients = false;
|
||||||
private bool Running = true;
|
private bool Running = true;
|
||||||
|
|
||||||
public Stack(Pool<T> poolRef, Connection initialConnection = null) {
|
public Stack(Pool<T> poolRef, T initialConnection = null) {
|
||||||
PoolRef = poolRef;
|
PoolRef = poolRef;
|
||||||
if(initialConnection != null)
|
if(initialConnection != null)
|
||||||
Clients.Add(initialConnection);
|
Clients.Add(initialConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stack(Pool<T> poolRef, bool runWithNoClients, Connection initialConnection = null)
|
public Stack(Pool<T> poolRef, bool runWithNoClients, T initialConnection = null)
|
||||||
: this(poolRef, initialConnection)
|
: this(poolRef, initialConnection)
|
||||||
{
|
{
|
||||||
RunWithNoClients = runWithNoClients;
|
RunWithNoClients = runWithNoClients;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddClient(Connection client) {
|
public void AddClient(T client) {
|
||||||
lock(Clients) {
|
lock(Clients) {
|
||||||
Clients.Add(client);
|
Clients.Add(client);
|
||||||
}
|
}
|
||||||
|
@ -42,19 +42,38 @@ namespace Kneesocks {
|
||||||
|
|
||||||
public bool Finished { get; private set; }
|
public bool Finished { get; private set; }
|
||||||
|
|
||||||
|
public bool UnlistConnection(Connection connection) {
|
||||||
|
lock(Clients) {
|
||||||
|
foreach(var conn in Clients) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// USED FOR THREADING -- DO NOT CALL
|
// USED FOR THREADING -- DO NOT CALL
|
||||||
public void ManageStack() {
|
public void ManageStack() {
|
||||||
while(Running && (Count > 0 || RunWithNoClients)) {
|
while(Running && (Count > 0 || RunWithNoClients)) {
|
||||||
for(var i = Count - 1; i >= 0 && Running; --i) {
|
lock(Clients) {
|
||||||
var client = Clients[i];
|
for(var i = Count - 1; i >= 0 && Running; --i) {
|
||||||
if(!client.Disconnected)
|
var client = Clients[i];
|
||||||
client.Parse();
|
var connected = !client.Disconnected;
|
||||||
else {
|
|
||||||
lock(Clients) {
|
if(connected) {
|
||||||
|
try {
|
||||||
|
client.Parse();
|
||||||
|
} catch {
|
||||||
|
connected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!connected) {
|
||||||
|
PoolRef.InvalidateConnection(client.Id);
|
||||||
Clients.RemoveAt(i);
|
Clients.RemoveAt(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Thread.Sleep(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
Finished = true;
|
Finished = true;
|
||||||
|
|
|
@ -7,10 +7,14 @@ using System.Threading.Tasks;
|
||||||
namespace Square {
|
namespace Square {
|
||||||
public static class ArrayExtensions {
|
public static class ArrayExtensions {
|
||||||
public static T[] Subset<T>(this T[] arr, int offset, int count = -1) {
|
public static T[] Subset<T>(this T[] arr, int offset, int count = -1) {
|
||||||
if(count < 0)
|
var arrEnum = arr.AsEnumerable();
|
||||||
return arr.Skip(offset).ToArray();
|
|
||||||
else
|
if(offset > 0)
|
||||||
return arr.Skip(offset).Take(count).ToArray();
|
arrEnum = arrEnum.Skip(offset);
|
||||||
|
if(count > 0 && count < arr.Length)
|
||||||
|
arrEnum = arr.Take(count);
|
||||||
|
|
||||||
|
return arrEnum.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T[] Range<T>(this T[] arr, int start, int end) {
|
public static T[] Range<T>(this T[] arr, int start, int end) {
|
||||||
|
|
|
@ -10,11 +10,16 @@ namespace CircleScape {
|
||||||
static class PoolManager {
|
static class PoolManager {
|
||||||
private static Pool<PendingConnection> PendingConnectionsPool;
|
private static Pool<PendingConnection> PendingConnectionsPool;
|
||||||
private static Pool<ActiveConnection> ActiveConnectionsPool;
|
private static Pool<ActiveConnection> ActiveConnectionsPool;
|
||||||
public static Pool<PendingConnection> Pool {
|
public static Pool<PendingConnection> Pending {
|
||||||
get {
|
get {
|
||||||
return PendingConnectionsPool;
|
return PendingConnectionsPool;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static Pool<ActiveConnection> Active {
|
||||||
|
get {
|
||||||
|
return ActiveConnectionsPool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static PoolManager() {
|
static PoolManager() {
|
||||||
PendingConnectionsPool = new Pool<PendingConnection> {
|
PendingConnectionsPool = new Pool<PendingConnection> {
|
||||||
|
|
Loading…
Reference in a new issue