This commit is contained in:
2022-04-19 00:05:16 +02:00
parent e7c2ae7b8d
commit d7f2348f0d
20 changed files with 924 additions and 49 deletions

View File

@@ -5,6 +5,7 @@
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<DebugType>embedded</DebugType>
<ApplicationIcon>..\doge.ico</ApplicationIcon>
<Title>Anime plan program</Title>
<Authors>ultrasn0w</Authors>
@@ -13,7 +14,6 @@
<Company>HANAMI</Company>
<TargetFramework>net6.0-windows10.0.22000.0</TargetFramework>
<LangVersion>10</LangVersion>
<SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion>
</PropertyGroup>
<ItemGroup>
@@ -22,10 +22,6 @@
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="6.0.1" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>

View File

@@ -2,9 +2,9 @@ using System.Text.Json.Serialization;
namespace APP.DTO;
public class SeasonAnime
public class Anime
{
[JsonPropertyName("anime")] public long Anime { get; set; }
[JsonPropertyName("anime")] public int AnimeId { get; set; }
[JsonPropertyName("title")] public string Title { get; set; }
@@ -18,23 +18,23 @@ public class SeasonAnime
[JsonPropertyName("imageThumb")] public string? ImageThumb { get; set; }
[JsonPropertyName("type")] public string Type { get; set; }
[JsonPropertyName("type")] public string? Type { get; set; }
[JsonPropertyName("status")] public string Status { get; set; }
[JsonPropertyName("episodes")] public int Episodes { get; set; }
[JsonPropertyName("episodes")] public int? Episodes { get; set; }
[JsonPropertyName("synopsis")] public string? Synopsis { get; set; }
[JsonPropertyName("synopsis")] public string Synopsis { get; set; }
[JsonPropertyName("genres")] public List<Genre>? Genres { get; set; }
[JsonPropertyName("startDate")] public DateTime StartDate { get; set; }
[JsonPropertyName("startDate")] public DateTime? StartDate { get; set; }
[JsonPropertyName("endDate")] public DateTime EndDate { get; set; }
[JsonPropertyName("endDate")] public DateTime? EndDate { get; set; }
[JsonPropertyName("year")] public int Year { get; set; }
[JsonPropertyName("year")] public int? Year { get; set; }
[JsonPropertyName("season")] public string SeasonString { get; set; }
[JsonPropertyName("season")] public string? Season { get; set; }
[JsonPropertyName("score")] public double Score { get; set; }

10
APP/DTO/Auth.cs Normal file
View File

@@ -0,0 +1,10 @@
using System.Text.Json.Serialization;
namespace APP.DTO;
public class Auth
{
[JsonPropertyName("username")] public string Username { get; set; }
[JsonPropertyName("secret")] public string Secret { get; set; }
}

14
APP/DTO/Register.cs Normal file
View File

@@ -0,0 +1,14 @@
using System.Text.Json.Serialization;
namespace APP.DTO;
public class Register
{
[JsonPropertyName("username")] public string Username { get; set; }
[JsonPropertyName("malId")] public long MalId { get; set; }
[JsonPropertyName("secret")] public string Secret { get; set; }
[JsonPropertyName("sauce")] public string Sauce { get; set; }
}

View File

@@ -12,7 +12,7 @@ public class User
[JsonPropertyName("imageUrl")] public string ImageUrl { get; set; }
[JsonPropertyName("lastOnline")] public DateTime LastOnline { get; set; }
[JsonPropertyName("lastOnline")] public DateTimeOffset LastOnline { get; set; }
[JsonPropertyName("gender")] public string? Gender { get; set; }

10
APP/DTO/Watch.cs Normal file
View File

@@ -0,0 +1,10 @@
using System.Text.Json.Serialization;
namespace APP.DTO;
public class Watch
{
[JsonPropertyName("anime")] public int Anime { get; set; }
[JsonPropertyName("users")] public List<WatchUser> WatchUsers { get; set; }
}

12
APP/DTO/WatchExtended.cs Normal file
View File

@@ -0,0 +1,12 @@
using System.Text.Json.Serialization;
namespace APP.DTO;
public class WatchExtended
{
[JsonPropertyName("anime")] public int Anime { get; set; }
[JsonPropertyName("users")] public List<User> Users { get; set; }
[JsonPropertyName("data")] public Anime Data { get; set; }
}

14
APP/DTO/WatchUser.cs Normal file
View File

@@ -0,0 +1,14 @@
using System.Text.Json.Serialization;
namespace APP.DTO;
public class WatchUser
{
[JsonPropertyName("username")] public string Username { get; set; }
[JsonPropertyName("malId")] public int MalId { get; set; }
[JsonPropertyName("progress")] public int? Progress { get; set; }
[JsonPropertyName("updated")] public DateTimeOffset? Updated { get; set; }
}

66
APP/LogWin.Designer.cs generated Normal file
View File

@@ -0,0 +1,66 @@
namespace APP
{
partial class LogWin
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.logBox = new System.Windows.Forms.RichTextBox();
this.SuspendLayout();
//
// logBox
//
this.logBox.BackColor = System.Drawing.Color.Black;
this.logBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.logBox.ForeColor = System.Drawing.Color.White;
this.logBox.Location = new System.Drawing.Point(0, 0);
this.logBox.Name = "logBox";
this.logBox.ReadOnly = true;
this.logBox.Size = new System.Drawing.Size(800, 450);
this.logBox.TabIndex = 0;
this.logBox.Text = "";
this.logBox.WordWrap = false;
//
// LogWin
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.logBox);
this.Name = "LogWin";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Log";
this.ResumeLayout(false);
}
#endregion
private RichTextBox logBox;
}
}

