VACUUM DOT MATRIX MONTHLY

note on my desk
This commit is contained in:
Malloc of Kuzkycyziklistan 2017-09-12 15:59:55 -05:00
parent 4b1adda2a6
commit 978977282d
8 changed files with 91 additions and 36 deletions

View file

@ -283,19 +283,31 @@ Communication between the master server and clients will be done over a WebSocke
<td class="center">2</td>
<td>Message</td>
<td>String</td>
<td>R<sub>1</sub></td>
<td>&not;R<sub>1</sub></td>
</tr>
<tr>
<td class="center">2</td>
<td>Session Id</td>
<td>Packed Unsigned Long</td>
<td>&not;R<sub>1</sub></td>
<td>R<sub>1</sub></td>
</tr>
<tr>
<td class="center">3</td>
<td>Secret</td>
<td>Bytes (16)</td>
<td>&not;R<sub>1</sub></td>
<td>R<sub>1</sub></td>
</tr>
<tr>
<td class="center">4</td>
<td>Server Address</td>
<td>IPv4 String</td>
<td>R<sub>1</sub></td>
</tr>
<tr>
<td class="center">5</td>
<td>Server Port</td>
<td>Packed Unsigned Short</td>
<td>R<sub>1</sub></td>
</tr>
</table>
@ -345,25 +357,15 @@ Communication between the master server and clients will be done over a WebSocke
<td colspan="2">Iterated over <i>n</i> (0 &leq; <i>i</i> &leq; <i>n - 1</i>)</td>
</tr>
<tr>
<td class="center">2 + 4<i>i</i></td>
<td class="center">2 + 2<i>i</i></td>
<td>Server Id</td>
<td>Packed Unsigned Short</td>
</tr>
<tr>
<td class="center">3 + 4<i>i</i></td>
<td class="center">3 + 2<i>i</i></td>
<td>User Count</td>
<td>Packed Unsigned Short</td>
</tr>
<tr>
<td class="center">4 + 4<i>i</i></td>
<td>IP Address</td>
<td>IPv4 String</td>
</tr>
<tr>
<td class="center">5 + 4<i>i</i></td>
<td>Port</td>
<td>Packed Unsigned Short</td>
</tr>
</table>
#### Client to Master
@ -409,6 +411,11 @@ Communication between the master server and clients will be done over a WebSocke
<td>Password</td>
<td>String</td>
</tr>
<tr>
<td class="center">3</td>
<td>Server Id</td>
<td>Packed Unsigned Short</td>
</tr>
</table>
<table style="margin-right: 8px; margin-bottom: 8px;">

View file

@ -17,6 +17,13 @@ namespace SockScape.DAL {
[Required, Index(IsUnique = true)]
public byte[] Secret { get; set; }
[Required]
public DateTime LastPing { get; set; }
[NotMapped]
public TimeSpan DeltaLastPing
=> DateTime.UtcNow - LastPing;
[Required]
public int ServerId { get; set; }
}

View file

