using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Net.Http; using System.Security.Cryptography; using System.Security.Principal; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; public class VpnLocation { public string id { get; set; } public string name { get; set; } public string country { get; set; } public string label { get; set; } public string username { get; set; } public string password_variable { get; set; } public string ovpn { get; set; } public override string ToString() { if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(country)) return name + " (" + country + ")"; return name ?? id ?? ""; } } public class vauth : IDisposable { private HttpClient _httpClient = new HttpClient(); //private string _apiBaseUrl = "https://velvetauth.com/api/1.1/"; private string _apiBaseUrl = "http://localhost/velvetauth/vauth-source/api/1.1/"; private System.Threading.Timer _heartbeatTimer; private System.Windows.Forms.Timer _watchTimer; private SynchronizationContext _uiContext; private int _heartbeatBusy; private bool _heartbeatReady; private const int HeartbeatIntervalMs = 3000; private string _appId; private string _secret; private string _version; public string _sessionId { get; private set; } public bool SessionKicked { get; private set; } public static vauth Instance { get; private set; } private EventHandler _sessionEnded; public event EventHandler SessionEnded { add { if (SynchronizationContext.Current != null) { _uiContext = SynchronizationContext.Current; } _sessionEnded += value; } remove { _sessionEnded -= value; } } public string Username { get; private set; } public string Email { get; private set; } public int user_level { get; private set; } public DateTime? ExpiryDate { get; private set; } public bool EmailVerificationRequired { get; private set; } public string VariableTitle { get; private set; } public string VariableValue { get; private set; } public List VpnLocations { get; private set; } = new List(); public string VpnId { get; private set; } public string VpnName { get; private set; } public string VpnCountry { get; private set; } public string VpnLabel { get; private set; } public string VpnUsername { get; private set; } public string VpnPasswordVariable { get; private set; } public string VpnOvpn { get; private set; } public int WebhookHttpCode { get; private set; } public string WebhookResponse { get; private set; } public string _hwid = WindowsIdentity.GetCurrent().User.Value; public vauth(string appId, string secret, string version) { Instance = this; _uiContext = SynchronizationContext.Current; _httpClient = new HttpClient(new HttpClientHandler { UseCookies = false }); _httpClient.Timeout = TimeSpan.FromSeconds(15); _appId = EncryptString(secret, appId); _secret = secret; _version = EncryptString(secret, version); } public HttpResponseMessage Post(string endpoint, object data) { var jsonData = JsonConvert.SerializeObject(data); var content = new StringContent(jsonData, Encoding.UTF8, "application/json"); MessageBox.Show($"Request URL: {_apiBaseUrl + endpoint}"); MessageBox.Show($"Request Data: {jsonData}"); try { HttpResponseMessage response = _httpClient.PostAsync(_apiBaseUrl + endpoint, content).Result; MessageBox.Show($"Response Status Code: {response.StatusCode}"); if (response != null && response.IsSuccessStatusCode) { return response; } return null; } catch (AggregateException ex) when (ex.InnerException is TaskCanceledException) { MessageBox.Show("Request timed out. The server may be slow sending email — try again or check SMTP on the web host."); return null; } catch (TaskCanceledException) { MessageBox.Show("Request timed out. The server may be slow sending email — try again or check SMTP on the web host."); return null; } catch (Exception ex) { MessageBox.Show("Request failed: " + ex.Message); return null; } } public bool Initialize() { if (!string.IsNullOrEmpty(_sessionId)) { return true; } var requestData = new { type = "init", app_id = _appId, secret = _secret, version = _version }; var response = Post("index.php", requestData); if (response != null && response.IsSuccessStatusCode) { var responseContent = response.Content.ReadAsStringAsync().Result; MessageBox.Show($"Raw Response Content for Initialization: {responseContent}"); try { dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); if (jsonResponse.status == "true") { _sessionId = Convert.ToString(jsonResponse.session_id); MessageBox.Show("Initialization Successful."); MessageBox.Show(jsonResponse); return true; } else if (jsonResponse.error != null && (string)jsonResponse.error == "wrong_version") { bool autoDownload = false; try { autoDownload = jsonResponse.auto_download == true || (jsonResponse.auto_download != null && jsonResponse.auto_download.ToString().ToLower() == "true"); } catch { } string fallbackUrl = jsonResponse.download_url != null ? (string)jsonResponse.download_url : ""; string fileName = jsonResponse.filename != null ? (string)jsonResponse.filename : "update.exe"; if (autoDownload) { DownloadUpdateFromApi(fileName); } else if (!string.IsNullOrEmpty(fallbackUrl)) { DownloadNewVersion(fallbackUrl); } else { MessageBox.Show("A new version is required, but no update file is uploaded yet."); } } else if (jsonResponse.error != null) { MessageBox.Show("Initialization failed: " + jsonResponse.error); } } catch (Exception ex) { MessageBox.Show("JSON Parsing error during initialization: " + ex.Message); } } else { MessageBox.Show("Initialization failed: HTTP " + (response?.StatusCode.ToString() ?? "No response")); } return false; } private void DownloadNewVersion(string url) { try { MessageBox.Show("Attempting to download new version from: " + url); Process.Start(new ProcessStartInfo { FileName = url, UseShellExecute = true }); MessageBox.Show("Download process started successfully."); } catch (Exception ex) { MessageBox.Show("Error starting download process: " + ex.Message); } } private void DownloadUpdateFromApi(string fileName) { try { if (string.IsNullOrEmpty(fileName)) { fileName = "update.exe"; } fileName = Path.GetFileName(fileName); string dest; using (SaveFileDialog dialog = new SaveFileDialog()) { dialog.Title = "Save new version"; dialog.FileName = fileName; dialog.OverwritePrompt = true; dialog.AddExtension = true; string ext = Path.GetExtension(fileName); if (!string.IsNullOrEmpty(ext)) { dialog.DefaultExt = ext.TrimStart('.'); dialog.Filter = ext.TrimStart('.').ToUpper() + " file (*" + ext + ")|*" + ext + "|All files (*.*)|*.*"; } else { dialog.Filter = "All files (*.*)|*.*"; } if (dialog.ShowDialog() != DialogResult.OK) { return; } dest = dialog.FileName; } var requestData = new { type = "download_update", app_id = _appId, secret = _secret }; var jsonData = JsonConvert.SerializeObject(requestData); var content = new StringContent(jsonData, Encoding.UTF8, "application/json"); using (var client = new HttpClient()) { client.Timeout = TimeSpan.FromMinutes(10); HttpResponseMessage response = client.PostAsync(_apiBaseUrl + "index.php", content).Result; if (response == null || !response.IsSuccessStatusCode) { MessageBox.Show("Could not download the new version from the API."); return; } string mediaType = response.Content.Headers.ContentType != null ? response.Content.Headers.ContentType.MediaType : ""; byte[] fileBytes = response.Content.ReadAsByteArrayAsync().Result; if (fileBytes == null || fileBytes.Length == 0) { MessageBox.Show("The update download was empty."); return; } if (!string.IsNullOrEmpty(mediaType) && mediaType.IndexOf("json", StringComparison.OrdinalIgnoreCase) >= 0) { MessageBox.Show("Update download failed: " + Encoding.UTF8.GetString(fileBytes)); return; } File.WriteAllBytes(dest, fileBytes); DialogResult openNow = MessageBox.Show( "New version saved to:\n" + dest + "\n\nOpen it now?", "Update downloaded", MessageBoxButtons.YesNo, MessageBoxIcon.Information); if (openNow == DialogResult.Yes) { Process.Start(new ProcessStartInfo { FileName = dest, UseShellExecute = true }); } } } catch (Exception ex) { MessageBox.Show("Error downloading new version: " + ex.Message); } } public bool keyless_register(string username, string password, string email) { var encryptedUsername = EncryptString(_secret, username); var encryptedPassword = EncryptString(_secret, password); var encryptedEmail = EncryptString(_secret, email); var encryptedHwid = EncryptString(_secret, _hwid); var requestData = new { type = "keyless", username = encryptedUsername, app_id = _appId, password = encryptedPassword, secret = _secret, email = encryptedEmail, hwid = encryptedHwid }; var response = Post("index.php", requestData); var responseContent = response.Content.ReadAsStringAsync().Result; MessageBox.Show($"Raw Response Content for Registration: {responseContent}"); try { dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); if (jsonResponse != null) { if (jsonResponse.message == "Registration successful") { EmailVerificationRequired = false; MessageBox.Show("Registration successful."); return true; } else if (jsonResponse.message == "Verification code sent") { EmailVerificationRequired = true; Username = username; Email = email; MessageBox.Show("Verification code sent. Check email, then call VerifyEmail."); return true; } else if (jsonResponse.message == "Username is already used") { MessageBox.Show("Registration failed: Username is already used."); } else if (jsonResponse.message == "Email is already used") { MessageBox.Show("Registration failed: Email is already used."); } else { MessageBox.Show("Registration failed: " + (jsonResponse.message ?? "Unknown error")); } } else { MessageBox.Show("No valid response received from API."); } } catch (Exception ex) { MessageBox.Show("JSON Parsing error during registration: " + ex.Message); } return false; } public bool RegisterLicense(string username, string password, string licenseKey, string email) { var encryptedUsername = EncryptString(_secret, username); var encryptedPassword = EncryptString(_secret, password); var encryptedLicenseKey = EncryptString(_secret, licenseKey); var encryptedEmail = EncryptString(_secret, email); var encryptedHwid = EncryptString(_secret, _hwid); var encryptedSID = EncryptString(_secret, _sessionId); var requestData = new { type = "register", username = encryptedUsername, app_id = _appId, password = encryptedPassword, secret = _secret, license_key = encryptedLicenseKey, email = encryptedEmail, hwid = encryptedHwid, session_id = encryptedSID }; var response = Post("index.php", requestData); var responseContent = response.Content.ReadAsStringAsync().Result; MessageBox.Show($"Raw Response Content for Registration: {responseContent}"); try { dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); if (jsonResponse != null) { if (jsonResponse.message == "Registration successful") { EmailVerificationRequired = false; Username = username; Email = jsonResponse.data.email; ExpiryDate = jsonResponse.data.expiry_date != null ? jsonResponse.data.expiry_date : (DateTime?)null; user_level = jsonResponse.data.user_level; StartHeartbeat(); MessageBox.Show("Registration successful."); return true; } else if (jsonResponse.message == "Verification code sent") { EmailVerificationRequired = true; Username = username; Email = email; MessageBox.Show("Verification code sent. Check email, then call VerifyEmail."); return true; } else { MessageBox.Show("Registration failed: " + jsonResponse.message); } } else { MessageBox.Show("No valid response received from API."); } } catch (Exception ex) { MessageBox.Show("JSON Parsing error during registration: " + ex.Message); } return false; } public bool Logout() { var encryptedSessionId = EncryptString(_secret, _sessionId); var encryptedAppId = _appId; var encryptedUsername = EncryptString(_secret, Username); var requestData = new { type = "logout", session_id = encryptedSessionId, app_id = encryptedAppId, secret = _secret, username = encryptedUsername }; var response = Post("index.php", requestData); var responseContent = response.Content.ReadAsStringAsync().Result; MessageBox.Show($"Raw Response Content for Logout: {responseContent}"); if (response.StatusCode == System.Net.HttpStatusCode.BadRequest) { MessageBox.Show("BadRequest Error: Check if all fields are correctly encrypted and match server expectations."); return false; } try { dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); string logoutMessage = jsonResponse != null && jsonResponse.message != null ? ((string)jsonResponse.message).Trim() : ""; if (logoutMessage.Equals("Logout successful", StringComparison.OrdinalIgnoreCase) || logoutMessage.Equals("logout successful", StringComparison.OrdinalIgnoreCase)) { StopHeartbeat(); SessionKicked = false; MessageBox.Show("Logout successful."); return true; } else { MessageBox.Show("Logout failed: " + (jsonResponse?.message ?? "Unknown error")); return false; } } catch (Exception ex) { MessageBox.Show("JSON Parsing error during logout: " + ex.Message); return false; } } public bool ChangeUsername(string currentPassword, string newUsername) { if (string.IsNullOrEmpty(_sessionId)) { MessageBox.Show("Change username failed: Call Initialize() first."); return false; } if (string.IsNullOrEmpty(Username)) { MessageBox.Show("Change username failed: Login first."); return false; } var requestData = new { type = "change_username", password = EncryptString(_secret, currentPassword), new_username = EncryptString(_secret, newUsername), app_id = _appId, secret = _secret, session_id = EncryptString(_secret, _sessionId) }; var response = Post("index.php", requestData); if (response == null) { MessageBox.Show("Change username failed: No response from server."); return false; } var responseContent = response.Content.ReadAsStringAsync().Result; MessageBox.Show($"Raw Response Content for Change Username: {responseContent}"); try { dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); if (jsonResponse != null && jsonResponse.message == "Username updated") { if (jsonResponse.data != null && jsonResponse.data.username != null) { Username = (string)jsonResponse.data.username; } else { Username = newUsername; } MessageBox.Show("Username updated."); return true; } MessageBox.Show("Change username failed: " + (jsonResponse?.message ?? jsonResponse?.error ?? "Unknown error")); } catch (Exception ex) { MessageBox.Show("JSON Parsing error during change username: " + ex.Message); } return false; } public bool ChangeEmail(string currentPassword, string newEmail) { if (string.IsNullOrEmpty(_sessionId)) { MessageBox.Show("Change email failed: Call Initialize() first."); return false; } if (string.IsNullOrEmpty(Username)) { MessageBox.Show("Change email failed: Login first."); return false; } var requestData = new { type = "change_email", password = EncryptString(_secret, currentPassword), new_email = EncryptString(_secret, newEmail), app_id = _appId, secret = _secret, session_id = EncryptString(_secret, _sessionId) }; var response = Post("index.php", requestData); if (response == null) { MessageBox.Show("Change email failed: No response from server."); return false; } var responseContent = response.Content.ReadAsStringAsync().Result; MessageBox.Show($"Raw Response Content for Change Email: {responseContent}"); try { dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); string message = jsonResponse != null && jsonResponse.message != null ? ((string)jsonResponse.message).Trim() : ""; if (message == "Email updated" || message == "Email updated. Verification code sent" || message == "Email updated but failed to send verification email") { if (jsonResponse.data != null && jsonResponse.data.email != null) { Email = (string)jsonResponse.data.email; } else { Email = newEmail; } EmailVerificationRequired = message != "Email updated"; MessageBox.Show(message == "Email updated" ? "Email updated." : message + "."); return true; } MessageBox.Show("Change email failed: " + (jsonResponse?.message ?? jsonResponse?.error ?? "Unknown error")); } catch (Exception ex) { MessageBox.Show("JSON Parsing error during change email: " + ex.Message); } return false; } public bool ChangePassword(string currentPassword, string newPassword) { if (string.IsNullOrEmpty(_sessionId)) { MessageBox.Show("Change password failed: Call Initialize() first."); return false; } if (string.IsNullOrEmpty(Username)) { MessageBox.Show("Change password failed: Login first."); return false; } var requestData = new { type = "change_password", password = EncryptString(_secret, currentPassword), new_password = EncryptString(_secret, newPassword), app_id = _appId, secret = _secret, session_id = EncryptString(_secret, _sessionId) }; var response = Post("index.php", requestData); if (response == null) { MessageBox.Show("Change password failed: No response from server."); return false; } var responseContent = response.Content.ReadAsStringAsync().Result; MessageBox.Show($"Raw Response Content for Change Password: {responseContent}"); try { dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); if (jsonResponse != null && jsonResponse.message == "Password updated") { MessageBox.Show("Password updated."); return true; } MessageBox.Show("Change password failed: " + (jsonResponse?.message ?? jsonResponse?.error ?? "Unknown error")); } catch (Exception ex) { MessageBox.Show("JSON Parsing error during change password: " + ex.Message); } return false; } public bool LoginUser(string username, string password) { var encryptedUsername = EncryptString(_secret, username); var encryptedPassword = EncryptString(_secret, password); var encryptedHwid = EncryptString(_secret, _hwid); var encryptedSessionId = EncryptString(_secret, _sessionId); var requestData = new { type = "login", username = encryptedUsername, password = encryptedPassword, hwid = encryptedHwid, app_id = _appId, secret = _secret, session_id = encryptedSessionId }; var response = Post("index.php", requestData); var responseContent = response.Content.ReadAsStringAsync().Result; MessageBox.Show($"Raw Response Content for Login: {responseContent}"); try { dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); if (jsonResponse != null) { if (jsonResponse.message == "Login successful") { Username = username; Email = jsonResponse.data.email; ExpiryDate = jsonResponse.data.expiry_date != null ? jsonResponse.data.expiry_date : (DateTime?)null; user_level = jsonResponse.data.user_level; StartHeartbeat(); MessageBox.Show("Login successful."); return true; } else { MessageBox.Show("Login failed: " + (jsonResponse.error ?? jsonResponse.message)); } } else { MessageBox.Show("No valid response received from API."); } } catch (Exception ex) { MessageBox.Show("JSON Parsing error during login: " + ex.Message); } return false; } public bool ForgotPassword(string email) { if (string.IsNullOrEmpty(_sessionId)) { MessageBox.Show("Forgot password failed: Call Initialize() first."); return false; } var encryptedEmail = EncryptString(_secret, email); var encryptedSessionId = EncryptString(_secret, _sessionId); var requestData = new { type = "forgot_password", email = encryptedEmail, app_id = _appId, secret = _secret, session_id = encryptedSessionId }; var response = Post("index.php", requestData); if (response == null) { MessageBox.Show("Forgot password failed: No response from server."); return false; } var responseContent = response.Content.ReadAsStringAsync().Result; MessageBox.Show($"Raw Response Content for Forgot Password: {responseContent}"); try { dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); if (jsonResponse != null && jsonResponse.message == "Password reset code sent") { MessageBox.Show("Password reset code sent to your email."); return true; } MessageBox.Show("Forgot password failed: " + (jsonResponse?.message ?? jsonResponse?.error ?? "Unknown error")); } catch (Exception ex) { MessageBox.Show("JSON Parsing error during forgot password: " + ex.Message); } return false; } public bool ResetPassword(string email, string code, string newPassword) { if (string.IsNullOrEmpty(_sessionId)) { MessageBox.Show("Reset password failed: Call Initialize() first."); return false; } var encryptedEmail = EncryptString(_secret, email); var encryptedCode = EncryptString(_secret, code); var encryptedPassword = EncryptString(_secret, newPassword); var encryptedSessionId = EncryptString(_secret, _sessionId); var requestData = new { type = "reset_password", email = encryptedEmail, code = encryptedCode, new_password = encryptedPassword, app_id = _appId, secret = _secret, session_id = encryptedSessionId }; var response = Post("index.php", requestData); if (response == null) { MessageBox.Show("Reset password failed: No response from server."); return false; } var responseContent = response.Content.ReadAsStringAsync().Result; MessageBox.Show($"Raw Response Content for Reset Password: {responseContent}"); try { dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); if (jsonResponse != null && jsonResponse.message == "Password reset successful") { MessageBox.Show("Password reset successful."); return true; } MessageBox.Show("Reset password failed: " + (jsonResponse?.message ?? jsonResponse?.error ?? "Unknown error")); } catch (Exception ex) { MessageBox.Show("JSON Parsing error during reset password: " + ex.Message); } return false; } public bool VerifyEmail(string email, string code) { if (string.IsNullOrEmpty(_sessionId)) { MessageBox.Show("Verify email failed: Call Initialize() first."); return false; } var encryptedEmail = EncryptString(_secret, email); var encryptedCode = EncryptString(_secret, code); var encryptedSessionId = EncryptString(_secret, _sessionId); var requestData = new { type = "verify_email", email = encryptedEmail, code = encryptedCode, app_id = _appId, secret = _secret, session_id = encryptedSessionId }; var response = Post("index.php", requestData); if (response == null) { MessageBox.Show("Verify email failed: No response from server."); return false; } var responseContent = response.Content.ReadAsStringAsync().Result; MessageBox.Show($"Raw Response Content for Verify Email: {responseContent}"); try { dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); if (jsonResponse != null && jsonResponse.message == "Email verified") { EmailVerificationRequired = false; Email = email; StartHeartbeat(); MessageBox.Show("Email verified."); return true; } MessageBox.Show("Verify email failed: " + (jsonResponse?.message ?? jsonResponse?.error ?? "Unknown error")); } catch (Exception ex) { MessageBox.Show("JSON Parsing error during verify email: " + ex.Message); } return false; } public bool ResendVerification(string email) { if (string.IsNullOrEmpty(_sessionId)) { MessageBox.Show("Resend verification failed: Call Initialize() first."); return false; } var encryptedEmail = EncryptString(_secret, email); var encryptedSessionId = EncryptString(_secret, _sessionId); var requestData = new { type = "resend_verification", email = encryptedEmail, app_id = _appId, secret = _secret, session_id = encryptedSessionId }; var response = Post("index.php", requestData); if (response == null) { MessageBox.Show("Resend verification failed: No response from server."); return false; } var responseContent = response.Content.ReadAsStringAsync().Result; MessageBox.Show($"Raw Response Content for Resend Verification: {responseContent}"); try { dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); if (jsonResponse != null && jsonResponse.message == "Verification code sent") { MessageBox.Show("Verification code sent to your email."); return true; } MessageBox.Show("Resend verification failed: " + (jsonResponse?.message ?? jsonResponse?.error ?? "Unknown error")); } catch (Exception ex) { MessageBox.Show("JSON Parsing error during resend verification: " + ex.Message); } return false; } public string GetVariable(string variableCode) { VariableTitle = ""; VariableValue = ""; if (string.IsNullOrEmpty(_sessionId) || string.IsNullOrEmpty(variableCode)) { return ""; } var encryptedCode = EncryptString(_secret, variableCode); var encryptedSessionId = EncryptString(_secret, _sessionId); var requestData = new { type = "get_variable", variable_code = encryptedCode, app_id = _appId, secret = _secret, session_id = encryptedSessionId }; try { var jsonData = JsonConvert.SerializeObject(requestData); var content = new StringContent(jsonData, Encoding.UTF8, "application/json"); HttpResponseMessage response = _httpClient.PostAsync(_apiBaseUrl + "index.php", content).Result; if (response == null || !response.IsSuccessStatusCode) { return ""; } var responseContent = response.Content.ReadAsStringAsync().Result; dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); if (jsonResponse != null && jsonResponse.message == "Variable found" && jsonResponse.data != null) { VariableTitle = jsonResponse.data.title != null ? (string)jsonResponse.data.title : ""; VariableValue = jsonResponse.data.value != null ? (string)jsonResponse.data.value : ""; return VariableValue ?? ""; } } catch { } return ""; } public List GetVpns() { VpnLocations = new List(); if (string.IsNullOrEmpty(_sessionId)) { return VpnLocations; } var encryptedSessionId = EncryptString(_secret, _sessionId); var requestData = new { type = "get_vpns", app_id = _appId, secret = _secret, session_id = encryptedSessionId }; try { var jsonData = JsonConvert.SerializeObject(requestData); var content = new StringContent(jsonData, Encoding.UTF8, "application/json"); HttpResponseMessage response = _httpClient.PostAsync(_apiBaseUrl + "index.php", content).Result; if (response == null || !response.IsSuccessStatusCode) { return VpnLocations; } var responseContent = response.Content.ReadAsStringAsync().Result; JObject jsonResponse = JObject.Parse(responseContent); string message = (string)jsonResponse["message"]; if (message == "VPNs found" || message == "No VPNs found") { if (jsonResponse["data"] != null) { VpnLocations = jsonResponse["data"].ToObject>() ?? new List(); } } } catch { } return VpnLocations; } public string GetVpn(string vpnId) { VpnId = ""; VpnName = ""; VpnCountry = ""; VpnLabel = ""; VpnUsername = ""; VpnPasswordVariable = ""; VpnOvpn = ""; if (string.IsNullOrEmpty(_sessionId) || string.IsNullOrEmpty(vpnId)) { return ""; } var encryptedVpnId = EncryptString(_secret, vpnId); var encryptedSessionId = EncryptString(_secret, _sessionId); var requestData = new { type = "get_vpn", vpn_id = encryptedVpnId, app_id = _appId, secret = _secret, session_id = encryptedSessionId }; try { var jsonData = JsonConvert.SerializeObject(requestData); var content = new StringContent(jsonData, Encoding.UTF8, "application/json"); HttpResponseMessage response = _httpClient.PostAsync(_apiBaseUrl + "index.php", content).Result; if (response == null || !response.IsSuccessStatusCode) { return ""; } var responseContent = response.Content.ReadAsStringAsync().Result; JObject jsonResponse = JObject.Parse(responseContent); if ((string)jsonResponse["message"] == "VPN found" && jsonResponse["data"] != null) { VpnLocation location = jsonResponse["data"].ToObject() ?? new VpnLocation(); VpnId = location.id ?? ""; VpnName = location.name ?? ""; VpnCountry = location.country ?? ""; VpnLabel = location.label ?? ""; VpnUsername = location.username ?? ""; VpnPasswordVariable = location.password_variable ?? ""; VpnOvpn = location.ovpn ?? ""; return VpnOvpn; } } catch { } return ""; } /// /// Fires a custom webhook configured in the dashboard (Webhooks page). /// Placeholders like {host}, {port}, {type}, {level} are filled from parameters. /// Requires Initialize() + LoginUser first. /// public bool SendWebhook(string webhookCode, Dictionary parameters = null) { WebhookHttpCode = 0; WebhookResponse = ""; if (string.IsNullOrEmpty(_sessionId) || string.IsNullOrEmpty(webhookCode)) { return false; } if (parameters == null) { parameters = new Dictionary(); } var encryptedCode = EncryptString(_secret, webhookCode); var encryptedSessionId = EncryptString(_secret, _sessionId); var encryptedParams = EncryptString(_secret, JsonConvert.SerializeObject(parameters)); var payload = new JObject { ["type"] = "send_webhook", ["webhook_code"] = encryptedCode, ["params"] = encryptedParams, ["app_id"] = _appId, ["secret"] = _secret, ["session_id"] = encryptedSessionId }; try { var jsonData = payload.ToString(Formatting.None); var content = new StringContent(jsonData, Encoding.UTF8, "application/json"); HttpResponseMessage response = _httpClient.PostAsync(_apiBaseUrl + "index.php", content).Result; if (response == null || !response.IsSuccessStatusCode) { return false; } var responseContent = response.Content.ReadAsStringAsync().Result; dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); if (jsonResponse != null && jsonResponse.message == "Webhook sent successfully") { if (jsonResponse.data != null) { WebhookHttpCode = jsonResponse.data.http_code != null ? (int)jsonResponse.data.http_code : 0; WebhookResponse = jsonResponse.data.response != null ? (string)jsonResponse.data.response : ""; } return true; } if (jsonResponse != null && jsonResponse.error != null) { WebhookResponse = (string)jsonResponse.error; if (jsonResponse.http_code != null) { WebhookHttpCode = (int)jsonResponse.http_code; } } } catch { } return false; } /// /// Convenience overload — pass any object that serializes to a JSON object of placeholders. /// Example: SendWebhook("start_server", new { host = "1.2.3.4", port = "25565", type = "survival", level = "1" }); /// public bool SendWebhook(string webhookCode, object parameters) { if (parameters == null) { return SendWebhook(webhookCode, (Dictionary)null); } var asDict = parameters as Dictionary; if (asDict != null) { return SendWebhook(webhookCode, asDict); } var token = JToken.FromObject(parameters); var map = new Dictionary(StringComparer.OrdinalIgnoreCase); var obj = token as JObject; if (obj != null) { foreach (var prop in obj.Properties()) { if (prop.Value == null || prop.Value.Type == JTokenType.Null) { map[prop.Name] = ""; } else if (prop.Value.Type == JTokenType.String) { map[prop.Name] = prop.Value.ToString(); } else { map[prop.Name] = prop.Value.ToString(Formatting.None); } } } return SendWebhook(webhookCode, map); } public bool Heartbeat() { if (string.IsNullOrEmpty(_sessionId)) { return false; } if (Interlocked.Exchange(ref _heartbeatBusy, 1) == 1) { return false; } try { var encryptedSessionId = EncryptString(_secret, _sessionId); var requestData = new { type = "heartbeat", app_id = _appId, secret = _secret, session_id = encryptedSessionId }; var jsonData = JsonConvert.SerializeObject(requestData); var content = new StringContent(jsonData, Encoding.UTF8, "application/json"); HttpResponseMessage response = _httpClient.PostAsync(_apiBaseUrl + "index.php", content).Result; if (response == null) { return !SessionKicked; } var responseContent = response.Content.ReadAsStringAsync().Result ?? ""; int jsonAt = responseContent.IndexOf('{'); if (jsonAt > 0) { responseContent = responseContent.Substring(jsonAt); } dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); string message = jsonResponse != null && jsonResponse.message != null ? ((string)jsonResponse.message).Trim() : ""; bool kicked = string.Equals(message, "Session kicked", StringComparison.OrdinalIgnoreCase); if (string.Equals(message, "Heartbeat ok", StringComparison.OrdinalIgnoreCase)) { _heartbeatReady = true; } if (kicked) { RaiseSessionKicked(); return false; } } catch { } finally { Interlocked.Exchange(ref _heartbeatBusy, 0); } return !SessionKicked; } private void RaiseSessionKicked() { if (SessionKicked) { return; } SessionKicked = true; StopHeartbeat(); RunOnUi(() => { MessageBox.Show("You've been kicked from the session.", "Session ended", MessageBoxButtons.OK, MessageBoxIcon.Warning); Environment.Exit(0); }); } private void RunOnUi(Action action) { if (action == null) { return; } Form target = null; foreach (Form form in Application.OpenForms) { if (form != null && !form.IsDisposed && form.IsHandleCreated && form.Visible) { target = form; break; } } if (target == null) { foreach (Form form in Application.OpenForms) { if (form != null && !form.IsDisposed && form.IsHandleCreated) { target = form; break; } } } if (target != null) { target.BeginInvoke(action); return; } if (_uiContext != null) { _uiContext.Post(_ => action(), null); return; } action(); } public void WatchSession() { SessionKicked = false; _uiContext = SynchronizationContext.Current ?? _uiContext; StopHeartbeat(); Task.Run(() => { try { Heartbeat(); } catch { } }); _watchTimer = new System.Windows.Forms.Timer(); _watchTimer.Interval = HeartbeatIntervalMs; _watchTimer.Tick += WatchTimer_Tick; _watchTimer.Start(); } private void WatchTimer_Tick(object sender, EventArgs e) { Task.Run(() => { try { Heartbeat(); } catch { } }); } private void StartHeartbeat() { SessionKicked = false; _heartbeatReady = false; _uiContext = SynchronizationContext.Current ?? _uiContext; StopHeartbeat(); _heartbeatTimer = new System.Threading.Timer(_ => { try { Heartbeat(); } catch { } }, null, HeartbeatIntervalMs, HeartbeatIntervalMs); } private void StopHeartbeat() { if (_heartbeatTimer != null) { _heartbeatTimer.Dispose(); _heartbeatTimer = null; } if (_watchTimer != null) { _watchTimer.Stop(); _watchTimer.Tick -= WatchTimer_Tick; _watchTimer.Dispose(); _watchTimer = null; } } public bool ExtendLicenseExpiry(string username, string licenseKey) { var encryptedUsername = EncryptString(_secret, username); var encryptedLicenseKey = EncryptString(_secret, licenseKey); var encryptedAppId = _appId; var requestData = new { type = "extend_expiry", username = encryptedUsername, license_key = encryptedLicenseKey, app_id = encryptedAppId, secret = _secret }; var response = Post("index.php", requestData); var responseContent = response.Content.ReadAsStringAsync().Result; MessageBox.Show($"Raw Response Content for License Extension: {responseContent}"); try { dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); if (jsonResponse != null) { if (jsonResponse.message == "License expiry extended successfully") { ExpiryDate = jsonResponse.data.new_expiry_date; MessageBox.Show("License expiry extended successfully."); return true; } else { MessageBox.Show("License extension failed: " + jsonResponse.message); } } else { MessageBox.Show("No valid response received from API."); } } catch (Exception ex) { MessageBox.Show("JSON Parsing error during license extension: " + ex.Message); } return false; } public bool Log(string message) { var requestData = new { type = "log", app_id = _appId, secret = _secret, message = EncryptString(_secret, message) }; var response = Post("index.php", requestData); if (response == null) { MessageBox.Show("Log failed: No response from server."); return false; } var responseContent = response.Content.ReadAsStringAsync().Result; MessageBox.Show($"Raw Response Content for Log: {responseContent}"); try { dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); if (jsonResponse != null && jsonResponse.message == "Log sent to Discord") { MessageBox.Show("Log sent successfully."); return true; } else { MessageBox.Show("Log failed: " + (jsonResponse?.error ?? "Unknown error")); } } catch (Exception ex) { MessageBox.Show("JSON Parsing error during log: " + ex.Message); } return false; } private static readonly object EncryptLock = new object(); public static string EncryptString(string keyHex, string plainText) { lock (EncryptLock) { byte[] key = StringToByteArray(keyHex); byte[] iv; using (Aes aesAlg = Aes.Create()) { aesAlg.Key = key; aesAlg.GenerateIV(); iv = aesAlg.IV; ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); using (MemoryStream msEncrypt = new MemoryStream()) { using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) { swEncrypt.Write(plainText); } } byte[] encryptedContent = msEncrypt.ToArray(); byte[] result = new byte[iv.Length + encryptedContent.Length]; Buffer.BlockCopy(iv, 0, result, 0, iv.Length); Buffer.BlockCopy(encryptedContent, 0, result, iv.Length, encryptedContent.Length); return Convert.ToBase64String(result); } } } } public static byte[] StringToByteArray(string hex) { int NumberChars = hex.Length; byte[] bytes = new byte[NumberChars / 2]; for (int i = 0; i < NumberChars; i += 2) { bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); } return bytes; } public static string DecryptString(string keyHex, string cipherText) { byte[] key = StringToByteArray(keyHex); byte[] fullCipher = Convert.FromBase64String(cipherText); byte[] iv = new byte[16]; byte[] cipher = new byte[fullCipher.Length - iv.Length]; Buffer.BlockCopy(fullCipher, 0, iv, 0, iv.Length); Buffer.BlockCopy(fullCipher, iv.Length, cipher, 0, cipher.Length); using (Aes aesAlg = Aes.Create()) { aesAlg.Key = key; aesAlg.IV = iv; ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); using (MemoryStream msDecrypt = new MemoryStream(cipher)) { using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (StreamReader srDecrypt = new StreamReader(csDecrypt)) { return srDecrypt.ReadToEnd(); } } } } } public void Dispose() { StopHeartbeat(); _httpClient.Dispose(); } }