buch of stuff; simple-captcha; mdtable; some more stuff
This commit is contained in:
111
bots/captcha.php
Normal file
111
bots/captcha.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/* simple-captcha, copyright rattatwinko 2026, license MIT
|
||||
* captcha.php, captcha generator
|
||||
* LICENSE AT END!
|
||||
*/
|
||||
session_start();
|
||||
|
||||
$chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
||||
$code = substr(str_shuffle($chars), 0, 6);
|
||||
$_SESSION['simple-captcha'] = $code;
|
||||
|
||||
$width = 220;
|
||||
$height = 80;
|
||||
|
||||
$image = imagecreatetruecolor($width, $height);
|
||||
|
||||
$bg = imagecolorallocate($image, rand(220,255), rand(220,255), rand(220,255));
|
||||
imagefilledrectangle($image, 0, 0, $width, $height, $bg);
|
||||
|
||||
// random text color
|
||||
$textColor = imagecolorallocate($image, rand(0,100), rand(0,100), rand(0,100));
|
||||
|
||||
// noise lines
|
||||
for ($i = 0; $i < 8; $i++) {
|
||||
$noiseColor = imagecolorallocate($image, rand(100,180), rand(100,180), rand(100,180));
|
||||
imageline(
|
||||
$image,
|
||||
rand(0,$width), rand(0,$height),
|
||||
rand(0,$width), rand(0,$height),
|
||||
$noiseColor
|
||||
);
|
||||
}
|
||||
|
||||
// noise dots
|
||||
for ($i = 0; $i < 800; $i++) {
|
||||
$dotColor = imagecolorallocate($image, rand(150,200), rand(150,200), rand(150,200));
|
||||
imagesetpixel($image, rand(0,$width), rand(0,$height), $dotColor);
|
||||
}
|
||||
|
||||
$font = __DIR__ . '/fonts/ComicRelief-Bold.ttf';
|
||||
$x = 20;
|
||||
|
||||
for ($i = 0; $i < strlen($code); $i++) {
|
||||
|
||||
$angle = rand(-25, 25);
|
||||
$y = rand(50, 65);
|
||||
|
||||
imagettftext(
|
||||
$image,
|
||||
rand(26, 32),
|
||||
$angle,
|
||||
$x,
|
||||
$y,
|
||||
$textColor,
|
||||
$font,
|
||||
$code[$i]
|
||||
);
|
||||
|
||||
$x += 30;
|
||||
}
|
||||
|
||||
imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR);
|
||||
|
||||
$distorted = imagecreatetruecolor($width, $height);
|
||||
imagefill($distorted, 0, 0, $bg);
|
||||
|
||||
for ($x = 0; $x < $width; $x++) {
|
||||
for ($y = 0; $y < $height; $y++) {
|
||||
|
||||
$newX = $x + (sin($y / 10) * 5);
|
||||
$newY = $y + (sin($x / 15) * 5);
|
||||
|
||||
if ($newX >= 0 && $newX < $width && $newY >= 0 && $newY < $height) {
|
||||
$color = imagecolorat($image, $newX, $newY);
|
||||
imagesetpixel($distorted, $x, $y, $color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header("Content-Type: image/png");
|
||||
imagepng($distorted);
|
||||
imagedestroy($image); // deprectated but who cares
|
||||
imagedestroy($distorted); // also deprecated
|
||||
|
||||
|
||||
/*
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) [2026] [rattatwinko]
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
?>
|
||||
BIN
bots/fonts/ComicRelief-Bold.ttf
Normal file
BIN
bots/fonts/ComicRelief-Bold.ttf
Normal file
Binary file not shown.
1
bots/fonts/readme.txt
Normal file
1
bots/fonts/readme.txt
Normal file
@@ -0,0 +1 @@
|
||||
fonts for scaptcha.php
|
||||
29
bots/index.html
Normal file
29
bots/index.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Captcha</title>
|
||||
<script type="module" src="simple-captcha.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<form id="myForm">
|
||||
<!-- Call the custom element, it will handle all the graphics stuff -->
|
||||
<simple-captcha id="captcha"></simple-captcha>
|
||||
</form>
|
||||
|
||||
<script type="module">
|
||||
// handle stuff here
|
||||
// something like a blog submit thing, that would be cool imo!
|
||||
const captcha = document.getElementById("captcha");
|
||||
|
||||
captcha.addEventListener("valid", () => {
|
||||
alert("correct!");
|
||||
});
|
||||
|
||||
captcha.addEventListener("invalid", () => {
|
||||
alert("wrong!");
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
107
bots/simple-captcha.js
Normal file
107
bots/simple-captcha.js
Normal file
@@ -0,0 +1,107 @@
|
||||
class SimpleCaptcha extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: "open" });
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.render();
|
||||
}
|
||||
|
||||
render() {
|
||||
this.shadowRoot.innerHTML = `
|
||||
<style>
|
||||
:host {
|
||||
display: inline-block;
|
||||
font-family: sans-serif;
|
||||
--captcha-border: #ccc;
|
||||
--captcha-bg: #f9f9f9;
|
||||
--captcha-gap: 6px;
|
||||
}
|
||||
.captcha-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--captcha-gap);
|
||||
}
|
||||
img {
|
||||
border: 1px solid var(--captcha-border);
|
||||
border-radius: 4px;
|
||||
height: 40px;
|
||||
object-fit: cover;
|
||||
}
|
||||
input {
|
||||
flex: 1;
|
||||
padding: 6px 8px;
|
||||
border: 1px solid var(--captcha-border);
|
||||
border-radius: 4px;
|
||||
}
|
||||
button {
|
||||
padding: 6px 10px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--captcha-border);
|
||||
background: var(--captcha-bg);
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
<div class="captcha-wrapper">
|
||||
<img id="img" src="captcha.php?${Date.now()}" alt="Captcha">
|
||||
<input id="input" placeholder="Enter code" autocomplete="off">
|
||||
<button id="refresh" title="Refresh Captcha">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="8" height="8" viewBox="0 0 256 256" xml:space="preserve">
|
||||
<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1; " transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)">
|
||||
<path d="M 81.521 31.109 c -0.86 -1.73 -2.959 -2.438 -4.692 -1.575 c -1.73 0.86 -2.436 2.961 -1.575 4.692 c 2.329 4.685 3.51 9.734 3.51 15.01 C 78.764 67.854 63.617 83 45 83 S 11.236 67.854 11.236 49.236 c 0 -16.222 11.501 -29.805 26.776 -33.033 l -3.129 4.739 c -1.065 1.613 -0.62 3.784 0.992 4.85 c 0.594 0.392 1.264 0.579 1.926 0.579 c 1.136 0 2.251 -0.553 2.924 -1.571 l 7.176 -10.87 c 0.001 -0.001 0.001 -0.002 0.002 -0.003 l 0.018 -0.027 c 0.063 -0.096 0.106 -0.199 0.159 -0.299 c 0.049 -0.093 0.108 -0.181 0.149 -0.279 c 0.087 -0.207 0.152 -0.419 0.197 -0.634 c 0.009 -0.041 0.008 -0.085 0.015 -0.126 c 0.031 -0.182 0.053 -0.364 0.055 -0.547 c 0 -0.014 0.004 -0.028 0.004 -0.042 c 0 -0.066 -0.016 -0.128 -0.019 -0.193 c -0.008 -0.145 -0.018 -0.288 -0.043 -0.431 c -0.018 -0.097 -0.045 -0.189 -0.071 -0.283 c -0.032 -0.118 -0.065 -0.236 -0.109 -0.35 c -0.037 -0.095 -0.081 -0.185 -0.125 -0.276 c -0.052 -0.107 -0.107 -0.211 -0.17 -0.313 c -0.054 -0.087 -0.114 -0.168 -0.175 -0.25 c -0.07 -0.093 -0.143 -0.183 -0.223 -0.27 c -0.074 -0.08 -0.153 -0.155 -0.234 -0.228 c -0.047 -0.042 -0.085 -0.092 -0.135 -0.132 L 36.679 0.775 c -1.503 -1.213 -3.708 -0.977 -4.921 0.53 c -1.213 1.505 -0.976 3.709 0.53 4.921 l 3.972 3.2 C 17.97 13.438 4.236 29.759 4.236 49.236 C 4.236 71.714 22.522 90 45 90 s 40.764 -18.286 40.764 -40.764 C 85.764 42.87 84.337 36.772 81.521 31.109 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round"/>
|
||||
</g>
|
||||
</svg>
|
||||
</button>
|
||||
<button id="submit" title="Submit Captcha">Submit</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const img = this.shadowRoot.getElementById("img");
|
||||
img.addEventListener("click", () => this.refresh());
|
||||
|
||||
this.shadowRoot.getElementById("refresh")
|
||||
.addEventListener("click", () => this.refresh());
|
||||
|
||||
this.shadowRoot.getElementById("submit")
|
||||
.addEventListener("click", () => this.handleSubmit());
|
||||
}
|
||||
|
||||
refresh() {
|
||||
const img = this.shadowRoot.getElementById("img");
|
||||
img.src = "captcha.php?" + Date.now();
|
||||
this.shadowRoot.getElementById("input").value = "";
|
||||
}
|
||||
|
||||
async validate() {
|
||||
const input = this.shadowRoot.getElementById("input").value.trim();
|
||||
if (!input) return false;
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("captcha", input);
|
||||
|
||||
try {
|
||||
const res = await fetch("validate.php", { method: "POST", body: formData });
|
||||
const data = await res.json();
|
||||
|
||||
return data.status === "valid";
|
||||
} catch (err) {
|
||||
console.error("Captcha validation failed:", err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async handleSubmit() {
|
||||
const isValid = await this.validate();
|
||||
|
||||
if (isValid) {
|
||||
this.dispatchEvent(new CustomEvent("valid"));
|
||||
this.refresh();
|
||||
} else {
|
||||
this.dispatchEvent(new CustomEvent("invalid"));
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("simple-captcha", SimpleCaptcha);
|
||||
22
bots/validate.php
Normal file
22
bots/validate.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/* server validation scaptcha */
|
||||
|
||||
session_start();
|
||||
|
||||
header("Content-Type: application/json");
|
||||
$input = $_POST['captcha'] ?? "";
|
||||
|
||||
if (!isset($_SESSION["simple-captcha"])) {
|
||||
echo json_encode(["status" => "error"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (strcasecmp($input, $_SESSION["simple-captcha"]) === 0) {
|
||||
unset($_SESSION["simple-captcha"]);
|
||||
echo json_encode(["status" => "valid"]);
|
||||
} else {
|
||||
echo json_encode(["status" => "invalid"]);
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user