Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: json session store #29

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions src/TgSharp.Core/DataCenter.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
using System;

namespace TgSharp.Core
{
internal class DataCenter
public class DataCenter
{
internal DataCenter (int? dcId, string address, int port)
private const string defaultConnectionAddress = "149.154.175.100";//"149.154.167.50";
private const int defaultConnectionPort = 443;

[Obsolete("Do not use, this ctor is public only for serialization")]
public DataCenter()
{
DataCenterId = dcId;
Address = address;
Port = port;
}

internal DataCenter (string address, int port) : this (null, address, port)
internal DataCenter (int? dcId, string address = defaultConnectionAddress, int port = defaultConnectionPort)
{
DataCenterId = dcId;
Address = address;
Port = port;
}

internal int? DataCenterId { get; }
internal string Address { get; }
internal int Port { get; }
public int? DataCenterId { get; set; }
public string Address { get; set; }
public int Port { get; set; }
}
}
14 changes: 14 additions & 0 deletions src/TgSharp.Core/MTProto/Crypto/AuthKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ public class AuthKey
private byte[] key;
private ulong keyId;
private ulong auxHash;

[Obsolete("Do not use, this ctor is public only for serialization")]
public AuthKey()
{
}

public AuthKey(BigInteger gab)
{
key = gab.ToByteArrayUnsigned();
Expand Down Expand Up @@ -69,6 +75,10 @@ public byte[] Data
{
return key;
}
set
{
key = value;
}
}

public ulong Id
Expand All @@ -77,6 +87,10 @@ public ulong Id
{
return keyId;
}
set
{
keyId = value;
}
}

public override string ToString()
Expand Down
6 changes: 4 additions & 2 deletions src/TgSharp.Core/Network/MtProtoSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ public class MtProtoSender
//private ulong sessionId = GenerateRandomUlong();

private readonly TcpTransport transport;
private readonly ISessionStore sessionStore;
private readonly Session session;

public readonly List<ulong> needConfirmation = new List<ulong>();

public MtProtoSender(TcpTransport transport, Session session)
public MtProtoSender(TcpTransport transport, ISessionStore sessionStore, Session session)
{
this.transport = transport;
this.sessionStore = sessionStore;
this.session = session;
}

Expand Down Expand Up @@ -63,7 +65,7 @@ private int GenerateSequence(bool confirmed)
await Send(memory.ToArray(), request, token).ConfigureAwait(false);
}

session.Save();
sessionStore.Save (session);
}

public async Task Send(byte[] packet, TLMethod request, CancellationToken token = default(CancellationToken))
Expand Down
147 changes: 101 additions & 46 deletions src/TgSharp.Core/Session.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using System.IO;

using Newtonsoft.Json;
using TgSharp.TL;
using TgSharp.Core.MTProto;
using TgSharp.Core.MTProto.Crypto;
Expand All @@ -13,11 +13,16 @@ public interface ISessionStore
Session Load(string sessionUserId);
}

public class FileSessionStore : ISessionStore
[Obsolete("Use JsonFileSessionStore")]
public class FileSessionStore : BinaryFileSessionStore
{
}

public class BinaryFileSessionStore : ISessionStore
{
private readonly DirectoryInfo basePath;

public FileSessionStore(DirectoryInfo basePath = null)
public BinaryFileSessionStore(DirectoryInfo basePath = null)
{
if (basePath != null && !basePath.Exists)
{
Expand Down Expand Up @@ -58,6 +63,52 @@ public Session Load(string sessionUserId)
}
}

public class JsonFileSessionStore : ISessionStore
{
private readonly DirectoryInfo basePath;
private readonly JsonSerializerSettings jsonSerializerSettings;

internal static JsonFileSessionStore DefaultSessionStore ()
{
return new JsonFileSessionStore (null, new JsonSerializerSettings () {
Formatting = Formatting.Indented
});
}

public JsonFileSessionStore(DirectoryInfo basePath = null, JsonSerializerSettings jsonSerializerSettings = null)
{
if (basePath != null && !basePath.Exists)
{
throw new ArgumentException("basePath doesn't exist", nameof(basePath));
}

this.basePath = basePath;
this.jsonSerializerSettings = jsonSerializerSettings;
}

public void Save(Session session)
{
File.WriteAllText(GetSessionPath(session.SessionUserId), JsonConvert.SerializeObject(session, jsonSerializerSettings));
}

public Session Load(string sessionUserId)
{
string sessionPath = GetSessionPath(sessionUserId);

if (File.Exists(sessionPath))
{
return JsonConvert.DeserializeObject<Session> (File.ReadAllText (sessionPath), jsonSerializerSettings);
}

return null;
}

private string GetSessionPath(string sessionUserId)
{
return Path.Combine(basePath?.FullName ?? string.Empty, sessionUserId + ".json");
}
}

public class FakeSessionStore : ISessionStore
{
public void Save(Session session)
Expand All @@ -71,11 +122,32 @@ public Session Load(string sessionUserId)
}
}

