diff --git a/.idea/.idea.ProjectLighthouse/.idea/git_toolbox_prj.xml b/.idea/.idea.ProjectLighthouse/.idea/git_toolbox_prj.xml
index b3820067..bcb1d9df 100644
--- a/.idea/.idea.ProjectLighthouse/.idea/git_toolbox_prj.xml
+++ b/.idea/.idea.ProjectLighthouse/.idea/git_toolbox_prj.xml
@@ -11,5 +11,10 @@
+
\ No newline at end of file
diff --git a/ProjectLighthouse/Controllers/GameApi/MessageController.cs b/ProjectLighthouse/Controllers/GameApi/MessageController.cs
index 6a5d653b..b378413d 100644
--- a/ProjectLighthouse/Controllers/GameApi/MessageController.cs
+++ b/ProjectLighthouse/Controllers/GameApi/MessageController.cs
@@ -78,11 +78,15 @@ public class MessageController : ControllerBase
public async Task Filter()
{
User? user = await this.database.UserFromGameRequest(this.Request);
+
if (user == null) return this.StatusCode(403, "");
- string loggedText = await new StreamReader(this.Request.Body).ReadToEndAsync();
+ string response = await new StreamReader(this.Request.Body).ReadToEndAsync();
+
+ string scannedText = CensorHelper.ScanMessage(response);
- Logger.Log($"{user.Username}: {loggedText}", LoggerLevelFilter.Instance);
- return this.Ok(loggedText);
+ Logger.Log($"{user.Username}: {response} / {scannedText}", LoggerLevelFilter.Instance);
+
+ return this.Ok(scannedText);
}
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Helpers/CensorHelper.cs b/ProjectLighthouse/Helpers/CensorHelper.cs
new file mode 100644
index 00000000..516cdf91
--- /dev/null
+++ b/ProjectLighthouse/Helpers/CensorHelper.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Text;
+using LBPUnion.ProjectLighthouse.Types;
+using LBPUnion.ProjectLighthouse.Types.Settings;
+
+namespace LBPUnion.ProjectLighthouse.Helpers;
+
+public static class CensorHelper
+{
+ private static readonly char[] randomCharacters =
+ {
+ '!', '@', '#', '$', '&', '%', '-', '_',
+ };
+
+ private static readonly string[] randomFurry =
+ {
+ "UwU", "OwO", "uwu", "owo", "o3o", ">.>", "*pounces on you*", "*boops*", "*baps*", ":P", "x3", "O_O", "xD", ":3", ";3", "^w^",
+ };
+
+ private static readonly string[] censorList = ResourceHelper.readManifestFile("chatCensoredList.txt").Split("\n");
+
+ public static string ScanMessage(string message)
+ {
+ if (ServerSettings.Instance.UserInputFilterMode == FilterMode.None) return message;
+
+ int profaneIndex = -1;
+
+ foreach (string profanity in censorList)
+ do
+ {
+ profaneIndex = message.ToLower().IndexOf(profanity, StringComparison.Ordinal);
+ if (profaneIndex != -1) message = Censor(profaneIndex, profanity.Length, message);
+ }
+ while (profaneIndex != -1);
+
+ return message;
+ }
+
+ private static string Censor(int profanityIndex, int profanityLength, string message)
+ {
+ StringBuilder sb = new();
+
+ char prevRandomChar = '\0';
+
+ sb.Append(message.AsSpan(0, profanityIndex));
+
+ switch (ServerSettings.Instance.UserInputFilterMode)
+ {
+ case FilterMode.Random:
+ for(int i = 0; i < profanityLength; i++)
+ lock(RandomHelper.random)
+ {
+ if (message[i] == ' ')
+ {
+ sb.Append(' ');
+ }
+ else
+ {
+ char randomChar = randomCharacters[RandomHelper.random.Next(0, randomCharacters.Length - 1)];
+ if (randomChar == prevRandomChar) randomChar = randomCharacters[RandomHelper.random.Next(0, randomCharacters.Length - 1)];
+
+ prevRandomChar = randomChar;
+
+ sb.Append(randomChar);
+ }
+ }
+
+ break;
+ case FilterMode.Asterisks:
+ for(int i = 0; i < profanityLength; i++)
+ {
+ if (message[i] == ' ')
+ {
+ sb.Append(' ');
+ }
+ else
+ {
+ sb.Append('*');
+ }
+ }
+
+ break;
+ case FilterMode.Furry:
+ lock(RandomHelper.random)
+ {
+ string randomWord = randomFurry[RandomHelper.random.Next(0, randomFurry.Length - 1)];
+ sb.Append(randomWord);
+ }
+
+ break;
+ }
+
+ sb.Append(message.AsSpan(profanityIndex + profanityLength));
+
+ return sb.ToString();
+ }
+}
\ No newline at end of file
diff --git a/ProjectLighthouse/Helpers/HashHelper.cs b/ProjectLighthouse/Helpers/HashHelper.cs
index e613df39..3cfe3a2a 100644
--- a/ProjectLighthouse/Helpers/HashHelper.cs
+++ b/ProjectLighthouse/Helpers/HashHelper.cs
@@ -14,7 +14,6 @@ public static class HashHelper
{
// private static readonly SHA1 sha1 = SHA1.Create();
private static readonly SHA256 sha256 = SHA256.Create();
- private static readonly Random random = new();
///
/// Generates a specified amount of random bytes in an array.
@@ -24,8 +23,12 @@ public static class HashHelper
public static IEnumerable GenerateRandomBytes(int count)
{
byte[] b = new byte[count];
- random.NextBytes(b);
-
+
+ lock (RandomHelper.random)
+ {
+ RandomHelper.random.NextBytes(b);
+ }
+
return b;
}
diff --git a/ProjectLighthouse/Helpers/RandomHelper.cs b/ProjectLighthouse/Helpers/RandomHelper.cs
new file mode 100644
index 00000000..f978717e
--- /dev/null
+++ b/ProjectLighthouse/Helpers/RandomHelper.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace LBPUnion.ProjectLighthouse.Helpers;
+
+public static class RandomHelper
+{
+ public static readonly Random random = new();
+}
\ No newline at end of file
diff --git a/ProjectLighthouse/Helpers/ResourceHelper.cs b/ProjectLighthouse/Helpers/ResourceHelper.cs
new file mode 100644
index 00000000..389155bd
--- /dev/null
+++ b/ProjectLighthouse/Helpers/ResourceHelper.cs
@@ -0,0 +1,20 @@
+using System;
+using System.IO;
+using System.Linq;
+using Kettu;
+using LBPUnion.ProjectLighthouse.Logging;
+using LBPUnion.ProjectLighthouse.Types.Settings;
+
+namespace LBPUnion.ProjectLighthouse.Helpers;
+
+public static class ResourceHelper
+{
+ public static string readManifestFile(string fileName)
+ {
+ using Stream stream =
+ typeof(Program).Assembly.GetManifestResourceStream($"{typeof(Program).Namespace}.{fileName}");
+ using StreamReader reader = new(stream ?? throw new Exception("The assembly or manifest resource is null."));
+
+ return reader.ReadToEnd().Trim();
+ }
+}
\ No newline at end of file
diff --git a/ProjectLighthouse/Helpers/VersionHelper.cs b/ProjectLighthouse/Helpers/VersionHelper.cs
index 3a806a5c..0e229ccb 100644
--- a/ProjectLighthouse/Helpers/VersionHelper.cs
+++ b/ProjectLighthouse/Helpers/VersionHelper.cs
@@ -13,10 +13,10 @@ public static class VersionHelper
{
try
{
- CommitHash = readManifestFile("gitVersion.txt");
- Branch = readManifestFile("gitBranch.txt");
+ CommitHash = ResourceHelper.readManifestFile("gitVersion.txt");
+ Branch = ResourceHelper.readManifestFile("gitBranch.txt");
- string remotesFile = readManifestFile("gitRemotes.txt");
+ string remotesFile = ResourceHelper.readManifestFile("gitRemotes.txt");
string[] lines = remotesFile.Split('\n');
@@ -26,7 +26,7 @@ public static class VersionHelper
// linq is a serious and painful catastrophe but its useful so i'm gonna keep using it
Remotes = lines.Select(line => line.Split("\t")[1]).ToArray();
- CommitsOutOfDate = readManifestFile("gitUnpushed.txt").Split('\n').Length;
+ CommitsOutOfDate = ResourceHelper.readManifestFile("gitUnpushed.txt").Split('\n').Length;
CanCheckForUpdates = true;
}
@@ -55,14 +55,6 @@ public static class VersionHelper
}
}
- private static string readManifestFile(string fileName)
- {
- using Stream stream = typeof(Program).Assembly.GetManifestResourceStream($"{typeof(Program).Namespace}.{fileName}");
- using StreamReader reader = new(stream ?? throw new Exception("The assembly or manifest resource is null."));
-
- return reader.ReadToEnd().Trim();
- }
-
public static string CommitHash { get; set; }
public static string Branch { get; set; }
public static string FullVersion => $"{ServerStatics.ServerName} {Branch}@{CommitHash} {Build}";
diff --git a/ProjectLighthouse/ProjectLighthouse.csproj b/ProjectLighthouse/ProjectLighthouse.csproj
index cc178e8a..12487b64 100644
--- a/ProjectLighthouse/ProjectLighthouse.csproj
+++ b/ProjectLighthouse/ProjectLighthouse.csproj
@@ -12,53 +12,57 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
+
+
+
-
+
Always
-
+
Always
-
+
Always
-
+
Always
-
-
+
+
+ Always
+
+
+
-
+
-
-
-
-
+
+
+
+
diff --git a/ProjectLighthouse/Types/FilterMode.cs b/ProjectLighthouse/Types/FilterMode.cs
new file mode 100644
index 00000000..194ad840
--- /dev/null
+++ b/ProjectLighthouse/Types/FilterMode.cs
@@ -0,0 +1,9 @@
+namespace LBPUnion.ProjectLighthouse.Types;
+
+public enum FilterMode
+{
+ None,
+ Asterisks,
+ Random,
+ Furry,
+}
\ No newline at end of file
diff --git a/ProjectLighthouse/Types/Settings/ServerSettings.cs b/ProjectLighthouse/Types/Settings/ServerSettings.cs
index 1ea4e3e5..06c7ff72 100644
--- a/ProjectLighthouse/Types/Settings/ServerSettings.cs
+++ b/ProjectLighthouse/Types/Settings/ServerSettings.cs
@@ -5,6 +5,7 @@ using System.Text.Json;
using System.Text.Json.Serialization;
using JetBrains.Annotations;
using Kettu;
+using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Logging;
namespace LBPUnion.ProjectLighthouse.Types.Settings;
@@ -12,7 +13,7 @@ namespace LBPUnion.ProjectLighthouse.Types.Settings;
[Serializable]
public class ServerSettings
{
- public const int CurrentConfigVersion = 24; // MUST BE INCREMENTED FOR EVERY CONFIG CHANGE!
+ public const int CurrentConfigVersion = 25; // MUST BE INCREMENTED FOR EVERY CONFIG CHANGE!
private static FileSystemWatcher fileWatcher;
static ServerSettings()
{
@@ -144,6 +145,8 @@ public class ServerSettings
public bool BooingEnabled { get; set; } = true;
+ public FilterMode UserInputFilterMode { get; set; } = FilterMode.None;
+
public bool DiscordWebhookEnabled { get; set; }
public string DiscordWebhookUrl { get; set; } = "";
diff --git a/ProjectLighthouse/chatCensoredList.txt b/ProjectLighthouse/chatCensoredList.txt
new file mode 100644
index 00000000..ecffdc55
--- /dev/null
+++ b/ProjectLighthouse/chatCensoredList.txt
@@ -0,0 +1,909 @@
+4r5e
+5h1t
+5hit
+a55
+anal
+anus
+ar5e
+arrse
+arse
+ass
+ass-fucker
+asses
+assfucker
+assfukka
+asshole
+assholes
+asswhole
+a_s_s
+b!tch
+b00bs
+b17ch
+b1tch
+ballbag
+balls
+ballsack
+bastard
+beastial
+beastiality
+bellend
+bestial
+bestiality
+bi+ch
+biatch
+bitch
+bitcher
+bitchers
+bitches
+bitchin
+bitching
+bloody
+blow job
+blowjob
+blowjobs
+boiolas
+bollock
+bollok
+boner
+boob
+boobs
+booobs
+boooobs
+booooobs
+booooooobs
+breasts
+buceta
+bugger
+bum
+bunny fucker
+butt
+butthole
+buttmunch
+buttplug
+c0ck
+c0cksucker
+carpet muncher
+cawk
+chink
+cipa
+cl1t
+clit
+clitoris
+clits
+cnut
+cock
+cock-sucker
+cockface
+cockhead
+cockmunch
+cockmuncher
+cocks
+cocksuck
+cocksucked
+cocksucker
+cocksucking
+cocksucks
+cocksuka
+cocksukka
+cok
+cokmuncher
+coksucka
+coon
+cox
+crap
+cum
+cummer
+cumming
+cums
+cumshot
+cunilingus
+cunillingus
+cunnilingus
+cunt
+cuntlick
+cuntlicker
+cuntlicking
+cunts
+cyalis
+cyberfuc
+cyberfuck
+cyberfucked
+cyberfucker
+cyberfuckers
+cyberfucking
+d1ck
+damn
+dick
+dickhead
+dildo
+dildos
+dink
+dinks
+dirsa
+dlck
+dog-fucker
+doggin
+dogging
+donkeyribber
+doosh
+duche
+dyke
+ejaculate
+ejaculated
+ejaculates
+ejaculating
+ejaculatings
+ejaculation
+ejakulate
+f u c k
+f u c k e r
+f4nny
+fridinator
+fag
+fagging
+faggitt
+faggot
+faggs
+fagot
+fagots
+fags
+fanny
+fannyflaps
+fannyfucker
+fanyy
+fatass
+fcuk
+fcuker
+fcuking
+feck
+fecker
+felching
+fellate
+fellatio
+fingerfuck
+fingerfucked
+fingerfucker
+fingerfuckers
+fingerfucking
+fingerfucks
+fistfuck
+fistfucked
+fistfucker
+fistfuckers
+fistfucking
+fistfuckings
+fistfucks
+flange
+fook
+fooker
+fuck
+fucka
+fucked
+fucker
+fuckers
+fuckhead
+fuckheads
+fuckin
+fucking
+fuckings
+fuckingshitmotherfucker
+fuckme
+fucks
+fuckwhit
+fuckwit
+fudge packer
+fudgepacker
+fuk
+fuker
+fukker
+fukkin
+fuks
+fukwhit
+fukwit
+fux
+fux0r
+f_u_c_k
+gangbang
+gangbanged
+gangbangs
+gaylord
+gaysex
+goatse
+god-dam
+god-damned
+goddamn
+goddamned
+hardcoresex
+hell
+heshe
+hoar
+hoare
+hoer
+homo
+hore
+horniest
+horny
+hotsex
+jack-off
+jackoff
+jap
+jerk-off
+jism
+jiz
+jizm
+jizz
+kawk
+knob
+knobead
+knobed
+knobend
+knobhead
+knobjocky
+knobjokey
+kock
+kondum
+kondums
+kum
+kummer
+kumming
+kums
+kunilingus
+kiunt
+l3i+ch
+l3itch
+labia
+lmfao
+lust
+lusting
+m0f0
+m0fo
+m45terbate
+ma5terb8
+ma5terbate
+masochist
+master-bate
+masterb8
+masterbat*
+masterbat3
+masterbate
+masterbation
+masterbations
+masturbate
+mo-fo
+mof0
+mofo
+mothafuck
+mothafucka
+mothafuckas
+mothafuckaz
+mothafucked
+mothafucker
+mothafuckers
+mothafuckin
+mothafucking
+mothafuckings
+mothafucks
+mother fucker
+motherfuck
+motherfucked
+motherfucker
+motherfuckers
+motherfuckin
+motherfucking
+motherfuckings
+motherfuckka
+motherfucks
+muff
+mutha
+muthafecker
+muthafuckker
+muther
+mutherfucker
+n1gga
+n1gger
+nazi
+nigg3r
+nigg4h
+nigga
+niggah
+niggas
+niggaz
+nigger
+niggers
+nob
+nob jokey
+nobhead
+nobjocky
+nobjokey
+numbnuts
+nutsack
+orgasim
+orgasims
+orgasm
+orgasms
+p0rn
+pawn
+pecker
+penis
+penisfucker
+phonesex
+phuck
+phuk
+phuked
+phuking
+phukked
+phukking
+phuks
+phuq
+pigfucker
+pimpis
+piss
+pissed
+pisser
+pissers
+pisses
+pissflaps
+pissin
+pissing
+pissoff
+poop
+porn
+porno
+pornography
+pornos
+prick
+pricks
+pron
+pube
+pusse
+pussi
+pussies
+pussy
+pussys
+rectum
+restitched
+retard
+rimjaw
+rimming
+s hit
+s.o.b.
+sadist
+schlong
+screwing
+scroat
+scrote
+scrotum
+semen
+sex
+sh!+
+sh!t
+sh1t
+shag
+shagger
+shaggin
+shagging
+shemale
+shi+
+shit
+shitdick
+shite
+shited
+shitey
+shitfuck
+shitfull
+shithead
+shiting
+shitings
+shits
+shitted
+shitter
+shitters
+shitting
+shittings
+shitty
+skank
+slut
+shiftos
+sluts
+smegma
+smut
+snatch
+son-of-a-bitch
+spac
+spunk
+s_h_i_t
+t1tt1e5
+t1tties
+teets
+teez
+testical
+testicle
+tit
+titfuck
+tits
+titt
+tittie5
+tittiefucker
+titties
+tittyfuck
+tittywank
+titwank
+toyo
+tosser
+turd
+tw4t
+twat
+twathead
+twatty
+twunt
+twunter
+v14gra
+v1gra
+vagina
+viagra
+vulva
+w00se
+wang
+wank
+wanker
+wanky
+whoar
+whore
+willies
+willy
+xrated
+xxx
+asesinato
+asno
+bastardo
+bollera
+cabrón
+caca
+chupada
+chupapollas
+chupetón
+concha
+concha de tu madre
+coño
+coprofagía
+culo
+drogas
+esperma
+fiesta de salchichas
+follador
+follar
+gilipichis
+gilipollas
+hacer una paja
+haciendo el amor
+heroína
+hija de puta
+hijaputa
+hijo de puta
+hijoputa
+idiota
+imbécil
+infierno
+jilipollas
+kapullo
+lameculos
+maciza
+macizorra
+maldito
+mamada
+marica
+maricón
+mariconazo
+martillo
+mierda
+orina
+pedo
+pendejo
+pervertido
+pezón
+pinche
+pis
+prostituta
+puta
+racista
+ramera
+sádico
+semen
+sexo
+sexo oral
+soplagaitas
+soplapollas
+tetas grandes
+tía buena
+travesti
+trio
+verga
+vete a la mierda
+vulva
+baiser
+bander
+bigornette
+bite
+bitte
+bloblos
+bordel
+bourré
+bourrée
+brackmard
+branlage
+branler
+branlette
+branleur
+branleuse
+brouter le cresson
+caca
+chatte
+chiasse
+chier
+chiottes
+clito
+clitoris
+con
+connard
+connasse
+conne
+couilles
+cramouille
+cul
+déconne
+déconner
+emmerdant
+emmerder
+emmerdeur
+emmerdeuse
+enculé
+enculée
+enculeur
+enculeurs
+enfoiré
+enfoirée
+étron
+fille de pute
+fils de pute
+folle
+foutre
+gerbe
+gerber
+gouine
+grande folle
+grogniasse
+gueule
+jouir
+la putain de ta mère
+malpt
+ménage à trois
+merde
+merdeuse
+merdeux
+meuf
+nègre
+nique ta mère
+nique ta race
+palucher
+pédale
+pédé
+péter
+pipi
+pisser
+pouffiasse
+pousse-crotte
+putain
+pute
+ramoner
+sac à foutre
+sac à merde
+salaud
+salope
+suce
+tapette
+tanche
+teuch
+tringler
+trique
+troncher
+trou du cul
+turlute
+zigounette
+zizi
+analritter
+arsch
+arschficker
+arschlecker
+arschloch
+bimbo
+bratze
+bumsen
+bonze
+dödel
+fick
+ficken
+flittchen
+fotze
+fratze
+hackfresse
+hure
+hurensohn
+ische
+kackbratze
+kacke
+kacken
+kackwurst
+kampflesbe
+kanake
+kimme
+lümmel
+milf
+möpse
+morgenlatte
+möse
+mufti
+muschi
+nackt
+neger
+nippel
+nutte
+onanieren
+orgasmus
+penis
+pimmel
+pimpern
+pinkeln
+pissen
+pisser
+popel
+poppen
+porno
+reudig
+rosette
+schabracke
+schlampe
+scheiße
+scheisser
+schiesser
+schnackeln
+schwanzlutscher
+schwuchtel
+tittchen
+titten
+vögeln
+vollpfosten
+wichse
+wichsen
+wichser
+arsle
+brutta
+discofitta
+dra åt helvete
+fan
+fitta
+fittig
+för helvete
+helvete
+hård
+jävlar
+knulla
+kuk
+kuksås
+kötthuvud
+köttnacke
+moona
+moonade
+moonar
+moonat
+mutta
+neger
+olla
+pippa
+pitt
+prutt
+pök
+runka
+röv
+rövhål
+rövknulla
+satan
+skita
+skit ner dig
+skäggbiff
+snedfitta
+snefitta
+stake
+subba
+sås
+sätta på
+tusan
+asshole
+dritt
+drittsekk
+faen
+faen i helvete
+fan
+fanken
+fitte
+forbanna
+forbannet
+forjævlig
+fuck
+fy faen
+føkk
+føkka
+føkkings
+jævla
+jævlig
+helvete
+helvetet
+kuk
+kukene
+kuker
+morraknuller
+morrapuler
+pakkis
+pikk
+pokker
+ræva
+ræven
+satan
+shit
+sinnsykt
+skitt
+sotrør
+ståpikk
+ståpikkene
+ståpikker
+svartheiteste
+bychara
+byk
+chernozhopyi
+dolboy'eb
+ebalnik
+ebalo
+ebalom sch'elkat
+gol
+mudack
+opizdenet
+osto'eblo
+ostokhuitel'no
+ot'ebis
+otmudohat
+otpizdit
+otsosi
+padlo
+pedik
+perdet
+petuh
+pidar gnoinyj
+pizda
+pizdato
+pizdatyi
+piz'det
+pizdetc
+pizdoi nakryt'sja
+pizd'uk
+piz`dyulina
+podi ku'evo
+poeben
+po'imat' na konchik
+po'iti posrat
+po khuy
+poluchit pizdy
+pososi moyu konfetku
+prissat
+proebat
+promudobl'adsksya pizdopro'ebina
+propezdoloch
+prosrat
+raspeezdeyi
+raspizdatyi
+raz'yebuy
+raz'yoba
+s'ebat'sya
+shalava
+styervo
+sukin syn
+svodit posrat
+svoloch
+trakhat'sya
+trimandoblydskiy pizdoproyob
+ubl'yudok
+uboy
+u'ebitsche
+vafl'a
+vafli lovit
+v pizdu
+vyperdysh
+vzdrochennyi
+yeb vas
+za'ebat
+zaebis
+zalupa
+zalupat
+zasranetc
+zassat
+zlo'ebuchy
+бздёнок
+блядки
+блядовать
+блядство
+блядь
+бугор
+во пизду
+встать раком
+выёбываться
+гандон
+говно
+говнюк
+голый
+дать пизды
+дерьмо
+дрочить
+другой дразнится
+ёбарь
+ебать
+ебать-копать
+ебло
+ебнуть
+ёб твою мать
+жопа
+жополиз
+играть на кожаной флейте
+измудохать
+каждый дрочит как он хочет
+какая разница
+как два пальца обоссать
+курите мою трубку
+лысого в кулаке гонять
+малофья
+манда
+мандавошка
+мент
+муда
+мудило
+мудозвон
+наебать
+наебениться
+наебнуться
+на фиг
+на хуй
+на хую вертеть
+на хуя
+нахуячиться
+невебенный
+не ебет
+ни за хуй собачу
+ни хуя
+обнаженный
+обоссаться можно
+один ебётся
+опесдол
+офигеть
+охуеть
+охуительно
+половое сношение
+секс
+сиськи
+спиздить
+срать
+ссать
+траxать
+ты мне ваньку не валяй
+фига
+хапать
+хер с ней
+хер с ним
+хохол
+хрен
+хуёво
+хуёвый
+хуем груши околачивать
+хуеплет
+хуило
+хуиней страдать
+хуиня
+хуй
+хуйнуть
+хуй пинать