10
APP/LogWin.cs Normal file
View File

@@ -0,0 +1,10 @@
namespace APP;
public partial class LogWin : Form
{
public LogWin(string log)
{
InitializeComponent();
logBox.Text = log;
}
}

60
APP/LogWin.resx Normal file
View File

@@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

36
APP/Main.Designer.cs generated
View File

@@ -31,6 +31,7 @@
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Main));
this.tabControl = new System.Windows.Forms.TabControl();
this.tabUser = new System.Windows.Forms.TabPage();
this.userLabelInfoData = new System.Windows.Forms.Label();
this.userLinkLabel = new System.Windows.Forms.LinkLabel();
this.userLabelInfo = new System.Windows.Forms.Label();
this.userLabel = new System.Windows.Forms.Label();
@@ -41,7 +42,7 @@
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.memeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.loginToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.userLabelInfoData = new System.Windows.Forms.Label();
this.logToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.tabControl.SuspendLayout();
this.tabUser.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.userImage)).BeginInit();
@@ -76,6 +77,17 @@
this.tabUser.TabIndex = 0;
this.tabUser.Text = "YOURNAME";
//
// userLabelInfoData
//
this.userLabelInfoData.AutoSize = true;
this.userLabelInfoData.ForeColor = System.Drawing.SystemColors.Control;
this.userLabelInfoData.Location = new System.Drawing.Point(374, 76);
this.userLabelInfoData.Name = "userLabelInfoData";
this.userLabelInfoData.Size = new System.Drawing.Size(38, 15);
this.userLabelInfoData.TabIndex = 4;
this.userLabelInfoData.Text = "label1";
this.userLabelInfoData.Visible = false;
//
// userLinkLabel
//
this.userLinkLabel.AutoSize = true;
@@ -166,7 +178,8 @@
this.menuStrip.BackColor = System.Drawing.Color.Gray;
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.memeToolStripMenuItem,
this.loginToolStripMenuItem});
this.loginToolStripMenuItem,
this.logToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Size = new System.Drawing.Size(828, 24);
@@ -182,20 +195,16 @@
// loginToolStripMenuItem
//
this.loginToolStripMenuItem.Name = "loginToolStripMenuItem";
this.loginToolStripMenuItem.Size = new System.Drawing.Size(49, 20);
this.loginToolStripMenuItem.Text = "Login";
this.loginToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
this.loginToolStripMenuItem.Text = "Register";
this.loginToolStripMenuItem.Click += new System.EventHandler(this.loginToolStripMenuItem_Click);
//
// userLabelInfoData
// logToolStripMenuItem
//
this.userLabelInfoData.AutoSize = true;
this.userLabelInfoData.ForeColor = System.Drawing.SystemColors.Control;
this.userLabelInfoData.Location = new System.Drawing.Point(374, 76);
this.userLabelInfoData.Name = "userLabelInfoData";
this.userLabelInfoData.Size = new System.Drawing.Size(38, 15);
this.userLabelInfoData.TabIndex = 4;
this.userLabelInfoData.Text = "label1";
this.userLabelInfoData.Visible = false;
this.logToolStripMenuItem.Name = "logToolStripMenuItem";
this.logToolStripMenuItem.Size = new System.Drawing.Size(39, 20);
this.logToolStripMenuItem.Text = "Log";
this.logToolStripMenuItem.Click += new System.EventHandler(this.logToolStripMenuItem_Click);
//
// Main
//
@@ -235,5 +244,6 @@
private Label userLabelInfo;
private LinkLabel userLinkLabel;
private Label userLabelInfoData;
private ToolStripMenuItem logToolStripMenuItem;
}
}

