diff --git a/static/filterWeapons.js b/static/filterWeapons.js index 7cced4a..986f06c 100644 --- a/static/filterWeapons.js +++ b/static/filterWeapons.js @@ -1,58 +1,53 @@ -let selectedWeapon = null; // Store the selected weapon's data -let selectedOperative = null; // Store the selected operative's data -let weapons = []; // This will be populated by the weapons -let globalModifiers = []; // This will be populated by the modifiers -let selectedGunTypes = []; // Track selected gun types for filtering -let headshotMultiplier = 0; // Initialize Headshots as 0 -let headshotBaseApplied = false; //Initialize Headshots Applied as false +let selectedWeapon = null; +let selectedOperative = null; +let weapons = []; +let globalModifiers = []; +let selectedGunTypes = []; +let headshotMultiplier = 0; +let headshotBaseApplied = false; let ignoreHeadshots = false; -// Function to fetch operatives data from JSON +//fetch operatives data from JSON function fetchOperativesData() { fetch('/trlstats/static/json/operative.json') .then(response => response.json()) .then(data => { - populateOperatives(data.operatives); // Populate the operative dropdown once data is loaded + populateOperatives(data.operatives); }) .catch(error => console.error('Error fetching operatives data:', error)); } -// Function to populate the select element with operatives +//populate the select element with operatives function populateOperatives(operatives) { const select = document.getElementById('operative-select'); - select.innerHTML = ""; // Clear any existing options - // Add the placeholder option + select.innerHTML = ""; const placeholderOption = document.createElement('option'); placeholderOption.value = ""; // Empty value for the placeholder placeholderOption.text = "Select an operative"; - select.appendChild(placeholderOption); // Add the placeholder option + select.appendChild(placeholderOption); operatives.forEach(operative => { const option = document.createElement('option'); option.value = operative.id; option.text = operative.name; select.appendChild(option); }); - // Attach event listener to detect when an operative is selected select.addEventListener('change', (event) => { const selectedOperativeId = event.target.value; - // If placeholder is selected, don't proceed if (!selectedOperativeId) { document.getElementById('operative-modifiers').innerHTML = ''; - return; // Do nothing when the placeholder is selected + return; } selectedOperative = operatives.find(op => op.id === selectedOperativeId); if (selectedOperative) { - updateOperativeBuffs(selectedOperative); // Update operative modifiers on valid selection + updateOperativeBuffs(selectedOperative); } }); } function updateOperativeBuffs(operative) { const operativeModifiers = operative.modifiers || []; - // Remove previously added operative-specific modifiers const operativeSection = document.getElementById('operative-modifiers'); - operativeSection.innerHTML = ''; // Clear existing operative modifiers - // If the operative has specific modifiers, show them + operativeSection.innerHTML = ''; if (operativeModifiers.length > 0) { operativeModifiers.forEach(mod => { const label = document.createElement('label'); @@ -61,8 +56,7 @@ function updateOperativeBuffs(operative) { input.id = mod.id; input.value = mod.value; input.dataset.type = mod.type; - input.dataset.buffs = mod.buffs ? JSON.stringify(mod.buffs) : ''; // Store buffs if available - // Set checkbox to be unchecked by default + input.dataset.buffs = mod.buffs ? JSON.stringify(mod.buffs) : ''; input.checked = false; label.appendChild(input); label.appendChild(document.createTextNode(mod.label)); @@ -70,58 +64,52 @@ function updateOperativeBuffs(operative) { operativeSection.appendChild(document.createElement('br')); }); } - // Make sure that each operative-specific modifier checkbox triggers recalculation when changed operativeSection.addEventListener('change', applyModifiers); - // Trigger recalculation once the operative buffs are displayed applyModifiers(); } -// Function to fetch weapons data from JSON +//fetch weapons data from JSON function fetchWeaponsData() { fetch('static/json/data.json') .then(response => response.json()) .then(data => { - weapons = data; // Store the fetched data in the global 'weapons' variable - populateWeapons(); // Populate the weapon dropdown once data is loaded - createGunTypeCheckboxes(); // Create the gun type checkboxes after loading the weapons + weapons = data; + populateWeapons(); + createGunTypeCheckboxes(); }) .catch(error => console.error('Error fetching weapons data:', error)); } -// Function to populate the weapon dropdown +//populate the weapon dropdown function populateWeapons() { const select = document.getElementById('weapon-select'); - select.innerHTML = ""; // Clear any existing options - // Add the placeholder option + select.innerHTML = ""; const placeholderOption = document.createElement('option'); - placeholderOption.value = ""; // Empty value for the placeholder + placeholderOption.value = ""; placeholderOption.text = "Select a Weapon"; - select.appendChild(placeholderOption); // Add the placeholder option - // Populate with actual weapons + select.appendChild(placeholderOption); weapons.forEach(weapon => { const option = document.createElement('option'); option.value = weapon.id; option.text = weapon.name; select.appendChild(option); }); - // Attach event listener to detect when a weapon is selected select.addEventListener('change', (event) => { const selectedWeaponId = parseInt(event.target.value); - // If placeholder is selected, don't proceed if (!selectedWeaponId) { document.getElementById('weapon-stats').innerHTML = ''; - return; // Do nothing when the placeholder is selected + return; } selectedWeapon = weapons.find(weapon => weapon.id === selectedWeaponId); if (selectedWeapon) { - updateWeaponStats(selectedWeapon); // Update stats on valid selection + updateWeaponStats(selectedWeapon); applyModifiers(); } }); } -// Function to display the selected weapon's stats in a table-like format +//display the selected weapon's stats in table function updateWeaponStats(weapon) { const statsElement = document.getElementById('weapon-stats'); statsElement.innerHTML = ` @@ -148,16 +136,14 @@ function updateWeaponStats(weapon) { `; - // Store values for further calculations const damage = weapon.damage * weapon.damage_multiplier; const rpm = weapon.rpm; const magSize = weapon.mag_size; const reloadTime = weapon.reload_time; - // Calculate DPS, DPM, and Average DPS calculateDPSAndDPM(damage, rpm, magSize, reloadTime); } -// Function to display the modified weapon's stats in the table format +//display the modified weapon's stats in the table function updateModifiedWeaponStats(damage, rpm, reloadTime) { const statsElement = document.getElementById('weapon-stats'); statsElement.innerHTML = ` @@ -184,38 +170,36 @@ function updateModifiedWeaponStats(damage, rpm, reloadTime) { `; - // Recalculate and update DPS, DPM, and Average DPS calculateDPSAndDPM(damage, rpm, selectedWeapon.mag_size, reloadTime); } -// Function to calculate DPS, DPM, and Average DPS, and update the values in the table +//calculate DPS, DPM, and Average DPS, and update the values in the table function calculateDPSAndDPM(damage, rpm, magSize, reloadTime) { const rps = rpm / 60; // Rounds per second - let dps = damage * rps; - const reloadTimeMin = reloadTime / 60; - let dpm = (magSize * damage) / (reloadTimeMin + (magSize / rpm)); - let averageDPS = dpm / 60; - // Update DPS, DPM, and Average DPS values in the table + let dps = damage * rps; //damage per second + const reloadTimeMin = reloadTime / 60; //variable used for dpm calculation + let dpm = (magSize * damage) / (reloadTimeMin + (magSize / rpm)); //damage per minute (including reload time) + let averageDPS = dpm / 60; //average damage per second considering reload time and mag size document.getElementById('dps-value').innerText = dps.toFixed(2); document.getElementById('dpm-value').innerText = dpm.toFixed(2); - document.getElementById('average-dps-value').innerText = averageDPS.toFixed(2); // Update the Average DPS in the table + document.getElementById('average-dps-value').innerText = averageDPS.toFixed(2); } -// Function to fetch and populate modifiers from the JSON file +//fetch and populate modifiers from the JSON file function fetchModifiers() { fetch('static/json/modifiers.json') .then(response => response.json()) .then(data => { - globalModifiers = data; // Save global modifiers for future use - populateModifiers(data); // Populate the modifiers in the UI + globalModifiers = data; + populateModifiers(data); }) .catch(error => console.error('Error fetching modifiers:', error)); } -// Function to dynamically populate modifiers into the HTML +//populate modifiers into the HTML function populateModifiers(modifiers) { const modifiersContainer = document.getElementById('modifiers-container'); - modifiersContainer.innerHTML = ''; // Clear existing modifiers + modifiersContainer.innerHTML = ''; const createModifierSection = (title, modifierList, sectionId) => { const section = document.createElement('div'); section.id = sectionId; @@ -233,7 +217,6 @@ function populateModifiers(modifiers) { input.value = mod.value; input.dataset.type = mod.type; } - // Add operative filtering if available if (mod.operatives) { input.dataset.operatives = mod.operatives; } @@ -252,17 +235,13 @@ function populateModifiers(modifiers) { }); return section; }; - // Create a container for all modifiers const container = document.createElement('div'); container.id = 'modifiers'; - // Populate sections container.appendChild(createModifierSection('Item Buffs', modifiers.itemBuffs, 'items')); container.appendChild(createModifierSection('Perks', modifiers.operativePerks, 'perks')); - modifiersContainer.appendChild(container); // Append item and perks container - // Create and append abilities section + modifiersContainer.appendChild(container); const abilitiesSection = createModifierSection('Abilities', modifiers.abilityPerks, 'abilities'); - modifiersContainer.appendChild(abilitiesSection); // Append abilities section - // Add event listener to recalculate DPS/DPM when modifiers are toggled + modifiersContainer.appendChild(abilitiesSection); modifiersContainer.addEventListener('change', applyModifiers); } @@ -281,30 +260,27 @@ function applyModifiers() { headshotBaseApplied = false; ignoreHeadshots = hasNVG; - // Function to process global modifiers function processModifier(mod) { if (mod.dataset.operatives && mod.dataset.operatives.trim() !== "" && (!selectedOperative || selectedOperative.category !== mod.dataset.operatives)) { - return; // Skip if operative category doesn't match. + return; } const weaponTags = selectedWeapon.guntype; const appliesNotTo = mod.dataset.appliesNotTo; const appliesTo = mod.dataset.appliesTo; if (appliesNotTo && weaponTags.includes(appliesNotTo)) { - return; // Skip this modifier if weapon type should be excluded + return; } if (appliesTo && !weaponTags.includes(appliesTo)) { - return; // Skip if the weapon type doesn't match + return; } if (mod.appliesNotTo && weaponTags.includes(mod.appliesNotTo)) { - return; // Skip this modifier + return; } - // Check if the modifier applies to any of the current weapon's tags if (mod.appliesTo && !weaponTags.includes(mod.appliesTo)) { - return; // Skip this modifier if it does not apply to the selected weapon type + return; } if (mod.dataset.type === 'multiplicative-headshot') { if (!headshotBaseApplied) { - // Automatically check and apply headshot base const baseHeadshotModifier = document.querySelector("#modifiers input[data-type='multiplicative-headshot-base']"); if (baseHeadshotModifier && !baseHeadshotModifier.checked) { baseHeadshotModifier.checked = true; @@ -319,10 +295,8 @@ function applyModifiers() { headshotBaseApplied = true; } } else { - // Process other modifiers applyBuff(mod, rpmModifier, reloadTimeModifier, damageModifier); } - // Handle modifiers with multiple buffs if (mod.dataset.buffs) { const buffs = JSON.parse(mod.dataset.buffs); buffs.forEach(buff => { @@ -345,20 +319,17 @@ function applyModifiers() { } applyBuff(singleBuff, rpmModifier, reloadTimeModifier, damageModifier); } - }; - // Function to process operative-specific modifiers + } + + //process operative-specific modifiers const processOperativeModifier = (mod) => { - // Ensure guntype is now an array of tags - const weaponTags = selectedWeapon.guntype; - // Skip the modifier if it should not apply to any of the current weapon's tags + const weaponTags = selectedWeapon.guntype; //this is now an array if (mod.appliesNotTo && weaponTags.includes(mod.appliesNotTo)) { - return; // Skip this modifier + return; } - // Check if the modifier applies to any of the current weapon's tags if (mod.appliesTo && !weaponTags.includes(mod.appliesTo)) { - return; // Skip this modifier if it does not apply to the selected weapon type + return; } - // Handle operative modifiers with multiple buffs if (mod.buffs) { mod.buffs.forEach(buff => { applyBuff(buff, rpmModifier, reloadTimeModifier, damageModifier); @@ -366,13 +337,11 @@ function applyModifiers() { } else { const modValue = parseFloat(mod.value); const modType = mod.type || 'additive'; - const singleBuff = { type: mod.id.includes('damage') ? 'damage' : mod.id.includes('rpm') ? 'rpm' : 'reloadTime', buffType: modType === 'multiplicative' ? 'multiplicative' : 'additive', value: modValue }; - applyBuff(singleBuff, rpmModifier, reloadTimeModifier, damageModifier); } }; @@ -382,13 +351,10 @@ function applyModifiers() { }); const modifiersContainer = document.getElementById('modifiers'); modifiersContainer.removeEventListener('change', applyModifiers); - // Process global modifiers document.querySelectorAll('#modifiers input:checked').forEach(mod => { processModifier(mod); }); - // Re-apply listener after change modifiersContainer.addEventListener('change', applyModifiers); - // Process operative-specific modifiers that are checked const operativeSection = document.getElementById('operative-modifiers'); operativeSection.querySelectorAll('input:checked').forEach(mod => { if (selectedOperative && selectedOperative.modifiers) { @@ -421,7 +387,6 @@ function applyBuff(buff, rpmModifier, reloadTimeModifier, damageModifier) { return; } const {type, buffType, value} = buff; - // Handle headshot multipliers if (buffType === 'multiplicative-headshot-base' && !headshotBaseApplied) { headshotMultiplier = value - 1; headshotBaseApplied = true; @@ -431,7 +396,6 @@ function applyBuff(buff, rpmModifier, reloadTimeModifier, damageModifier) { headshotMultiplier += value - 1; return; } - // Apply buffs based on the stat being modified if (type === 'rpm') { if (buffType === 'multiplicative') rpmModifier.multiplicative *= value; else if (buffType === 'additive') rpmModifier.additive += value; @@ -444,88 +408,77 @@ function applyBuff(buff, rpmModifier, reloadTimeModifier, damageModifier) { } } -// Modify the existing filterWeapons function to consider gun type checkboxes +//consider gun type checkboxes function filterWeapons() { const input = document.getElementById('weapon-search').value.toLowerCase(); const weaponSelect = document.getElementById('weapon-select'); const options = weaponSelect.getElementsByTagName('option'); - // Get selected guntype filters const selectedGuntypes = Array.from(document.querySelectorAll('#guntype-filters input:checked')) .map(checkbox => checkbox.value); - let firstVisibleOption = null; // Variable to track the first matching option + let firstVisibleOption = null; for (let i = 0; i < options.length; i++) { const optionText = options[i].textContent || options[i].innerText; - const weaponId = parseInt(options[i].value); // Get the weapon ID - const weapon = weapons.find(w => w.id === weaponId); // Find the corresponding weapon - if (!weapon) continue; // Skip if the weapon is not found (for safety) - // Check if the option matches the search query and the selected guntype filters + const weaponId = parseInt(options[i].value); + const weapon = weapons.find(w => w.id === weaponId); + if (!weapon) continue; const matchesSearch = optionText.toLowerCase().indexOf(input) > -1; const matchesGuntypes = selectedGuntypes.length === 0 || selectedGuntypes.every(type => weapon.guntype.includes(type)); - // Show or hide options based on both search and guntype filters if (matchesSearch && matchesGuntypes) { - options[i].style.display = ''; // Show matching option + options[i].style.display = ''; if (!firstVisibleOption) { - firstVisibleOption = options[i]; // Save the first visible option + firstVisibleOption = options[i]; } } else { - options[i].style.display = 'none'; // Hide non-matching option + options[i].style.display = 'none'; } } - // Automatically select the first visible matching option if (firstVisibleOption) { weaponSelect.value = firstVisibleOption.value; - // Manually trigger the 'change' event after auto-selecting the first option weaponSelect.dispatchEvent(new Event('change')); } } -// Function to filter operatives in the dropdown based on search input +//filter operatives in the dropdown based on search input function filterOperatives() { const input = document.getElementById('operative-search').value.toLowerCase(); const operativeSelect = document.getElementById('operative-select'); const options = operativeSelect.getElementsByTagName('option'); - let firstVisibleOption = null; // Track the first matching option + let firstVisibleOption = null; for (let i = 0; i < options.length; i++) { const optionText = options[i].textContent || options[i].innerText; - // Check if the option matches the search query if (optionText.toLowerCase().indexOf(input) > -1) { - options[i].style.display = ''; // Show matching option + options[i].style.display = ''; if (!firstVisibleOption) { - firstVisibleOption = options[i]; // Save the first visible option + firstVisibleOption = options[i]; } } else { - options[i].style.display = 'none'; // Hide non-matching option + options[i].style.display = 'none'; } } - // Automatically select the first visible matching option if (firstVisibleOption) { operativeSelect.value = firstVisibleOption.value; - // Manually trigger the 'change' event after auto-selecting the first option operativeSelect.dispatchEvent(new Event('change')); } } -// Function to dynamically create gun type checkboxes based on available gun types in the weapon data +//create gun type checkboxes based on available gun types in the weapon data function createGunTypeCheckboxes() { const gunTypeFiltersContainer = document.getElementById('gun-type-filters'); - gunTypeFiltersContainer.innerHTML = ''; // Clear existing checkboxes - const gunTypesSet = new Set(); // Use a Set to store unique gun types from the weapon data - // Extract unique gun types from the weapon data + gunTypeFiltersContainer.innerHTML = ''; + const gunTypesSet = new Set(); weapons.forEach(weapon => { - weapon.guntype.forEach(type => gunTypesSet.add(type)); // Add each gun type to the Set + weapon.guntype.forEach(type => gunTypesSet.add(type)); }); - // Create checkboxes for each unique gun type gunTypesSet.forEach(gunType => { const label = document.createElement('label'); const input = document.createElement('input'); input.type = 'checkbox'; input.value = gunType; input.className = 'gun-type-checkbox'; - // Add event listener to filter weapons when checkbox is checked/unchecked input.addEventListener('change', () => { const selectedCheckboxes = Array.from(document.querySelectorAll('.gun-type-checkbox:checked')); selectedGunTypes = selectedCheckboxes.map(checkbox => checkbox.value); - filterWeapons(); // Re-filter weapons based on the selected gun types + filterWeapons(); }); label.appendChild(input); label.appendChild(document.createTextNode(gunType)); @@ -540,24 +493,24 @@ document.querySelectorAll('#guntype-filters input').forEach(checkbox => { checkbox.addEventListener('change', filterWeapons); }); -// function for Creating a Weapon +//Create a Weapon const openBtn = document.getElementById('weapon-create'); const closeBtn = document.getElementById('weapon-cancel'); const modal = document.getElementById('weapon-form'); const form = document.getElementById('weaponForm'); -// Show the modal +//Show the modal openBtn.addEventListener('click', () => { modal.style.display = 'flex'; }); -// Hide the modal +//Hide the modal closeBtn.addEventListener('click', () => { modal.style.display = 'none'; form.reset(); }); -// Handle form submission +//Handle form submission form.addEventListener('submit', e => { e.preventDefault(); const data = new FormData(form); @@ -588,51 +541,51 @@ modal.addEventListener('click', e => { }); document.getElementById('copy-stats').addEventListener('click', async () => { - const statsTable = document.querySelector('#weapon-stats table tr + tr'); - if (!statsTable) { - showCopyMessage('No weapon selected to copy.', 'error'); - return; - } - const cells = Array.from(statsTable.querySelectorAll('td')).map(td => td.innerText.trim()); - const [ name, dmg, rpm, mag, reload, dps, dpm, avgDps ] = cells; - const globalMods = Array.from( - document.querySelectorAll('#modifiers label input:checked') - ).map(cb => cb.parentNode.textContent.trim()); - const opMods = Array.from( - document.querySelectorAll('#operative-modifiers label input:checked') - ).map(cb => cb.parentNode.textContent.trim()); - const allMods = globalMods.concat(opMods); - const modsString = allMods.length - ? allMods.join(', ') - : 'None'; - const payload = [ - `Weapon: ${name}`, - `Damage: ${dmg}`, - `RPM: ${rpm}`, - `Mag Size: ${mag}`, - `Reload Time: ${reload}`, - `DPS: ${dps}`, - `DPM: ${dpm}`, - `Average DPS: ${avgDps}`, - `Modifiers used for this calculation: ${modsString}` - ].join('\n'); - try { - await navigator.clipboard.writeText(payload); - showCopyMessage('✅ Stats copied to clipboard!', 'success'); - } catch (err) { - console.error(err); - showCopyMessage('Failed to copy.', 'error'); - } + const statsTable = document.querySelector('#weapon-stats table tr + tr'); + if (!statsTable) { + showCopyMessage('No weapon selected to copy.', 'error'); + return; + } + const cells = Array.from(statsTable.querySelectorAll('td')).map(td => td.innerText.trim()); + const [name, dmg, rpm, mag, reload, dps, dpm, avgDps] = cells; + const globalMods = Array.from( + document.querySelectorAll('#modifiers label input:checked') + ).map(cb => cb.parentNode.textContent.trim()); + const opMods = Array.from( + document.querySelectorAll('#operative-modifiers label input:checked') + ).map(cb => cb.parentNode.textContent.trim()); + const allMods = globalMods.concat(opMods); + const modsString = allMods.length + ? allMods.join(', ') + : 'None'; + const payload = [ + `Weapon: ${name}`, + `Damage: ${dmg}`, + `RPM: ${rpm}`, + `Mag Size: ${mag}`, + `Reload Time: ${reload}`, + `DPS: ${dps}`, + `DPM: ${dpm}`, + `Average DPS: ${avgDps}`, + `Modifiers used for this calculation: ${modsString}` + ].join('\n'); + try { + await navigator.clipboard.writeText(payload); + showCopyMessage('✅ Stats copied to clipboard!', 'success'); + } catch (err) { + console.error(err); + showCopyMessage('Failed to copy.', 'error'); + } }); function showCopyMessage(text, type) { - const msg = document.getElementById('copy-message'); - msg.textContent = text; - msg.className = type; - setTimeout(() => { - msg.textContent = ''; - msg.className = ''; - }, 3000); + const msg = document.getElementById('copy-message'); + msg.textContent = text; + msg.className = type; + setTimeout(() => { + msg.textContent = ''; + msg.className = ''; + }, 3000); } diff --git a/static/populateTable.js b/static/populateTable.js index 2e4d52c..a7b1227 100644 --- a/static/populateTable.js +++ b/static/populateTable.js @@ -1,5 +1,5 @@ document.addEventListener('DOMContentLoaded', () => { - fetch('/trlstats/static/json/data.json') // Fetch the JSON file directly + fetch('/trlstats/static/json/data.json') .then(response => response.json()) .then(data => { const updatedGuns = data.map(gun => { @@ -10,8 +10,6 @@ document.addEventListener('DOMContentLoaded', () => { const reload_time_min = gun['reload_time'] / 60; const dpm = (gun['mag_size'] * total_damage) / (reload_time_min + (gun['mag_size'] / gun['rpm'])); const avg_dps = dpm / 60; - - // Add the calculated stats to the gun object return { ...gun, total_damage: total_damage, @@ -28,7 +26,7 @@ document.addEventListener('DOMContentLoaded', () => { function populateTable(data) { const table = document.getElementById('gun-stats').getElementsByTagName('tbody')[0]; - table.innerHTML = ''; // Clear existing table data + table.innerHTML = ''; data.forEach(gun => { const row = table.insertRow(); row.insertCell(0).innerText = gun.name; diff --git a/static/suggestion.js b/static/suggestion.js index e527439..cf3eb18 100644 --- a/static/suggestion.js +++ b/static/suggestion.js @@ -6,91 +6,59 @@ const prohibitedWords = ['fuck', 'shit', 'asshole', 'bitch', 'bastard', 'damn', 'fuckface', 'shitfaced', 'asshat', 'bint', 'chink', 'gook', 'jap', 'negro', 'dyke', 'queer', 'tranny', 'tosser', 'spaz', 'mong', 'coon', 'beaner', 'cracker', 'wetback', 'homo', 'fudgepacker', 'tard', 'cocks', 'bollocks', 'numbnuts', 'knob', 'muppet', 'git', 'shag', 'minge', 'git', 'bugger', 'tosser', 'nonce', 'plonker', 'pillock'] -; // Example word filtering +; -// Function to get the last submission time from localStorage function getLastSubmissionTime() { const storedTime = localStorage.getItem('lastSubmissionTime'); return storedTime ? parseInt(storedTime, 10) : 0; } -// Function to save the last submission time to localStorage function setLastSubmissionTime(time) { localStorage.setItem('lastSubmissionTime', time.toString()); } function sendMessage() { - // Get the current time const currentTime = Date.now(); - - // Retrieve the last submission time from localStorage const lastSubmissionTime = getLastSubmissionTime(); - - // Cooldown logic to prevent spamming if (currentTime - lastSubmissionTime < cooldownDuration) { alert(`Please wait for ${cooldownDuration / 1000} seconds between submissions.`); return; } - - // Get the values from the input fields const pseudoname = document.getElementById("name").value || "Anonymous"; const rating = parseInt(document.getElementById("rate").value, 10); const comment = document.getElementById("text").value.trim(); - - // Validation: Rating should be between 1 and 10 if (isNaN(rating) || rating < 1 || rating > 10) { alert("Rating must be a number between 1 and 10."); return; } - - // Validation: Comment length (min 5, max 500) and simple prohibited word check if (comment.length < 5 || comment.length > 500) { alert("Comment must be between 5 and 500 characters."); return; } - - // Check for prohibited words (basic check) for (const word of prohibitedWords) { if (comment.toLowerCase().includes(word)) { alert("Your comment contains inappropriate content."); return; } } - - // If all checks pass, send the message to the Discord webhook const request = new XMLHttpRequest(); request.open("POST", "https://discord.com/api/webhooks/1284936894890901649/Zi-2ZV12L1v1OSBoM-DluE1V1LECXilrNNRZYJcxelnwO7rGgXNH47dxvfFEOK7Fe9_J"); request.setRequestHeader('Content-type', 'application/json'); - - // Create the content to send to the Discord webhook const content = `**Rating:** ${rating}\n**Comment:**\n${comment}`; - - // Debugging information console.log('Sending message with content:', content); - - // Send the message payload to the Discord webhook const params = { - username: pseudoname, // Pseudoname will appear as the username - content: content // The combined content (pseudoname, rating, and comment) + username: pseudoname, + content: content }; - request.send(JSON.stringify(params)); - - // Update the last submission time to the current time setLastSubmissionTime(currentTime); - - // Optionally, you can reset the form after sending document.getElementById("name").value = ""; document.getElementById("rate").value = ""; document.getElementById("text").value = ""; - - // Display the success message const successMessage = document.getElementById("successMessage"); successMessage.textContent = "Successfully sent the message!"; - successMessage.style.display = "block"; // Ensure the message is visible - - // Optionally hide the message after a few seconds + successMessage.style.display = "block"; setTimeout(() => { - successMessage.style.display = "none"; // Hide message after 3 seconds + successMessage.style.display = "none"; }, 3000); }