@ -171,9 +171,9 @@ namespace Kneesocks {
internal void Parse() {
if(Handshaked) {
if(!Buffer.IsReading) {
if(TimeSinceLastPing.Seconds > TimeoutInterval) {
if(TimeSinceLastPing.TotalSeconds > TimeoutInterval) {
Disconnect(Frame.kClosingReason.Normal, "Ping response timed out.");
} else if(TimeSinceLastPing.Seconds > PingInterval && !AwaitingPingResponse) {
} else if(TimeSinceLastPing.TotalSeconds > PingInterval && !AwaitingPingResponse) {
var frameBytes = new Frame {
IsFinal = true,
IsMasked = false,
@ -204,7 +204,7 @@ namespace Kneesocks {
if(Buffer.IsReading) {
readBuffer = Buffer.AttemptRead();
if(readBuffer == null) {
if((!Handshaked || (Handshaked && FirstTwoBytes != null)) && Buffer.ElapsedReadTime.Seconds > (Handshaked ? 300 : 30))
if((!Handshaked || (Handshaked && FirstTwoBytes != null)) && Buffer.ElapsedReadTime.TotalSeconds > (Handshaked ? 300 : 30))
Disconnect(Frame.kClosingReason.ProtocolError, "Timed out waiting for a full response");
return;

View file

@ -36,8 +36,7 @@ namespace SockScape {
var packet = new Packet(kInterMasterId.ServerListing, ((ushort)_Servers.Count).Pack());
foreach(var server in _Servers)
// TODO change this to support IPv6
packet.AddRegions(server.Key.Pack(), server.Value.UserCount.Pack(),
server.Value.Address.MapToIPv4().ToString(), server.Value.Port.Pack());
packet.AddRegions(server.Key.Pack(), server.Value.UserCount.Pack());
return packet;
}
@ -47,7 +46,7 @@ namespace SockScape {
public static void RemoveServersByOwners(IEnumerable<MasterIntraServer.Client> owners) {
lock(_Servers) {
_Servers = _Servers.Where(x => !owners.Contains(x.Value.Owner))
.ToDictionary(x => x.Key, x => x.Value);
.ToDictionary(x => x.Key, x => x.Value);
}
}

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Text;
@ -16,7 +17,7 @@ namespace SockScape {
protected override void OnOpen() {
Key = new Key();
Send(Key.GenerateRequestPacket().GetBytes());
Send(Key.GenerateRequestPacket());
}
protected override void OnParse() {
@ -49,11 +50,44 @@ namespace SockScape {
Encryptor = new StreamCipher(Key.PrivateKey);
break;
case kInterMasterId.LoginAttempt:
if(packet.RegionCount != 2)
if(packet.RegionCount != 3 || !packet.CheckRegions(2, 2))
break;
using(var db = new ScapeDb()) {
if(db.Users.)
User user;
if((user = db.Users.FirstOrDefault(x => x.Username == packet[0])) == null) {
SendEncrypted(new Packet(kInterMasterId.LoginAttempt, Convert.ToByte(false), "User does not exist."));
break;
}
if(!packet[1].Str.CheckPassword(user.Password)) {
SendEncrypted(new Packet(kInterMasterId.LoginAttempt, Convert.ToByte(false), "Password is incorrect."));
break;
}
if(user.Session?.DeltaLastPing.TotalMinutes < 3) {
SendEncrypted(new Packet(kInterMasterId.LoginAttempt, Convert.ToByte(false), "You are already logged in. Log out or try again shortly."));
break;
}
ushort server = packet[2].Raw.UnpackUInt16();
if(!MasterServerList.HasId(server)) {
SendEncrypted(new Packet(kInterMasterId.LoginAttempt, Convert.ToByte(false), "The world you have specified is offline."));
break;
}
if(user.Session?.DeltaLastPing.TotalMinutes >= 3) {
db.Entry(user.Session).State = EntityState.Deleted;
db.SaveChanges();
}
db.Sessions.Add(new Session {
Id = user.Id,
Secret = RNG.NextBytes(16),
ServerId = server,
LastPing = DateTime.UtcNow
});
db.SaveChanges();
}
break;
case kInterMasterId.RegistrationAttempt:
@ -68,5 +102,13 @@ namespace SockScape {
Console.WriteLine($"{Id} says {data.GetString()}");
}
private void Send(Packet packet) {
Send(packet.GetBytes());
}
private void SendEncrypted(Packet packet) {
Send(Encryptor.Parse(packet.GetBytes()));
}
}
}

View file

@ -20,11 +20,11 @@ namespace SockScape {
private static DateTime LastMessageOut = new DateTime(0);
private static TimeSpan DeltaLastOut
=> DateTime.Now - LastMessageOut;
=> DateTime.UtcNow - LastMessageOut;
private static DateTime LastMessageIn = new DateTime(0);
private static TimeSpan DeltaLastIn
=> DateTime.Now - LastMessageIn;
=> DateTime.UtcNow - LastMessageIn;
public static void Initialize() {
if(IsOpen || ListeningThread != null)
@ -52,7 +52,7 @@ namespace SockScape {
var endPoint = new IPEndPoint(IPAddress.Any, 0);
while(Sock.Available > 0) {
var data = Sock.Receive(ref endPoint);
LastMessageIn = DateTime.Now;
LastMessageIn = DateTime.UtcNow;
bool readRaw = Encryptor == null
|| data.Take(Packet.MagicNumber.Length).SequenceEqual(Packet.MagicNumber);
@ -108,7 +108,7 @@ namespace SockScape {
public static void Send(byte[] bytes) {
Sock.Send(bytes, bytes.Length);
LastMessageOut = DateTime.Now;
LastMessageOut = DateTime.UtcNow;
}
public static void Close() {

View file

@ -63,9 +63,9 @@ namespace SockScape {
}
if(IsProspectConnected(client) && encryptor == null)
Prospects[client].LastReceive = DateTime.Now;
Prospects[client].LastReceive = DateTime.UtcNow;
else if(IsClientConnected(client) && encryptor != null)
Clients[client].LastReceive = DateTime.Now;
Clients[client].LastReceive = DateTime.UtcNow;
switch((kIntraSlaveId)packet.Id) {
case kIntraSlaveId.InitiationAttempt:
@ -75,7 +75,7 @@ namespace SockScape {
if(packet[0] == Configuration.General["Master Secret"]) {
var key = new Key();
Prospects[client] = new Client {
LastReceive = DateTime.Now,
LastReceive = DateTime.UtcNow,
Address = endPoint,
Key = key
};
@ -90,7 +90,7 @@ namespace SockScape {
var privateKey = Prospects[client].Key.ParseResponsePacket(packet);
if(privateKey != -1) {
Prospects[client].LastReceive = DateTime.Now;
Prospects[client].LastReceive = DateTime.UtcNow;
Prospects[client].Encryptor = new BlockCipher(privateKey);
Clients[client] = Prospects[client];
Prospects.Remove(client);
@ -131,10 +131,10 @@ namespace SockScape {
}
}
Prospects = Prospects.Where(x => x.Value.ReceiveDelta.Seconds < 10)
Prospects = Prospects.Where(x => x.Value.ReceiveDelta.TotalSeconds < 10)
.ToDictionary(x => x.Key, x => x.Value);
var expiredClients = Clients.Where(x => x.Value.ReceiveDelta.Seconds > 60).Select(x => x.Value).ToList();
var expiredClients = Clients.Where(x => x.Value.ReceiveDelta.TotalSeconds > 60).Select(x => x.Value).ToList();
if(expiredClients.Count > 0)
MasterServerList.RemoveServersByOwners(expiredClients);
@ -180,7 +180,7 @@ namespace SockScape {
public class Client {
public IPEndPoint Address { get; set; }
public DateTime LastReceive { get; set; }
public TimeSpan ReceiveDelta => DateTime.Now - LastReceive;
public TimeSpan ReceiveDelta => DateTime.UtcNow - LastReceive;
public BlockCipher Encryptor { get; set; }
public Key Key { get; set; }
}

View file

@ -17,7 +17,7 @@ namespace SockScape {
}
protected override void OnParse() {
if((DateTime.UtcNow - ConnectionOpened).Seconds > 60) {
if((DateTime.UtcNow - ConnectionOpened).TotalSeconds > 60) {
Disconnect(Frame.kClosingReason.ProtocolError, "Logon request timed out.");
}
}