View File

@@ -6,23 +6,53 @@ namespace APP;
public partial class Main : Form
{
private Auth? _auth;
private bool _authSucc;
private ImageList _imageListSeason;
private List<SeasonAnime>? _seasonAnime;
private List<Anime>? _seasonAnime;
private User? _user;
public Main()
{
InitializeComponent();
_imageListSeason = new ImageList();
Load += OnLoad;
Load += OnLoadEv;
}
private async void OnLoad(object? sender, EventArgs e)
private async void OnLoadEv(object? sender, EventArgs e)
{
await UpdateData();
_auth = await SaveBoy.ReadAuth();
if (_auth != null)
{
// check if we exist
var users = await BackendComms.GetUser();
if (users == null || users.All(u => u.Username != _auth.Username))
{
// We dont exist
SaveBoy.DeleteAuth();
_auth = null;
}
else
{
// try auth
if (await BackendComms.Auth(_auth.Username, _auth.Secret))
{
// Login successful
loginToolStripMenuItem.Visible = false;
_authSucc = true;
await UpdateUser();
}
else
{
_authSucc = false;
}
}
}
private async Task UpdateData()
await UpdateSeason();
}
private async Task UpdateSeason()
{
_seasonAnime = await BackendComms.GetSeason();
if (_seasonAnime == null)
@@ -40,8 +70,11 @@ public partial class Main : Form
});
}
}
}
_user = await BackendComms.GetUser("ultrasn0w");
private async Task UpdateUser()
{
_user = await BackendComms.GetUser(_auth?.Username);
if (_user == null)
{
ShowError("Fehler beim User abrufen");
@@ -57,21 +90,50 @@ public partial class Main : Form
userLabelInfo.Visible = true;
userLabelInfoData.Text = StringAssemble.UserData(_user);
userLabelInfoData.Visible = true;
if (!string.IsNullOrWhiteSpace(_user.ImageUrl))
{
userImage.LoadAsync(_user.ImageUrl);
}
}
}
private static void ShowError(string text)
{
MessageBox.Show(text, @"FEHLER", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
private void loginToolStripMenuItem_Click(object sender, EventArgs e)
private async void loginToolStripMenuItem_Click(object sender, EventArgs e)
{
// TODO search for user in backend
if (_authSucc) return;
var users = await BackendComms.GetUser();
if (DoRegister(users))
{
await UpdateUser();
}
}
private void userLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
private bool DoRegister(List<User>? users)
{
// Register promt
var regWin = new RegisterWin(_auth, users);
regWin.ShowDialog();
if (regWin.Cancelled)
{
regWin.Dispose();
return false;
}
_auth = new Auth
{
Username = regWin.Auth.Username,
Secret = regWin.Auth.Secret
};
loginToolStripMenuItem.Visible = false;
regWin.Dispose();
return true;
}
private async void userLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
if (string.IsNullOrWhiteSpace(_user?.Url)) return;
try
@@ -85,7 +147,14 @@ public partial class Main : Form
}
catch (Exception ex)
{
Console.Error.WriteLineAsync(ex.Message);
await Console.Error.WriteLineAsync(ex.Message);
}
}
private void logToolStripMenuItem_Click(object sender, EventArgs e)
{
var logWin = new LogWin(LogBoy.GetLog());
logWin.ShowDialog();
logWin.Dispose();
}
}

200
APP/RegisterWin.Designer.cs generated Normal file
View File