public class Session
internal static class SessionFactory
{
private const string defaultConnectionAddress = "149.154.175.100";//"149.154.167.50";
private const int defaultConnectionPort = 443;
internal static Session TryLoadOrCreateNew (ISessionStore store, string sessionUserId)
{
var session = store.Load (sessionUserId);
if (null == session) {
var defaultDataCenter = new DataCenter (null);
session = new Session {
Id = GenerateRandomUlong (),
SessionUserId = sessionUserId,
DataCenter = defaultDataCenter,
};
}
return session;
}

private static ulong GenerateRandomUlong ()
{
var random = new Random ();
ulong rand = (((ulong)random.Next ()) << 32) | ((ulong)random.Next ());
return rand;
}
}

public class Session
{
public int Sequence { get; set; }
#if CI
// see the same CI-wrapped assignment in .FromBytes(), but this one will become useful
Expand All @@ -90,23 +162,30 @@ private static int CurrentTime ()
#endif

public string SessionUserId { get; set; }
internal DataCenter DataCenter { get; set; }
public DataCenter DataCenter { get; set; }
public AuthKey AuthKey { get; set; }
public ulong Id { get; set; }
public ulong Salt { get; set; }
public int TimeOffset { get; set; }
public long LastMessageId { get; set; }
public int SessionExpires { get; set; }
public TLUser TLUser { get; set; }
private Random random;

private ISessionStore store;

public Session(ISessionStore store)
{
random = new Random();
this.store = store;
public int UserId { get; set; }
private TLUser user = null;
public TLUser User {
get { return user; }
internal set {
user = value;
if (value != null) {
UserId = value.Id;
}
}
}
public bool AuthenticatedSuccessfully {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically we don't have to save UserId at all because we can just run GetSelfUser and If we're not authenticated we get an error

get { return UserId != default; }
}

private readonly Random random = new Random();

public byte[] ToBytes()
{
Expand All @@ -121,11 +200,11 @@ public byte[] ToBytes()
Serializers.String.Write(writer, DataCenter.Address);
writer.Write(DataCenter.Port);

if (TLUser != null)
if (AuthenticatedSuccessfully)
{
writer.Write(1);
writer.Write(SessionExpires);
ObjectUtils.SerializeObject(TLUser, writer);
ObjectUtils.SerializeObject (UserId, writer);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

writer.write(UserId);

}
else
{
Expand Down Expand Up @@ -160,17 +239,17 @@ public static Session FromBytes(byte[] buffer, ISessionStore store, string sessi

var isAuthExsist = reader.ReadInt32() == 1;
int sessionExpires = 0;
TLUser TLUser = null;
int userId = default;
if (isAuthExsist)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol that typo is not in my commit :P

{
sessionExpires = reader.ReadInt32();
TLUser = (TLUser)ObjectUtils.DeserializeObject(reader);
userId = (int)ObjectUtils.DeserializeObject (reader);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

userId = reader.ReadInt32();

}

var authData = Serializers.Bytes.Read(reader);
var defaultDataCenter = new DataCenter (serverAddress, port);
var defaultDataCenter = new DataCenter (null, serverAddress, port);

return new Session(store)
return new Session()
{
AuthKey = new AuthKey(authData),
Id = id,
Expand All @@ -179,37 +258,13 @@ public static Session FromBytes(byte[] buffer, ISessionStore store, string sessi
LastMessageId = lastMessageId,
TimeOffset = timeOffset,
SessionExpires = sessionExpires,
TLUser = TLUser,
UserId = userId,
SessionUserId = sessionUserId,
DataCenter = defaultDataCenter,
};
}
}

public void Save()
{
store.Save(this);
}

public static Session TryLoadOrCreateNew(ISessionStore store, string sessionUserId)
{
var defaultDataCenter = new DataCenter (defaultConnectionAddress, defaultConnectionPort);

return store.Load(sessionUserId) ?? new Session(store)
{
Id = GenerateRandomUlong(),
SessionUserId = sessionUserId,
DataCenter = defaultDataCenter,
};
}

private static ulong GenerateRandomUlong()
{
var random = new Random();
ulong rand = (((ulong)random.Next()) << 32) | ((ulong)random.Next());
return rand;
}

public long GetNewMessageId()
{
long time = Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds);
Expand Down
Loading