1
0

Initial Release

This commit is contained in:
2026-05-24 19:58:20 -07:00
commit d7b7e01e92
28 changed files with 4273 additions and 0 deletions
+88
View File
@@ -0,0 +1,88 @@
package env
import (
"crypto/tls"
"crypto/x509"
"fmt"
"log"
"os"
"strconv"
)
const (
MAX_FORM_BYTES = 1 << 24
FILE_MODE = os.FileMode(0770)
STICKERBOARD_FILENAME = "stickerboard.webp"
)
var (
HTTP_TLS *tls.Config // http: TLS Configuration
HTTP_PROXY_HEADER = envString("HTTP_PROXY_HEADER", "") // http: Retrieve IP Address from Following HTTP Header
HTTP_ADDRESS = envString("HTTP_ADDRESS", "localhost:8080") // http: Address to Listen for Requests on
TLS_ENABLED = envString("TLS_ENABLED", "false") == "true" // http: Enable TLS?
TLS_CERT = envString("TLS_CERT", "tls_crt.pem") // http: Path to TLS Certificate
TLS_KEY = envString("TLS_KEY", "tls_key.pem") // http: Path to TLS Key
TLS_CA = envString("TLS_CA", "tls_ca.pem") // http: Path to TLS CA Bundle
DATA_DIRECTORY = envString("DATA_DIRECTORY", "data") // env: Data Directory
)
func init() {
// Create Data Directory
if err := os.MkdirAll(DATA_DIRECTORY, FILE_MODE); err != nil {
log.Fatalln("[env/data] Create Directory Error:", err)
}
// Load and Parse TLS Configuration from Disk
if TLS_ENABLED {
cert, err := tls.LoadX509KeyPair(TLS_CERT, TLS_KEY)
if err != nil {
log.Fatalln("[env/tls] Cannot Load Keypair", err)
}
caBytes, err := os.ReadFile(TLS_CA)
if err != nil {
log.Fatalln("[env/tls] Cannot Read CA File", err)
}
caPool := x509.NewCertPool()
if !caPool.AppendCertsFromPEM(caBytes) {
log.Fatalln("[env/tls] Cannot Append Certificates")
}
HTTP_TLS = &tls.Config{
Certificates: []tls.Certificate{cert},
ClientCAs: caPool,
MinVersion: tls.VersionTLS13,
MaxVersion: tls.VersionTLS13,
CipherSuites: []uint16{
tls.TLS_AES_128_GCM_SHA256,
tls.TLS_AES_256_GCM_SHA384,
tls.TLS_CHACHA20_POLY1305_SHA256,
},
}
}
}
// Reads String from Environment
func envString(key, defaultValue string) string {
systemValue := os.Getenv(key)
if systemValue == "" {
if defaultValue == "\x00" {
fmt.Printf("[env] Environment Variable '%s' is undefined\n", key)
os.Exit(2)
}
return defaultValue
}
return systemValue
}
// Read Number from Environment
func envNumber(key string, defaultValue int) int {
systemValue := os.Getenv(key)
if systemValue == "" {
return defaultValue
}
v, err := strconv.Atoi(systemValue)
if err != nil {
fmt.Printf("[env] Environment Variable '%s' is not a integer: %s\n", key, err)
os.Exit(2)
}
return v
}
+75
View File
@@ -0,0 +1,75 @@
package env
import (
"context"
"encoding/json"
"errors"
"log"
"os"
"path"
"sync"
"time"
)
type DatabaseRoot struct {
Stickers []DatabaseSticker `json:"stickers"`
}
type DatabaseSticker struct {
Created time.Time `json:"created"` // Sticker Created
UserAddress string `json:"user_address"` // User IP Address (For Manual Bans)
UserName string `json:"user_name"` // User Name
UserURL string `json:"user_url"` // User URL (Optional)
Message string `json:"message"` // Sticker Message
Visible bool `json:"visible"` // Sticker Visible?
OffsetX int `json:"offset_x"` // Placement X
OffsetY int `json:"offset_y"` // Placement Y
ImageScale float64 `json:"image_scale"` // Image Scale
ImageHeight int `json:"image_height"` // Image Height
ImageWidth int `json:"image_width"` // Image Width
ImageType ImageType `json:"image_type"` // Original Image File Type
ImageHash string `json:"image_hash"` // Original Image File Hash
}
var (
Database DatabaseRoot
DatabaseMtx sync.RWMutex
)
func SetupDatabase(stop context.Context, await *sync.WaitGroup) {
t := time.Now()
p := path.Join(DATA_DIRECTORY, "database.json")
// Decode File
b, err := os.ReadFile(p)
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
log.Fatalln("[db] Read Database Error:", err)
}
Database.Stickers = make([]DatabaseSticker, 0)
}
if err == nil {
if err := json.Unmarshal(b, &Database); err != nil {
log.Fatalln("[db] Parse Database Error:", err)
}
}
// Shutdown Logic
await.Add(1)
go func() {
defer await.Done()
<-stop.Done()
// Write Database To Disk
b, err := json.MarshalIndent(&Database, "", " ")
if err != nil {
log.Fatalln("[db] Cannot Marshal Database:", err)
}
if err := os.WriteFile(p, b, FILE_MODE); err != nil {
log.Fatalln("[db] Cannot Write Database:", err)
}
log.Println("[db] Database Saved")
}()
log.Println("[db] Ready in", time.Since(t))
}
+101
View File
@@ -0,0 +1,101 @@
package env
import (
"context"
"image"
"log"
"sync"
"time"
tf "github.com/galeone/tensorflow/tensorflow/go"
"golang.org/x/image/draw"
)
const (
MODEL_TRESHOLD = 0.7 // Threshold before an image is considered inappropriate
MODEL_SIZE = 224 // Model Size
)
var nsfwModel *tf.SavedModel
func SetupModel(stop context.Context, await *sync.WaitGroup) {
t := time.Now()
// Read Model from Disk
model, err := tf.LoadSavedModel("resources/model", []string{"serve"}, nil)
if err != nil {
log.Fatalf("[model] Unable to Load Model (%s)\n", err)
}
nsfwModel = model
// Test Model using Dummy Tensor
dummy, _ := tf.NewTensor([1][MODEL_SIZE][MODEL_SIZE][3]float32{})
if _, err := ModelClassifyTensor(dummy); err != nil {
log.Fatalf("[model] Failed to Initialize Model (%s)\n", err)
}
// Shutdown Logic
await.Add(1)
go func() {
defer await.Done()
<-stop.Done()
nsfwModel.Session.Close()
log.Println("[model] Model Closed")
}()
log.Printf("[model] Model Ready (%s)\n", time.Since(t))
}
// Cast Predictions on a Tensor using the NSFW Model
func ModelClassifyTensor(tensor *tf.Tensor) ([]float32, error) {
results, err := nsfwModel.Session.Run(
map[tf.Output]*tf.Tensor{
nsfwModel.Graph.Operation("serving_default_input").Output(0): tensor,
},
[]tf.Output{
nsfwModel.Graph.Operation("StatefulPartitionedCall").Output(0),
},
[]*tf.Operation{},
)
if err != nil {
return []float32{}, err
}
// cursed...
return results[0].Value().([][]float32)[0], err
}
// Classify an Image returning true if it's considered safe
func ModelClassifyImage(someImage image.Image) (bool, error) {
// Resize Image to Usable Size
resized := image.NewRGBA(image.Rect(0, 0, MODEL_SIZE, MODEL_SIZE))
draw.NearestNeighbor.Scale(resized, resized.Rect, someImage, someImage.Bounds(), draw.Over, nil)
// Convert Pixel Data into Normalized Floats
var tensorCap = MODEL_SIZE * MODEL_SIZE * 3
var tensorData = make([]float32, 0, tensorCap)
var tensorShape = []int64{1, MODEL_SIZE, MODEL_SIZE, 3}
for x := 0; x < MODEL_SIZE; x++ {
for y := 0; y < MODEL_SIZE; y++ {
r, g, b, _ := resized.At(x, y).RGBA()
tensorData = append(tensorData, float32(r)/65535, float32(g)/65535, float32(b)/65535)
}
}
// Create Tensor, reshape it, then classify
tensor, err := tf.NewTensor(tensorData)
if err != nil {
return false, err
}
if err := tensor.Reshape(tensorShape); err != nil {
return false, err
}
results, err := ModelClassifyTensor(tensor)
if err != nil {
return false, err
}
// Calculate How Inappropriate this Image is
// Drawing[0], Hentai[1], Neutral[2], Porn[3], Sexy[4]
return (results[1] + results[3] + (results[4] * 0.9)) < MODEL_TRESHOLD, nil
}
+264
View File
@@ -0,0 +1,264 @@
package env
import (
"bytes"
"fmt"
"image"
"image/color"
"image/gif"
"image/jpeg"
"image/png"
"log"
"os"
"os/exec"
"path"
"runtime"
"sync"
"sync/atomic"
"time"
"golang.org/x/image/draw"
"golang.org/x/image/webp"
)
const (
CANVAS_WIDTH = 854 // Canvas Width
CANVAS_HEIGHT = 480 // Canvas Height
CANVAS_STICKER_MAX_HEIGHT = 240 // Canvas Max Sticker Height in Pixels
CANVAS_FRAMES = 100
CANVAS_FPS = 20
CANVAS_DELAY = 100 / CANVAS_FPS
)
var (
StickerboardReady atomic.Bool
StickerboardPath = path.Join(DATA_DIRECTORY, STICKERBOARD_FILENAME)
StickerboardBack *image.RGBA
StickerboardMtx sync.RWMutex
Stickerboard []byte
)
func init() {
// Initialize Background to Black to Prevent Coalescing
base := image.NewRGBA(image.Rect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT))
for x := 0; x < CANVAS_WIDTH; x++ {
for y := 0; y < CANVAS_HEIGHT; y++ {
base.Set(x, y, color.Black)
}
}
StickerboardBack = base
// Load Custom Background (if any)
p := path.Join(DATA_DIRECTORY, "background.png")
if f, err := os.Open(p); err == nil {
if o, err := png.Decode(f); err == nil {
b := base.Bounds()
draw.CatmullRom.Scale(base, b.Bounds(), o, o.Bounds(), draw.Over, nil)
}
f.Close()
}
}
func stickerboardCopy() {
b, err := os.ReadFile(StickerboardPath)
if err != nil {
log.Println("[stickerboard] Read Image Error:", err)
return
}
StickerboardMtx.Lock()
Stickerboard = b
StickerboardReady.Store(true)
StickerboardMtx.Unlock()
}
func StickerboardRender() (int, error) {
t := time.Now()
// Mass Decode and Resizing of all Stickers
type DecodedSticker struct {
Position image.Rectangle
Frames []*image.RGBA
Delays []int
}
stickers := make([]DecodedSticker, len(Database.Stickers))
DatabaseMtx.RLock()
if err := Multithread(len(stickers), func(i int) error {
// Read Sticker from Disk
info := &Database.Stickers[i]
path := path.Join(DATA_DIRECTORY, info.ImageHash)
reader, err := os.Open(path)
if err != nil {
return err
}
defer reader.Close()
var images = make([]image.Image, 1)
var delays = make([]int, 1)
// Decode Sticker Frames
var decodeGIF *gif.GIF
var decodeImage image.Image
var decodeError error
switch info.ImageType {
case IMAGE_GIF:
decodeGIF, decodeError = gif.DecodeAll(reader)
case IMAGE_WEBP:
decodeImage, decodeError = webp.Decode(reader)
case IMAGE_JPEG:
decodeImage, decodeError = jpeg.Decode(reader)
case IMAGE_PNG:
decodeImage, decodeError = png.Decode(reader)
default:
return fmt.Errorf("decoder available")
}
if decodeError != nil {
return err
}
if info.ImageType == IMAGE_GIF {
// This section here properly layers GIF frames
delays = decodeGIF.Delay
images = make([]image.Image, len(decodeGIF.Image))
var imageBase = image.NewRGBA(image.Rect(0, 0, decodeGIF.Config.Width, decodeGIF.Config.Height))
var imagePrev *image.RGBA
var disposal = byte(gif.DisposalNone)
for i, frame := range decodeGIF.Image {
if disposal == gif.DisposalPrevious {
imagePrev = image.NewRGBA(imageBase.Bounds())
copy(imageBase.Pix, imagePrev.Pix)
}
if i > 0 {
switch disposal {
case gif.DisposalBackground:
draw.Draw(imageBase, decodeGIF.Image[i-1].Bounds(), image.Transparent, image.Point{}, draw.Src)
case gif.DisposalPrevious:
if imagePrev != nil {
draw.Draw(imageBase, imageBase.Bounds(), imagePrev, image.Point{}, draw.Src)
}
}
}
// Save Composited Frame
draw.Draw(imageBase, frame.Bounds(), frame, frame.Bounds().Min, draw.Over)
imageCopy := image.NewRGBA(imageBase.Bounds())
copy(imageCopy.Pix, imageBase.Pix)
images[i] = imageCopy
disposal = decodeGIF.Disposal[i]
}
} else {
// Copy Static Frame
images[0] = decodeImage
}
// Resize Decoded Frames
var (
stickerFrames = make([]*image.RGBA, len(images))
stickerPosition image.Rectangle
stickerBounds = images[0].Bounds()
stickerWidth = int(float64(stickerBounds.Dx()) * info.ImageScale)
stickerHeight = int(float64(stickerBounds.Dy()) * info.ImageScale)
)
for j := range images {
// Nice and Smooth Scaling
source := images[j]
scaled := image.NewRGBA(image.Rect(0, 0, stickerWidth, stickerHeight))
draw.CatmullRom.Scale(scaled, scaled.Bounds(), source, source.Bounds(), draw.Over, nil)
// Invert Y position because browsers placment origin is bottom-left but server is top-left
y := CANVAS_HEIGHT - info.OffsetY - stickerHeight
stickerPosition = image.Rect(info.OffsetX, y, info.OffsetX+stickerWidth, y+stickerHeight)
stickerFrames[j] = scaled
}
// Store Resized Frame
stickers[i] = DecodedSticker{
Frames: stickerFrames,
Delays: delays,
Position: stickerPosition,
}
return nil
}); err != nil {
DatabaseMtx.RUnlock()
return 0, err
}
DatabaseMtx.RUnlock()
// Startup Encoder
var outputLogs bytes.Buffer
cmd := exec.Command(
"ffmpeg", "-y",
"-threads", fmt.Sprint(runtime.NumCPU()),
"-f", "rawvideo",
"-pix_fmt", "rgba",
"-s", fmt.Sprintf("%dx%d", CANVAS_WIDTH, CANVAS_HEIGHT),
"-framerate", fmt.Sprint(CANVAS_FPS),
"-i", "pipe:0",
"-vcodec", "libwebp",
"-compression_level", "4",
"-q:v", "75",
"-loop", "0",
StickerboardPath,
)
cmdStdin, err := cmd.StdinPipe()
if err != nil {
return 0, err
}
cmd.Stdout = &outputLogs
cmd.Stderr = &outputLogs
if err := cmd.Start(); err != nil {
return 0, err
}
// Generate Frames
for i := 0; i < CANVAS_FRAMES; i++ {
// Generate Frame
canvas := image.NewRGBA(StickerboardBack.Rect)
copy(canvas.Pix, StickerboardBack.Pix)
for j := range stickers {
decode := &stickers[j]
index := 0
if len(decode.Frames) > 1 {
offset := 0
for {
idx := index % len(decode.Frames)
offset += decode.Delays[idx]
if offset > (i * CANVAS_DELAY) {
index = idx
break
}
index++
}
}
draw.Draw(canvas, decode.Position, decode.Frames[index], image.Point{}, draw.Over)
}
// Submit Encoder
for y := 0; y < canvas.Rect.Dy(); y++ {
start := y * canvas.Stride
end := start + canvas.Rect.Dx()*4
cmdStdin.Write(canvas.Pix[start:end])
}
}
// Await Encoding
cmdStdin.Close()
if err := cmd.Wait(); err != nil {
exitCode := -1
if cmd.ProcessState != nil {
exitCode = cmd.ProcessState.ExitCode()
}
log.Println("[sticker] FFMPEG Exited With Code %d\n%s\n", exitCode, outputLogs.String())
return 0, err
}
log.Printf("[sticker] Rendered %d Images in %s", len(stickers), time.Since(t))
stickerboardCopy()
return len(stickers), nil
}
+84
View File
@@ -0,0 +1,84 @@
package env
import (
"runtime"
"sync"
"sync/atomic"
)
type ImageType string
const (
IMAGE_OTHER ImageType = "UNKNOWN"
IMAGE_WEBP ImageType = "WEBP"
IMAGE_JPEG ImageType = "JPG"
IMAGE_PNG ImageType = "PNG"
IMAGE_GIF ImageType = "GIF"
)
// Classify the contents of a file based on it's starting bytes
// https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files)
func ImageSniffType(d []byte) ImageType {
switch {
case len(d) > 3 && // JPEG
d[0] == 0xFF && d[1] == 0xD8 && d[2] == 0xFF:
return IMAGE_JPEG
case len(d) > 8 && // PNG
d[0] == 0x89 && d[1] == 0x50 && d[2] == 0x4E && d[3] == 0x47 &&
d[4] == 0x0D && d[5] == 0x0A && d[6] == 0x1A && d[7] == 0x0A:
return IMAGE_PNG
case len(d) > 4 && // GIF
d[0] == 0x47 && d[1] == 0x49 && d[2] == 0x46 && d[3] == 0x38:
return IMAGE_GIF
case len(d) > 12 && // WEBP
d[0] == 0x52 && d[1] == 0x49 && d[2] == 0x46 && d[3] == 0x46 &&
d[8] == 0x57 && d[9] == 0x45 && d[10] == 0x42 && d[11] == 0x50:
return IMAGE_WEBP
default:
return IMAGE_OTHER
}
}
// Easily spread a workload across all available threads, returning the error if any
func Multithread(jobCount int, handler func(i int) error) error {
threads := runtime.NumCPU()
channel := make(chan int, jobCount)
var wait sync.WaitGroup
var fail atomic.Value
// Startup Goroutines
for workerId := 0; workerId < threads; workerId++ {
wait.Add(1)
go func() {
defer wait.Done()
for i := range channel {
// Exit early if an error has ocurred
if fail.Load() != nil {
return
}
// Run Handler and store it's error (if any)
if err := handler(i); err != nil {
fail.Store(err)
return
}
}
}()
}
// Queue and Complete Work Across all Threads
for i := 0; i < jobCount; i++ {
channel <- i
}
close(channel) // close or wait forever
wait.Wait()
// Return Error (if any)
if v := fail.Load(); v != nil {
return v.(error)
}
return nil
}