@@ -0,0 +1,200 @@
namespace APP
{
partial class RegisterWin
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.cancelButton = new System.Windows.Forms.Button();
this.okButton = new System.Windows.Forms.Button();
this.usernameBox = new System.Windows.Forms.TextBox();
this.secretBox = new System.Windows.Forms.TextBox();
this.secretBox2 = new System.Windows.Forms.TextBox();
this.labelMain = new System.Windows.Forms.Label();
this.labelSecret = new System.Windows.Forms.Label();
this.labelSecret2 = new System.Windows.Forms.Label();
this.checkUserButton = new System.Windows.Forms.Button();
this.pwcheckLabel = new System.Windows.Forms.Label();
this.pictureBox = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
this.SuspendLayout();
//
// cancelButton
//
this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.cancelButton.Location = new System.Drawing.Point(385, 166);
this.cancelButton.Name = "cancelButton";
this.cancelButton.Size = new System.Drawing.Size(75, 23);
this.cancelButton.TabIndex = 6;
this.cancelButton.Text = "Abbruch";
this.cancelButton.UseVisualStyleBackColor = true;
this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
//
// okButton
//
this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.okButton.Enabled = false;
this.okButton.Location = new System.Drawing.Point(304, 166);
this.okButton.Name = "okButton";
this.okButton.Size = new System.Drawing.Size(75, 23);
this.okButton.TabIndex = 5;
this.okButton.Text = "OK";
this.okButton.UseVisualStyleBackColor = true;
this.okButton.Click += new System.EventHandler(this.okButton_Click);
//
// usernameBox
//
this.usernameBox.Location = new System.Drawing.Point(12, 27);
this.usernameBox.Name = "usernameBox";
this.usernameBox.Size = new System.Drawing.Size(220, 23);
this.usernameBox.TabIndex = 1;
this.usernameBox.TextChanged += new System.EventHandler(this.usernameBox_TextChanged);
//
// secretBox
//
this.secretBox.Location = new System.Drawing.Point(12, 87);
this.secretBox.Name = "secretBox";
this.secretBox.PasswordChar = 'ඞ';
this.secretBox.Size = new System.Drawing.Size(220, 23);
this.secretBox.TabIndex = 3;
this.secretBox.TextChanged += new System.EventHandler(this.secretBox_TextChanged);
//
// secretBox2
//
this.secretBox2.Location = new System.Drawing.Point(12, 131);
this.secretBox2.Name = "secretBox2";
this.secretBox2.PasswordChar = 'ඞ';
this.secretBox2.Size = new System.Drawing.Size(220, 23);
this.secretBox2.TabIndex = 4;
this.secretBox2.TextChanged += new System.EventHandler(this.secretBox2_TextChanged);
//
// labelMain
//
this.labelMain.AutoSize = true;
this.labelMain.ForeColor = System.Drawing.SystemColors.Control;
this.labelMain.Location = new System.Drawing.Point(12, 9);
this.labelMain.Name = "labelMain";
this.labelMain.Size = new System.Drawing.Size(87, 15);
this.labelMain.TabIndex = 5;
this.labelMain.Text = "MAL username";
//
// labelSecret
//
this.labelSecret.AutoSize = true;
this.labelSecret.ForeColor = System.Drawing.SystemColors.Control;
this.labelSecret.Location = new System.Drawing.Point(12, 69);
this.labelSecret.Name = "labelSecret";
this.labelSecret.Size = new System.Drawing.Size(75, 15);
this.labelSecret.TabIndex = 6;
this.labelSecret.Text = "Neues Secret";
//
// labelSecret2
//
this.labelSecret2.AutoSize = true;
this.labelSecret2.ForeColor = System.Drawing.SystemColors.Control;
this.labelSecret2.Location = new System.Drawing.Point(12, 113);
this.labelSecret2.Name = "labelSecret2";
this.labelSecret2.Size = new System.Drawing.Size(91, 15);
this.labelSecret2.TabIndex = 7;
this.labelSecret2.Text = "Nochmal Secret";
//
// checkUserButton
//
this.checkUserButton.Enabled = false;
this.checkUserButton.Location = new System.Drawing.Point(238, 27);
this.checkUserButton.Name = "checkUserButton";
this.checkUserButton.Size = new System.Drawing.Size(75, 23);
this.checkUserButton.TabIndex = 2;
this.checkUserButton.Text = "Check";
this.checkUserButton.UseVisualStyleBackColor = true;
this.checkUserButton.Click += new System.EventHandler(this.checkUserButton_Click);
//
// pwcheckLabel
//
this.pwcheckLabel.AutoSize = true;
this.pwcheckLabel.Location = new System.Drawing.Point(238, 134);
this.pwcheckLabel.Name = "pwcheckLabel";
this.pwcheckLabel.Size = new System.Drawing.Size(19, 15);
this.pwcheckLabel.TabIndex = 9;
this.pwcheckLabel.Text = "❌";
//
// pictureBox
//
this.pictureBox.Location = new System.Drawing.Point(319, 12);
this.pictureBox.Name = "pictureBox";
this.pictureBox.Size = new System.Drawing.Size(140, 140);
this.pictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBox.TabIndex = 10;
this.pictureBox.TabStop = false;
this.pictureBox.Visible = false;
//
// RegisterWin
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.CancelButton = this.cancelButton;
this.ClientSize = new System.Drawing.Size(472, 201);
this.ControlBox = false;
this.Controls.Add(this.pictureBox);
this.Controls.Add(this.pwcheckLabel);
this.Controls.Add(this.checkUserButton);
this.Controls.Add(this.labelSecret2);
this.Controls.Add(this.labelSecret);
this.Controls.Add(this.labelMain);
this.Controls.Add(this.secretBox2);
this.Controls.Add(this.secretBox);
this.Controls.Add(this.usernameBox);
this.Controls.Add(this.okButton);
this.Controls.Add(this.cancelButton);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "RegisterWin";
this.ShowIcon = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Register";
((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Button cancelButton;
private Button okButton;
private TextBox usernameBox;
private TextBox secretBox;
private TextBox secretBox2;
private Label labelMain;
private Label labelSecret;
private Label labelSecret2;
private Button checkUserButton;
private Label pwcheckLabel;
private PictureBox pictureBox;
}
}

125
APP/RegisterWin.cs Normal file
View File

@@ -0,0 +1,125 @@
using APP.DTO;
using APP.Utility;
namespace APP;
public partial class RegisterWin : Form
{
private readonly Auth? _prevAuth;
private readonly List<User>? _users;
private bool _exist;
private bool _uChecked;
private User? _user;
public Auth Auth;
public bool Cancelled;
public RegisterWin(Auth? prevAuth, List<User>? existing)
{
_prevAuth = prevAuth;
_user = new User();
_users = existing;
Cancelled = true;
Auth = new Auth();
InitializeComponent();
Load += OnLoadEv;
}
private async Task<bool> PerformRegister(User user, Auth auth)
{
if (_exist)
{
// only try change login
return await BackendComms.Auth(auth.Username, auth.Secret);
}
var register = new Register
{
Username = user.Username,
MalId = user.Id,
Secret = auth.Secret,
Sauce = StringAssemble.CalcSauce(user.Id, user.Username)
};
var res = await BackendComms.Register(register);
return res != null;
}
private void OnLoadEv(object? sender, EventArgs e)
{
// check if we exist
if (_users == null || _users.All(u => u.Username != _prevAuth?.Username)) return;
_exist = true;
usernameBox.Name = _prevAuth?.Username;
}
private void cancelButton_Click(object sender, EventArgs e)
{
Cancelled = true;
Close();
}
private async void okButton_Click(object sender, EventArgs e)
{
if (_uChecked && _user != null && !string.IsNullOrEmpty(_user.Username) && !string.IsNullOrEmpty(secretBox.Text))
{
// PERFORM ACTUAL REGISTER
Auth = new Auth
{
Username = _user.Username,
Secret = StringAssemble.CalcSha512(secretBox.Text)
};
if (await PerformRegister(_user, Auth))
{
await SaveBoy.SaveAuth(Auth);
Cancelled = false;
}
else
{
MessageBox.Show(_exist ? @"Passwortänderung hat nicht geklappt -> Frag Admin" : @"Registrieren hat nicht geklappt", @"FEHLER", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Close();
}
private async void checkUserButton_Click(object sender, EventArgs e)
{
_user = await BackendComms.GetUser(usernameBox.Text);
if (_user == null || string.IsNullOrEmpty(_user.Username) || _user.Id == 0)
{
MessageBox.Show(@"Benutzer gibts nicht", @"FEHLER", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (!string.IsNullOrWhiteSpace(_user.ImageUrl))
{
pictureBox.LoadAsync(_user.ImageUrl);
pictureBox.Visible = true;
}
_exist = _users != null && _users.Any(u => u.Username == _user.Username);
MessageBox.Show($@"Hi {_user.Username} mit ID {_user.Id}", @"OK", MessageBoxButtons.OK, MessageBoxIcon.Information);
_uChecked = true;
}
private void usernameBox_TextChanged(object sender, EventArgs e)
{
_uChecked = false;
pictureBox.Visible = false;
checkUserButton.Enabled = !string.IsNullOrWhiteSpace(usernameBox.Text);
}
private void secretBox_TextChanged(object sender, EventArgs e)
{
var same = !string.IsNullOrWhiteSpace(secretBox.Text) && !string.IsNullOrWhiteSpace(secretBox2.Text) && secretBox.Text == secretBox2.Text;
pwcheckLabel.Text = same ? @"✅" : @"❌";
okButton.Enabled = _uChecked && same;
}
private void secretBox2_TextChanged(object sender, EventArgs e)
{
var same = !string.IsNullOrWhiteSpace(secretBox.Text) && !string.IsNullOrWhiteSpace(secretBox2.Text) && secretBox.Text == secretBox2.Text;
pwcheckLabel.Text = same ? @"✅" : @"❌";
okButton.Enabled = _uChecked && same;
}
}

60
APP/RegisterWin.resx Normal file
View File

@@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -1,4 +1,6 @@
using System.Net.Http.Json;
using System.Net.Mime;
using System.Text;
using System.Text.Json;
using APP.DTO;
@@ -7,25 +9,126 @@ namespace APP.Utility;
internal static class BackendComms
{
private const string ApiBaseUrl = "https://huso.hanami.family/api/";
private const string AuthHeader = "X-HUSO-AUTH";
private static readonly HttpClient Client = new();
private static readonly JsonSerializerOptions JsonSerializerOptions = new() {PropertyNameCaseInsensitive = true};
internal static async Task<List<SeasonAnime>?> GetSeason()
internal static async Task<List<Anime>?> GetSeason()
{
var resp = await Client.GetAsync(ApiBaseUrl + "season");
if (!resp.IsSuccessStatusCode) return null;
return await resp.Content.ReadFromJsonAsync<List<SeasonAnime>>(JsonSerializerOptions);
if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync<List<Anime>>(JsonSerializerOptions);
LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode);
return null;
}
internal static async Task<User?> GetUser(string username)
internal static async Task<bool> Auth(string username, string secret)
{
if (string.IsNullOrWhiteSpace(username))
{
return false;
}
using var msg = new HttpRequestMessage(HttpMethod.Get, ApiBaseUrl + "auth/" + username);
msg.Headers.Add(AuthHeader, secret);
var resp = await Client.SendAsync(msg);
if (!resp.IsSuccessStatusCode)
{
LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode);
}
return resp.IsSuccessStatusCode;
}
internal static async Task<Anime?> GetAnime(long animeId)
{
var resp = await Client.GetAsync(ApiBaseUrl + "anime/" + animeId);
if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync<Anime>(JsonSerializerOptions);
LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode);
return null;
}
internal static async Task<List<Anime>?> SearchAnime(string query)
{
var resp = await Client.GetAsync(ApiBaseUrl + "animesearch?q=" + query);
if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync<List<Anime>>(JsonSerializerOptions);
LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode);
return null;
}
internal static async Task<List<User>?> GetUser()
{
var resp = await Client.GetAsync(ApiBaseUrl + "user");
if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync<List<User>>(JsonSerializerOptions);
LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode);
return null;
}
internal static async Task<User?> GetUser(string? username)
{
if (string.IsNullOrWhiteSpace(username))
{
return null;
}
var resp = await Client.GetAsync(ApiBaseUrl + "user/"+username);
if (!resp.IsSuccessStatusCode) return null;
var resp = await Client.GetAsync(ApiBaseUrl + "user/" + username);
if (!resp.IsSuccessStatusCode)
{
LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode);
return null;
}
var users = await resp.Content.ReadFromJsonAsync<ICollection<User>>(JsonSerializerOptions);
return users?.SingleOrDefault();
}
internal static async Task<List<Watch>?> GetWatching()
{
var resp = await Client.GetAsync(ApiBaseUrl + "watch");
if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync<List<Watch>>(JsonSerializerOptions);
LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode);
return null;
}
internal static async Task<List<Watch>?> GetWatching(string? username)
{
if (string.IsNullOrWhiteSpace(username))
{
return null;
}
var resp = await Client.GetAsync(ApiBaseUrl + "watch/" + username);
if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync<List<Watch>>(JsonSerializerOptions);
LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode);
return null;
}
internal static async Task<List<WatchExtended>?> GetWatchingExtended()
{
var resp = await Client.GetAsync(ApiBaseUrl + "watchext");
if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync<List<WatchExtended>>(JsonSerializerOptions);
LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode);
return null;
}
internal static async Task<List<WatchExtended>?> GetWatchingExtended(string? username)
{
if (string.IsNullOrWhiteSpace(username))
{
return null;
}
var resp = await Client.GetAsync(ApiBaseUrl + "watchext/" + username);
if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync<List<WatchExtended>>(JsonSerializerOptions);
LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode);
return null;
}
internal static async Task<Register?> Register(Register register)
{
using var content = new StringContent(JsonSerializer.Serialize(register), Encoding.UTF8, MediaTypeNames.Application.Json);
using var resp = await Client.PostAsync(ApiBaseUrl + "register", content);
if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync<Register>(JsonSerializerOptions);
LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode);
return null;
}
}

