421 lines
16 KiB
C#
421 lines
16 KiB
C#
using System.Diagnostics;
|
|
using System.Net;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
using GraphicsManager;
|
|
using GraphicsManager.Enums;
|
|
using GraphicsManager.Interfaces;
|
|
using GraphicsManager.Objects;
|
|
using GraphicsManager.Objects.Core;
|
|
using Luski.GUI.MainScreen.Interfaces;
|
|
using Luski.GUI.MainScreen.UI;
|
|
using Luski.GUI.StartPage.UI;
|
|
using Luski.net;
|
|
using Luski.net.Enums;
|
|
using Luski.net.Interfaces;
|
|
using Luski.net.JsonTypes;
|
|
using OpenTK.Graphics.OpenGL4;
|
|
using OpenTK.Mathematics;
|
|
using OpenTK.Windowing.Desktop;
|
|
using OpenTK.Windowing.Common;
|
|
using Window = GraphicsManager.Window;
|
|
|
|
namespace Luski.GUI.MainScreen;
|
|
|
|
public class MainScreen : Window
|
|
{
|
|
private static readonly NativeWindowSettings Settings = new()
|
|
{
|
|
Title = "Luski Login",
|
|
WindowBorder = WindowBorder.Fixed,
|
|
APIVersion = new Version(3, 2),
|
|
StartFocused = true,
|
|
Size = new Vector2i((int)(240.5 * Globals.Settings.Scale), (int)(419 * Globals.Settings.Scale)),
|
|
Icon = Globals.Icon,
|
|
SharedContext = null
|
|
};
|
|
|
|
private TabControl tc;
|
|
private FlowLayout? channelpicker, friends, friend_request;
|
|
private RoundedButton? FriendManagerBtn;
|
|
public Chat? chat;
|
|
Login login;
|
|
CreateAccount ca;
|
|
private static DebugProc DebugMessageDelegate = OnDebugMessage;
|
|
private static void OnDebugMessage(
|
|
DebugSource source, // Source of the debugging message.
|
|
DebugType type, // Type of the debugging message.
|
|
int id, // ID associated with the message.
|
|
DebugSeverity severity, // Severity of the message.
|
|
int length, // Length of the string in pMessage.
|
|
IntPtr pMessage, // Pointer to message string.
|
|
IntPtr pUserParam) // The pointer you gave to OpenGL, explained later.
|
|
{
|
|
// In order to access the string pointed to by pMessage, you can use Marshal
|
|
// class to copy its contents to a C# string without unsafe code. You can
|
|
// also use the new function Marshal.PtrToStringUTF8 since .NET Core 1.1.
|
|
string message = Marshal.PtrToStringAnsi(pMessage, length);
|
|
|
|
// The rest of the function is up to you to implement, however a debug output
|
|
// is always useful.
|
|
|
|
return;
|
|
switch (severity)
|
|
{
|
|
case DebugSeverity.DebugSeverityHigh:
|
|
Console.ForegroundColor = ConsoleColor.DarkRed;
|
|
Console.WriteLine("[{0} source={1} type={2} id={3}] {4}", severity, source, type, id, message);
|
|
Console.ResetColor();
|
|
break;
|
|
case DebugSeverity.DebugSeverityMedium:
|
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
|
Console.WriteLine("[{0} source={1} type={2} id={3}] {4}", severity, source, type, id, message);
|
|
Console.ResetColor();
|
|
break;
|
|
default:
|
|
Console.ForegroundColor = ConsoleColor.Green;
|
|
Console.WriteLine(message);
|
|
Console.ResetColor();
|
|
break;
|
|
}
|
|
}
|
|
|
|
public MainScreen() : base(Settings)
|
|
{
|
|
VSync = VSyncMode.On;
|
|
GL.DebugMessageCallback(DebugMessageDelegate, IntPtr.Zero);
|
|
GL.Enable(EnableCap.DebugOutput);
|
|
Globals.DefaultFont =
|
|
Font.MakeEmbeddedFont("Luski.Resources.Fonts.OpenSans-Regular.ttf", Assembly.GetExecutingAssembly());
|
|
Globals.DefaultFont.PixelHeight = (uint)(12 * Globals.Settings.Scale);
|
|
//Font.MakeFontFromSystem((uint)(12 * Globals.Settings.Scale));
|
|
Globals.LuskiTexture = TextureManager.AddTexture(Tools.GetResourceBytes(Assembly.GetExecutingAssembly(),
|
|
"Luski.Resources.Textures.Luski.png"));
|
|
|
|
CenterWindow(0);
|
|
Controls.Add(ca = new CreateAccount());
|
|
ca.Visible = false;
|
|
ca.ChangeToApp += LoginOnChangeToApp;
|
|
Controls.Add(login = new Login());
|
|
|
|
login.ChangeToApp += LoginOnChangeToApp;
|
|
login.ChangeToCa += LoginOnChangeToCa;
|
|
|
|
Thread t = new(_ =>
|
|
{
|
|
Encryption.GenerateKeys();
|
|
|
|
});
|
|
t.Start();
|
|
WindowLoaded += OnWindowLoadedd;
|
|
}
|
|
|
|
private Task OnWindowLoadedd(Window arg)
|
|
{
|
|
Console.WriteLine(login.r.Location.Y);
|
|
Console.WriteLine(login.r.ScissorLocation.Y);
|
|
Console.WriteLine(login.r.Location.X);
|
|
Console.WriteLine(login.r.ScissorLocation.X);
|
|
return Task.CompletedTask;
|
|
}
|
|
private Task OnWindowLoaded(Window arg)
|
|
{
|
|
if (Globals.UpdaterSettings.AutoUpdateCheck && new HttpClient().GetAsync($"https://www.jacobtech.com/Updater/GetProgramVersion?directory=Luski&branch={Globals.UpdaterSettings.Branch}&selfcontained={Globals.UpdaterSettings.SelfContained.ToString().ToLower()}&platform={Globals.UpdaterSettings.Platform}").Result.Content.ReadAsStringAsync().Result != FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion)
|
|
{
|
|
var update = new UpdateWindow();
|
|
var result = update.ShowDialogue(this);
|
|
if (result == UpdateWindow.DialogueResult.Yes)
|
|
{
|
|
Globals.Download = true;
|
|
Close();
|
|
}
|
|
}
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private Task LoginOnChangeToCa()
|
|
{
|
|
Title = "Create Account";
|
|
ca.Visible = true;
|
|
login.Visible = false;
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public void AddGroup(SocketGroupChannel group)
|
|
{
|
|
Group friend = new(group);
|
|
friend.ClickCon += ChannelOnClickCon;
|
|
channelpicker!.Controls.Add(friend);
|
|
chans.Add(friend);
|
|
}
|
|
|
|
private readonly List<Friend> fr = new();
|
|
private List<IChannelPick> chans = new();
|
|
private Dictionary<long, int> FR_Index = new();
|
|
|
|
public void AddFriendRequest(SocketRemoteUser user)
|
|
{
|
|
FriendRequest frui = new(this, user);
|
|
FR_Index.Add(user.Id, friend_request!.Controls.Length);
|
|
friend_request.Controls.Add(frui);
|
|
}
|
|
|
|
public void RemoveFriendRequest(SocketRemoteUser user)
|
|
{
|
|
if (!FR_Index.ContainsKey(user.Id)) return;
|
|
friend_request!.Controls.Remove(friend_request!.Controls[FR_Index[user.Id]]);
|
|
}
|
|
|
|
public void AddFriend(SocketRemoteUser user)
|
|
{
|
|
Friend friend2 = new(user);
|
|
friend2.ClickCon += ChannelOnClickCon;
|
|
friends.Controls.Add(friend2);
|
|
if (user.Channel is not null)
|
|
{
|
|
Friend friend = new(user);
|
|
friend.ClickCon += ChannelOnClickCon;
|
|
fr.Add(friend);
|
|
channelpicker!.Controls.Add(friend);
|
|
chans.Add(friend);
|
|
}
|
|
}
|
|
|
|
private CancellationTokenSource? channelCancellationToken = null;
|
|
private async Task ChannelOnClickCon(IChannelPick arg)
|
|
{
|
|
try
|
|
{
|
|
BlockDraw = true;
|
|
Thread t = new(a => cc(a));
|
|
t.Start(arg);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine(e);
|
|
}
|
|
}
|
|
|
|
private void cc(object argg)
|
|
{
|
|
try
|
|
{
|
|
IChannelPick arg = (IChannelPick)argg;
|
|
Invoke(new Action(() =>
|
|
{
|
|
chat!.UpdateTitle(arg);
|
|
}));
|
|
Console.WriteLine("Checking token");
|
|
if (channelCancellationToken is not null)
|
|
{
|
|
Console.WriteLine("Cancling token");
|
|
channelCancellationToken.Cancel(false);
|
|
}
|
|
channelCancellationToken = new CancellationTokenSource();
|
|
Globals.Luski.ChangeChannel(arg.Channel.Id, channelCancellationToken.Token).Wait();
|
|
Invoke(new Action(() =>
|
|
{
|
|
chat!.Clear();
|
|
}));
|
|
IReadOnlyList<SocketMessage> messages = arg.Channel.GetMessages(channelCancellationToken.Token, Globals.Settings.LoadPerChannel).Result;
|
|
|
|
foreach (SocketMessage message in messages.Reverse())
|
|
{
|
|
if (channelCancellationToken is null || channelCancellationToken.Token.IsCancellationRequested) return;
|
|
Invoke(new Action(() =>
|
|
{
|
|
chat!.AddMessage(TextureManager, message);
|
|
}));
|
|
}
|
|
if (channelCancellationToken is null || channelCancellationToken.Token.IsCancellationRequested) return;
|
|
channelCancellationToken = null;
|
|
Invoke(new Action(() =>
|
|
{
|
|
BlockDraw = false;
|
|
chat!.MessageFlow.ScrollToBottom();
|
|
DrawFrame();
|
|
}));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
if (e.Message.Contains("A task was canceled")) return;
|
|
Console.WriteLine(e);
|
|
}
|
|
}
|
|
|
|
private Task LoginOnChangeToApp()
|
|
{
|
|
Controls.Clear();
|
|
BlockDraw = true;
|
|
Title = "Luski";
|
|
// string Public, Private;
|
|
// using (RSACryptoServiceProvider cryptoServiceProvider = new RSACryptoServiceProvider(Encryption.NewKeySize))
|
|
//{
|
|
// Private = cryptoServiceProvider.ToXmlString(true);
|
|
// Public = cryptoServiceProvider.ToXmlString(false);
|
|
//}
|
|
// Luski.net.Encryption.File.Channels.AddKey(69, Private);
|
|
//Clip
|
|
// Console.WriteLine(Public);
|
|
Globals.Luski.SetMultiThreadPercent(Globals.Settings.MultiThreadPercent);
|
|
Size = new((int)(1024 * Globals.Settings.Scale), (int)(667 * Globals.Settings.Scale));
|
|
DateTime start = DateTime.Now;
|
|
CenterWindow(0);
|
|
DateTime start1 = DateTime.Now;
|
|
WindowBorder = WindowBorder.Resizable;
|
|
BackgroundColor = new Color4(34, 34, 34, 255);
|
|
Controls.Add(new Rectangle(TextureManager.AddTexture(Globals.Luski.CurrentUser.GetAvatar(CancellationToken.None).Result, true)) { Anchor = ObjectAnchor.Bottom | ObjectAnchor.Left, Size = new((int)(35 * Globals.Settings.Scale)), Location = new((int)(47 * Globals.Settings.Scale), (int)(624 * Globals.Settings.Scale))});
|
|
Controls.Add(new Label(){ Font = Globals.DefaultFont, Anchor = ObjectAnchor.Bottom | ObjectAnchor.Left, Location = new((int)(86 * Globals.Settings.Scale), (int)(635.5 * Globals.Settings.Scale)), Text = Globals.Luski.CurrentUser.Username});
|
|
FlowLayout ser;
|
|
Controls.Add(chat = new() {Location = new((int)(270 * Globals.Settings.Scale),0)});
|
|
Controls.Add(ser = new FlowLayout()
|
|
{
|
|
BackgroundColor = new(26, 26, 26, 255),
|
|
Size = new((int)(40 * Globals.Settings.Scale),(int)(667 * Globals.Settings.Scale)),
|
|
Anchor = ObjectAnchor.Top | ObjectAnchor.Left | ObjectAnchor.Bottom,
|
|
|
|
});
|
|
Controls.Add(tc = new()// this is here to showcase my good friend TCLL
|
|
{
|
|
Location = chat.Location,
|
|
Size = chat.Size,
|
|
BackgroundColor = chat.BackgroundColor,
|
|
Anchor = ObjectAnchor.All,
|
|
Visible = false,
|
|
TitleFont = Globals.DefaultFont,
|
|
Border = (int)( 10 * Globals.Settings.Scale),
|
|
TabSpace = (int)(5 * Globals.Settings.Scale),
|
|
});
|
|
tc.AddPage("Friends", friends = new FlowLayout()
|
|
{
|
|
BackgroundColor = new(45,45,45,255)
|
|
});
|
|
tc.AddPage("Friend Request", friend_request = new FlowLayout()
|
|
{
|
|
BackgroundColor = new(45,45,45,255)
|
|
});
|
|
tc.AddPage("Add Friend", new AddFriendPage(this));
|
|
ser.Controls.Add(new Rectangle(Globals.LuskiTexture)
|
|
{
|
|
Size = new((int)(40 * Globals.Settings.Scale)),
|
|
});
|
|
Controls.Add(channelpicker = new FlowLayout()
|
|
{
|
|
BackgroundColor = new(34,34,34,255),
|
|
Size = new((int)(230 * Globals.Settings.Scale), (int)(616 * Globals.Settings.Scale)),
|
|
Location = new((int)(40 * Globals.Settings.Scale), 0),
|
|
Anchor = ObjectAnchor.Top | ObjectAnchor.Left | ObjectAnchor.Bottom
|
|
});
|
|
channelpicker.Controls.Add(FriendManagerBtn = new RoundedButton() { Font = Globals.DefaultFont, Text = "Friends", Size = new((int)(40* Globals.Settings.Scale)), InsideColor = new(28, 28, 28, 255), BorderColor = Color4.DarkCyan});
|
|
FriendManagerBtn.Clicked += FriendManagerBtnOnClicked;
|
|
Console.WriteLine("Templates loaded in " + (DateTime.Now - start).TotalSeconds + " seconds");
|
|
foreach (SocketGroupChannel ch in Globals.Luski.CurrentUser.Channels.Where(s => s is SocketGroupChannel).Cast<SocketGroupChannel>())
|
|
{
|
|
AddGroup(ch);
|
|
}
|
|
foreach (SocketRemoteUser item in Globals.Luski.CurrentUser.Friends)
|
|
{
|
|
if (item.Channel is not null) AddFriend(item);
|
|
}
|
|
Console.WriteLine("Channels done in " + (DateTime.Now - start).TotalSeconds + " seconds");
|
|
|
|
SocketTextChannel chan = Globals.Luski.GetChannel<SocketTextChannel>(Globals.Luski.CurrentUser.SelectedChannel, CancellationToken.None).Result;
|
|
chat.UpdateTitle(chans.First(s => s.Channel.Id == chan.Id));
|
|
chat.MessageFlow.BlockDraw = true;
|
|
try
|
|
{
|
|
IReadOnlyList<SocketMessage> messages = chan.GetMessages(CancellationToken.None, Globals.Settings.LoadPerChannel).Result;
|
|
Console.WriteLine("Messages done in " + (DateTime.Now - start).TotalSeconds + " seconds");
|
|
foreach (SocketMessage message in messages.Reverse())
|
|
{
|
|
chat.AddMessage(TextureManager, message);
|
|
}
|
|
chat.MessageFlow.ScrollToBottom();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine(e);
|
|
ChannelOnClickCon(chans.Where(s => s.Channel.Id == 0).First());
|
|
}
|
|
|
|
chat.MessageFlow.BlockDraw = false;
|
|
|
|
Console.WriteLine("Messages Fonts done in " + (DateTime.Now - start).TotalSeconds + " seconds");
|
|
foreach (SocketRemoteUser cufr in Globals.Luski.CurrentUser.FriendRequests)
|
|
{
|
|
AddFriendRequest(cufr);
|
|
}
|
|
Console.WriteLine("FR done in " + (DateTime.Now - start).TotalSeconds + " seconds");
|
|
BlockDraw = false;
|
|
DrawFrame();
|
|
Console.WriteLine("GUI done in " + (DateTime.Now - start1).TotalSeconds + " seconds");
|
|
MainShow += OnMainShow;
|
|
MainShow.Invoke();
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private Task OnMainShow()
|
|
{
|
|
Globals.Luski.OnError += LuskiOnOnError;
|
|
Globals.Luski.UserStatusUpdate += LuskiOnUserStatusUpdate;
|
|
Globals.Luski.ReceivedFriendRequest += LuskiOnReceivedFriendRequest;
|
|
Globals.Luski.FriendRequestResult += LuskiOnFriendRequestResult;
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public event Func<Task> MainShow;
|
|
|
|
private Task LuskiOnOnError(Exception arg)
|
|
{
|
|
Console.WriteLine(arg);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private Task LuskiOnFriendRequestResult(SocketRemoteUser arg1, bool arg2)
|
|
{
|
|
Console.WriteLine("new result");
|
|
Invoke(new Action(() =>
|
|
{
|
|
RemoveFriendRequest(arg1);
|
|
if (arg2) AddFriend(arg1);
|
|
}));
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private Task LuskiOnReceivedFriendRequest(SocketRemoteUser arg)
|
|
{
|
|
Invoke(new Action(() =>
|
|
{
|
|
AddFriendRequest(arg);
|
|
}));
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private Task LuskiOnUserStatusUpdate(IUser before, IUser After)
|
|
{
|
|
Console.WriteLine(before);
|
|
Console.WriteLine(After);
|
|
if (before is not SocketRemoteUser Before || Before.FriendStatus != FriendStatus.Friends || Before.Id == 0) return Task.CompletedTask;
|
|
Label stat = fr.Where(s => s.User.Id == before.Id).First()!.Status;
|
|
Invoke(new Action(() =>
|
|
{
|
|
stat.Text = After.Status.ToString();
|
|
}));
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private Task FriendManagerBtnOnClicked(IRenderObject arg)
|
|
{
|
|
if (chat.Visible)
|
|
{
|
|
chat.Visible = false;
|
|
tc.Visible = true;
|
|
}
|
|
else
|
|
{
|
|
chat.Visible = true;
|
|
tc.Visible = false;
|
|
}
|
|
return Task.CompletedTask;
|
|
}
|
|
} |