This repository has been archived on 2023-11-01. You can view files and clone it, but cannot push or open issues or pull requests.
autenticador-cliente/Main.cs

374 lines
14 KiB
C#

/*
MIT License
Copyright (c) 2020 luca0N!
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Contact me by e-mail via <mailto:luca0N@protonmail.com>.
*/
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Diagnostics;
namespace autenticador_do_luca0N
{
public partial class Main : Form
{
private static readonly string versionAddress = "http://<seu sítio>/adl/ver.txt";
private static readonly string getAddressUrl = "http://<seu sítio>/adl/ip.php";
private static readonly string dataDir = "./data";
private static readonly string configFile = $"{dataDir}/session.xml";
private static readonly string registerAccountAddress = "http://<seu sítio>/adl/v1/";
private static readonly string version = "v1.1";
private string tokenString, lastAddress;
private HttpClient httpClient;
private XmlDocument config;
public Main()
{
InitializeComponent();
}
private void Main_Load(object sender, EventArgs e)
{
log($"autenticador do luca0N! {version}\n", LogType.INFO);
log("21 de março de 2020, 01:09 (Horário de Brasília)\n", LogType.INFO);
log("Inicializando gestor de conexões...");
httpClient = new HttpClient();
}
private void Main_Closing(object sender, EventArgs e)
{
try { config.Save(configFile); } catch (XmlException) { }
}
private void Main_Shown(object sender, EventArgs e)
{
log("Limpando...");
if (Directory.Exists("./cache/"))
{
log("Limpando pasta desnecessária...");
foreach(string file in Directory.GetFiles("./cache/"))
{
log("Deletando um arquivo desnecessário...");
File.Delete(file);
}
log("Deletando pasta desnecessária...");
Directory.Delete("./cache/");
}
else
log("Não é necessário realizar uma limpeza.");
CheckForUpdates();
log("Verificando se há sessões existentes...", LogType.INFO);
if (!File.Exists(configFile))
{
log("Nenhuma sessão encontrada.", LogType.WARN);
if (!Directory.Exists(dataDir))
Directory.CreateDirectory(dataDir);
//File.Create(configFile);
//log("Arquivo de configurações criado.", LogType.INFO);
log("Gerando chave...", LogType.INFO);
ulong currentEpoch = GetCurrentTime();
Random rnd = new Random((int)(currentEpoch / 1000));
tokenString = rnd.Next().ToString();
log("Inicializando gestor de configurações...", LogType.INFO);
XmlDocument cfg = new XmlDocument();
log("Gerando propriedades...", LogType.INFO);
XmlElement root = cfg.CreateElement("adlCfg");
XmlElement token = cfg.CreateElement("token");
token.InnerText = tokenString;
token.SetAttribute("epoch", currentEpoch.ToString());
XmlElement target = cfg.CreateElement("target");
root.AppendChild(token);
cfg.AppendChild(root);
log("Salvando configurações...", LogType.INFO);
cfg.Save(configFile);
}
else
{
log("Sessão existente encontrada.", LogType.INFO);
}
log("Lendo configurações...\n", LogType.INFO);
config = new XmlDocument();
XmlElement lastAddrElement = null;
try
{
config.Load(configFile);
bool connected = false;
foreach (XmlNode element in config.DocumentElement)
{
switch (element.Name)
{
case "connected":
connected = true;
break;
case "token":
tokenString = element.InnerText;
log("Chave encontrada: " + tokenString);
break;
case "lastAddress":
lastAddress = element.InnerText;
lastAddrElement = (XmlElement) element;
log("Último endereço IP encontrado: " + lastAddress);
break;
}
}
if (!connected)
{
log("Conta não conectada!", LogType.INFO);
RegisterToken();
log("Tentando conectar-se ao servidor...");
string address;
log("Tentando obter endereço IP...");
WebClient wc = new WebClient();
address = wc.DownloadString(getAddressUrl);
wc.Dispose();
log("Endereço IP encontrado: " + address);
log("Procurando último endereço IP...");
if (lastAddress == address)
log("Endereço IP não alterado.");
else
{
lastAddress = address;
log("Endereço IP alterado. Atualizando...");
if (lastAddrElement == null)
{
log("Criando elemento de último endereço...");
lastAddrElement = config.CreateElement("lastAddress");
config.DocumentElement.AppendChild(lastAddrElement);
}
lastAddrElement.InnerText = address;
log("Atualizado.");
}
}
UpdateAddress();
}
catch (XmlException)
{
log("Erro ao ler as configurações!", LogType.ERR);
var result = MessageBox.Show("Impossível ler as configurações. Deseja redefinir este programa? Você vai precisar abrir este programa novamente.", "Erro", MessageBoxButtons.YesNo, MessageBoxIcon.Error);
if (result == DialogResult.Yes)
{
File.Delete(configFile);
log("Configurações redefinidas.", LogType.INFO);
Close();
}
}
}
private ulong GetCurrentTime()
{
return (ulong)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
}
private void log (string text, LogType logType = LogType.INFO)
{
richTextBox_console.Text += $"[{DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss")}] [{logType}] {text}\n";
}
private void button_update_Click(object sender, EventArgs e)
{
UpdateAddress();
}
private void UpdateAddress()
{
log("Checando endereço IP...");
WebClient wc = new WebClient();
string address;
try
{
address = wc.DownloadString(getAddressUrl);
}
catch (WebException)
{
log("Impossível conectar ao servidor principal.", LogType.ERR);
MessageBox.Show("Impossível conectar ao servidor principal. Certifique-se de que a sua conexão com a internet esteja boa e tente novamente.", "Falha na conexão", MessageBoxButtons.OK, MessageBoxIcon.Error);
wc.Dispose();
return;
}
wc.Dispose();
log("Endereço IP encontrado: " + address);
if (lastAddress == address)
{
log("Sem atualizações disponíveis.");
//MessageBox.Show("Seu endereço IP não alterou.", "Sem atualizações disponíveis", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
lastAddress = address;
foreach (XmlNode node in config.DocumentElement)
{
switch (node.Name)
{
case "lastAddress":
node.InnerText = address;
SendUpdateAddressRequest();
log("Endereço IP atualizado.");
config.Save(configFile);
break;
}
}
}
}
/// <summary>
/// Checks if there are any updates for this program available. Since March 21st, 2020, 16:24 (BRT).
/// </summary>
private void CheckForUpdates()
{
log("Checando atualizações...");
WebClient wc = new WebClient();
string[] verStr = wc.DownloadString(versionAddress).Split('\n');
string serverVersion = verStr[0],
file = verStr[1];
if (serverVersion != version)
{
log("Nova atualização encontrada.");
Updater updater = new Updater(this, serverVersion, file);
updater.Show();
Hide();
}
}
/// <summary>
/// Runs the downloaded setup file.
/// </summary>
public void RunUpdate(string version)
{
Process.Start($@".\cache\setup-{version}.exe");
Close();
}
private async Task SendUpdateAddressRequest()
{
var args = new Dictionary<string, string>
{
{ "action", "updateAddress" },
{ "token", tokenString }
};
var content = new FormUrlEncodedContent(args);
var response = await httpClient.PostAsync(registerAccountAddress, content);
var responseStr = await response.Content.ReadAsStringAsync();
if (responseStr == "OK")
{
log("Sucesso na atualização de endereço no servidor.");
}
}
private async Task RegisterToken()
{
try
{
//WebClient wcd = new WebClient();
//string requestResult = wcd.DownloadString(registerAccountAddress);
var args = new Dictionary<string, string>
{
{ "action", "registerToken" },
{ "token", tokenString }
};
var content = new FormUrlEncodedContent(args);
var response = await httpClient.PostAsync(registerAccountAddress, content);
var responseStr = await response.Content.ReadAsStringAsync();
if (responseStr == "OK")
{
log("Conta conectada");
MessageBox.Show("Sua conta foi registrada!", "Conectado", MessageBoxButtons.OK, MessageBoxIcon.Information);
var result = MessageBox.Show("Parece que você não se conectou com a sua conta Minecraft do servidor. Entre no servidor, e insira a seguinte chave: " + tokenString + ".\n\nAssim que você executar este comando, clique em OK. Você então poderá atualizar seu IP manualmente através deste programa.", "Conectar-se ao Minecraft", MessageBoxButtons.OK, MessageBoxIcon.Information);
if (result != DialogResult.OK)
{
log("Operação cancelada pelo usuário.", LogType.FATAL);
MessageBox.Show("Operação cancelada pelo usuário.", "Cancelado", MessageBoxButtons.OK, MessageBoxIcon.Error);
Close();
}
config.DocumentElement.AppendChild(config.CreateElement("connected"));
}
else
{
log("Impossível conectar conta.", LogType.ERR);
log($"Resposta do servidor: {responseStr}", LogType.ERR);
MessageBox.Show("Não foi possível registrar sua conta.", "Não conectado", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch (WebException)
{
log("Impossível conectar ao servidor principal.", LogType.ERR);
MessageBox.Show("Impossível conectar ao servidor principal. Certifique-se de que a sua conexão com a internet esteja boa e tente novamente.", "Falha na conexão", MessageBoxButtons.OK, MessageBoxIcon.Error);
Close();
return;
}
}
private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (Visible)
Hide();
else
Show();
}
private enum LogType
{
INFO, WARN, ERR, FATAL
}
}
}