20
APP/Utility/LogBoy.cs Normal file
View File

@@ -0,0 +1,20 @@
using System.Text;
namespace APP.Utility;
internal static class LogBoy
{
private static readonly StringBuilder Log = new();
internal static void AddToLog(string text)
{
Log.Append('[' + DateTime.Now.ToShortTimeString() + "] ");
Log.Append(text);
Log.AppendLine();
}
internal static string GetLog()
{
return Log.ToString();
}
}

77
APP/Utility/SaveBoy.cs Normal file
View File

@@ -0,0 +1,77 @@
using System.Text.Json;
using APP.DTO;
namespace APP.Utility;
internal static class SaveBoy
{
private static readonly string AuthFile = ".." + Path.DirectorySeparatorChar + "reg.json";
internal static async Task<Auth?> ReadAuth()
{
if (File.Exists(AuthFile))
{
return await ReadFromFile<Auth>(AuthFile);
}
return null;
}
internal static void DeleteAuth()
{
if (File.Exists(AuthFile))
{
File.Delete(AuthFile);
}
}
internal static async Task SaveAuth(Auth auth)
{
await WriteToFile(AuthFile, auth);
}
private static async Task WriteToFile<T>(string filePath, T objectToWrite)
{
try
{
await using var sw = new StreamWriter(filePath, false);
try
{
var res = JsonSerializer.Serialize(objectToWrite);
await sw.WriteAsync(res);
}
finally
{
sw.Close();
}
}
catch (Exception ex)
{
await Console.Error.WriteLineAsync(ex.Message);
}
}
private static async Task<T?> ReadFromFile<T>(string filePath)
{
try
{
using var sr = new StreamReader(filePath);
try
{
var text = await sr.ReadToEndAsync();
var res = JsonSerializer.Deserialize<T>(text);
return res;
}
finally
{
sr.Close();
}
}
catch (Exception ex)
{
await Console.Error.WriteLineAsync(ex.Message);
}
return default;
}
}

View File

@@ -1,11 +1,14 @@
using System.Security.Cryptography;
using System.Text;
using APP.DTO;
namespace APP.Utility;
public static class StringAssemble
internal static class StringAssemble
{
public static string UserInfo(User? user)
private const string RegisterSecret = "綾波レイ";
internal static string UserInfo(User? user)
{
if (user == null)
{
@@ -31,7 +34,7 @@ public static class StringAssemble
return sb.ToString();
}
public static string UserData(User? user)
internal static string UserData(User? user)
{
if (user == null)
{
@@ -56,4 +59,20 @@ public static class StringAssemble
return sb.ToString();
}
internal static string CalcSha512(string input)
{
var bytes = Encoding.UTF8.GetBytes(input);
using var hash = SHA512.Create();
var hashedInputBytes = hash.ComputeHash(bytes);
var hashedInputStringBuilder = new StringBuilder(128);
foreach (var b in hashedInputBytes)
hashedInputStringBuilder.Append(b.ToString("X2"));
return hashedInputStringBuilder.ToString().ToLower();
}
internal static string CalcSauce(long malId, string username)
{
return CalcSha512(RegisterSecret + malId + username);
}
}