mirror of
https://github.com/barelyprofessional/KfChatDotNet.git
synced 2026-08-01 19:18:31 -04:00
Added rapbattles courtesy of Bloitzhole
This commit is contained in:
@@ -0,0 +1,32 @@
|
|||||||
|
# Keno Kasino rap battle challenge flourishes
|
||||||
|
#
|
||||||
|
# When someone is challenged, the bot picks ONE of these lines at random and appends it to the
|
||||||
|
# challenge announcement, right after "...for <bet> a head." For example, picking "GET ON STAGE!"
|
||||||
|
# produces: "...you've been challenged to a RAP BATTLE by @X for 500 KKK a head. GET ON STAGE! Reply ..."
|
||||||
|
#
|
||||||
|
# One flourish per line. Blank lines and lines starting with '#' are ignored.
|
||||||
|
# {challenger} and {opponent} are replaced with the respective usernames (already @-prefixed).
|
||||||
|
#
|
||||||
|
# Edit this file freely - it's reloaded on every challenge, no restart required.
|
||||||
|
# The avelloon has, allegedly, been seen slipping a few of its own taunts in here.
|
||||||
|
|
||||||
|
GET ON STAGE!
|
||||||
|
Bars or be felted.
|
||||||
|
Step up or step off.
|
||||||
|
The avelloon is watching. Don't choke.
|
||||||
|
Time to find out who's really got bars.
|
||||||
|
Lace up, this one's for the culture.
|
||||||
|
No pen, no paper, no mercy.
|
||||||
|
The mic is hot and the crowd is mean.
|
||||||
|
Defend your honor or forfeit your juice.
|
||||||
|
{opponent}, the whole Kasino can hear the silence already.
|
||||||
|
Crack your knuckles, {opponent}.
|
||||||
|
Last one to spit is a Ratdad.
|
||||||
|
The booth is open. The judges are nefarious.
|
||||||
|
Don't bring bars to a felting.
|
||||||
|
Warm up that throat, {opponent}.
|
||||||
|
Either drop heat or drop out.
|
||||||
|
Cmon Cmon Cmon, prove you're not all talk.
|
||||||
|
The avelloon already wrote your eulogy. Prove it wrong.
|
||||||
|
Money's up. Egos higher. Let's go.
|
||||||
|
This is your moment, {opponent}. Don't fumble it.
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
# Keno Kasino rap battle feedback pool
|
||||||
|
#
|
||||||
|
# The Kasino "mediator" reads one of these lines at random to justify the winner of a
|
||||||
|
# rap battle. The result is PURE CHANCE - the actual verses are never read by anyone.
|
||||||
|
# These lines exist purely to preserve the illusion that the bars mattered.
|
||||||
|
#
|
||||||
|
# One reason per line. Blank lines and lines starting with '#' are ignored.
|
||||||
|
# {winner} and {loser} are replaced with the respective usernames (already @-prefixed).
|
||||||
|
# {verse} is replaced with a short, sanitised snippet of the WINNER's submitted verse,
|
||||||
|
# so you can write lines that "quote" the bars - e.g. the lines near the bottom of this file.
|
||||||
|
#
|
||||||
|
# Edit this file freely - it's reloaded every battle, no restart required.
|
||||||
|
# An avelloon was last seen tampering with these lines. Audit accordingly.
|
||||||
|
|
||||||
|
{winner}'s flow was tighter than {loser}'s budget after a night at the Kasino.
|
||||||
|
The judges felt {winner}'s bars in their soul, while {loser} mostly mumbled into the mic.
|
||||||
|
{winner} stayed on beat; {loser} was rapping to a metronome only they could hear.
|
||||||
|
{winner}'s punchlines actually landed. {loser} threw haymakers at the air.
|
||||||
|
{winner} had the crowd bouncing. {loser} had the crowd checking their phones.
|
||||||
|
{winner}'s wordplay was surgical. {loser} brought a spork to a knife fight.
|
||||||
|
{winner} controlled the cypher from bar one. {loser} got lost looking for it.
|
||||||
|
{winner}'s delivery was ice cold. {loser} sweated through every syllable.
|
||||||
|
{winner} painted pictures with every line. {loser} drew stick figures.
|
||||||
|
{winner}'s rhyme scheme was a labyrinth. {loser}'s rhymed 'cat' with 'cat'.
|
||||||
|
{winner} switched flows three times mid-verse. {loser} forgot the one flow they had.
|
||||||
|
{winner}'s breath control was elite. {loser} tapped out halfway through the first bar.
|
||||||
|
{winner} weaponized the silence between bars. {loser} just filled it with 'uhh'.
|
||||||
|
{winner}'s metaphors hit like a felted plane. {loser}'s landed like a wet rizla.
|
||||||
|
{winner} freestyled circles around {loser}'s pre-written notes-app verse.
|
||||||
|
{winner} had bars for days. {loser} had a payment plan.
|
||||||
|
{winner}'s cadence was hypnotic. {loser}'s put the front row to sleep.
|
||||||
|
{winner} dropped a triple entendre. {loser} dropped the mic on their own foot.
|
||||||
|
{winner}'s diss was personal and devastating. {loser} apologized mid-verse.
|
||||||
|
The Kasino's certified-fair applause-o-meter clocked {winner} at double {loser}'s volume.
|
||||||
|
{winner} brought the heat; {loser} brought a participation trophy.
|
||||||
|
{winner} rhymed in pocket. {loser} rhymed in another area code.
|
||||||
|
{winner}'s closer left the room speechless. {loser}'s closer left the room.
|
||||||
|
{winner} simply wanted it more, and the algorithm respects hunger.
|
||||||
|
{winner} spit fire. {loser} spit, then forgot the rest.
|
||||||
|
|
||||||
|
# Lines that quote the winner's verse with {verse}:
|
||||||
|
The Kasino found the line "{verse}" very moving. You win, {winner}.
|
||||||
|
"{verse}" — the judges replayed that bar three times. {winner} takes it over {loser}.
|
||||||
|
When {winner} dropped "{verse}", {loser} knew it was over.
|
||||||
|
"{verse}". Chills. That's a {winner} victory, no debate.
|
||||||
|
The mediator is still quoting "{verse}" in the back office. {winner} wins.
|
||||||
|
{loser} never recovered after {winner} hit them with "{verse}".
|
||||||
|
That "{verse}" line had the whole room gasping. Crown goes to {winner}.
|
||||||
|
|
||||||
|
# Lines where the avelloon - a nefarious, cat-shaped balloon that rigs casinos - presides as judge:
|
||||||
|
The avelloon, a cat-shaped balloon of pure malice, bobbed toward {winner} and declared the battle rigged in their favor.
|
||||||
|
The judge tonight is the avelloon. It rigged the scoreboard, doxxed {loser}'s rhyme notes, and crowned {winner} anyway.
|
||||||
|
The avelloon floated over the booth, hissed at {loser}, and pawed the win to {winner}. Probably fair.
|
||||||
|
A nefarious balloon shaped like a cat — the avelloon — inflated with glee and awarded the bag to {winner}.
|
||||||
|
The avelloon doesn't read bars, it reads leaked data. It found dirt on {loser} and handed {winner} the W.
|
||||||
|
By decree of the avelloon, the rigging cat balloon that owns this Kasino: {winner} wins. Appeals go in the trash.
|
||||||
|
The avelloon batted the verdict between its paws, then let it drift to {winner}. {loser} was felted by helium and spite.
|
||||||
|
The avelloon judged "{verse}" the realest bar of the night. {winner} takes it; {loser} got rigged, as is tradition.
|
||||||
|
The avelloon squeaked once, ominously, and the scoreboard flipped to {winner}. Nobody questions the balloon.
|
||||||
|
The avelloon rigged it, the avelloon owns it, the avelloon says {winner}. {loser}, file a complaint with the cat.
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -51,6 +51,15 @@
|
|||||||
<Content Include="NLog.config">
|
<Content Include="NLog.config">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<None Remove="rapbattle_feedback.txt" />
|
||||||
|
<!-- PreserveNewest so admins can edit the feedback pool in the output dir without rebuilds clobbering it -->
|
||||||
|
<None Remove="rapbattle_challenges.txt" />
|
||||||
|
<Content Update="Assets\rapbattle_challenges.txt">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\rapbattle_feedback.txt">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -311,7 +311,9 @@ public enum WagerGame
|
|||||||
[Description("Roulette but live")]
|
[Description("Roulette but live")]
|
||||||
Roulette,
|
Roulette,
|
||||||
Krash,
|
Krash,
|
||||||
Cecil
|
Cecil,
|
||||||
|
[Description("Rap Battle")]
|
||||||
|
RapBattle
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum GamblerState
|
public enum GamblerState
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ public class BotServices
|
|||||||
|
|
||||||
private Task? _websocketWatchdog;
|
private Task? _websocketWatchdog;
|
||||||
private Task? _howlggGetUserTimer;
|
private Task? _howlggGetUserTimer;
|
||||||
|
private Task? _rapBattleTimeoutSweeper;
|
||||||
|
|
||||||
private string? _bmjTwitchUsername;
|
private string? _bmjTwitchUsername;
|
||||||
private bool _twitchDisabled;
|
private bool _twitchDisabled;
|
||||||
@@ -114,6 +115,28 @@ public class BotServices
|
|||||||
_logger.Info("Starting websocket watchdog and Howl.gg user stats timer");
|
_logger.Info("Starting websocket watchdog and Howl.gg user stats timer");
|
||||||
_websocketWatchdog = WebsocketWatchdog();
|
_websocketWatchdog = WebsocketWatchdog();
|
||||||
_howlggGetUserTimer = HowlggGetUserTimer();
|
_howlggGetUserTimer = HowlggGetUserTimer();
|
||||||
|
_rapBattleTimeoutSweeper = RapBattleTimeoutSweeperTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Durable replacement for the rap battle's old in-memory timeout timers: rap battle state lives in
|
||||||
|
// Redis, and this periodically refunds any battle whose deadline has passed - so timeouts still fire
|
||||||
|
// after a restart. No-ops cheaply when Redis isn't configured.
|
||||||
|
private async Task RapBattleTimeoutSweeperTask()
|
||||||
|
{
|
||||||
|
using var timer = new PeriodicTimer(TimeSpan.FromSeconds(5));
|
||||||
|
while (await timer.WaitForNextTickAsync(_cancellationToken))
|
||||||
|
{
|
||||||
|
if (_chatBot.InitialStartCooldown) continue;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await Commands.Kasino.RapBattleCommand.SweepExpiredBattlesAsync(_chatBot);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.Error("Rap battle timeout sweep failed");
|
||||||
|
_logger.Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task BuildKasinoKrash()
|
private async Task BuildKasinoKrash()
|
||||||
|
|||||||
@@ -597,6 +597,30 @@ public static class BuiltIn
|
|||||||
public static string KasinoPlinkoSize = "Kasino.Plinko.Size";
|
public static string KasinoPlinkoSize = "Kasino.Plinko.Size";
|
||||||
[BuiltInSetting("Whether Cecil is enabled", SettingValueType.Boolean, "true", BooleanRegex)]
|
[BuiltInSetting("Whether Cecil is enabled", SettingValueType.Boolean, "true", BooleanRegex)]
|
||||||
public static string KasinoCecilEnabled = "Kasino.Cecil.Enabled";
|
public static string KasinoCecilEnabled = "Kasino.Cecil.Enabled";
|
||||||
|
[BuiltInSetting("Whether the rap battle game is enabled", SettingValueType.Boolean, "true", BooleanRegex)]
|
||||||
|
public static string KasinoRapBattleEnabled = "Kasino.RapBattle.Enabled";
|
||||||
|
[BuiltInSetting("How many seconds players have to accept a rap battle, and (once accepted) to submit their verses", SettingValueType.Text, "90", WholeNumberRegex)]
|
||||||
|
public static string KasinoRapBattleTimeout = "Kasino.RapBattle.Timeout";
|
||||||
|
[BuiltInSetting("Percentage of the pot the Kasino keeps as mediator when a rap battle is decided", SettingValueType.Text, "10")]
|
||||||
|
public static string KasinoRapBattleCasinoCutPercent = "Kasino.RapBattle.CasinoCutPercent";
|
||||||
|
[BuiltInSetting("Percentage fee the Kasino keeps when a rap battle is declined or times out and buy-ins are refunded", SettingValueType.Text, "5")]
|
||||||
|
public static string KasinoRapBattleRefundFeePercent = "Kasino.RapBattle.RefundFeePercent";
|
||||||
|
[BuiltInSetting("Minimum bet for a rap battle", SettingValueType.Text, "1", WholeNumberRegex)]
|
||||||
|
public static string KasinoRapBattleMinimumBet = "Kasino.RapBattle.MinimumBet";
|
||||||
|
[BuiltInSetting("Minimum length (in characters) of a rap battle verse, to guard against low-effort one-word entries", SettingValueType.Text, "12", WholeNumberRegex)]
|
||||||
|
public static string KasinoRapBattleMinimumVerseLength = "Kasino.RapBattle.MinimumVerseLength";
|
||||||
|
[BuiltInSetting("Minimum number of bars (sentences separated by full stops) a rap battle verse must contain. There is no maximum", SettingValueType.Text, "3", WholeNumberRegex)]
|
||||||
|
public static string KasinoRapBattleMinimumBars = "Kasino.RapBattle.MinimumBars";
|
||||||
|
[BuiltInSetting("Delay in milliseconds before cleaning up transient rap battle status / error messages", SettingValueType.Text, "15000", WholeNumberRegex)]
|
||||||
|
public static string KasinoRapBattleCleanupDelay = "Kasino.RapBattle.CleanupDelay";
|
||||||
|
[BuiltInSetting("Delay in milliseconds the bot spends 'evaluating' the verses (fake suspense) before revealing a rap battle result", SettingValueType.Text, "3500", WholeNumberRegex)]
|
||||||
|
public static string KasinoRapBattleEvaluatingDelay = "Kasino.RapBattle.EvaluatingDelay";
|
||||||
|
[BuiltInSetting("Path to the editable text file containing the pool of (fictional) rap battle feedback lines. One reason per line, lines starting with # are ignored, {winner}, {loser} and {verse} are substituted", SettingValueType.Text, "rapbattle_feedback.txt")]
|
||||||
|
public static string KasinoRapBattleFeedbackFile = "Kasino.RapBattle.FeedbackFile";
|
||||||
|
[BuiltInSetting("Path to the editable text file containing the pool of rap battle challenge flourishes appended to the challenge message (e.g. 'GET ON STAGE!'). One per line, lines starting with # are ignored, {challenger} and {opponent} are substituted", SettingValueType.Text, "rapbattle_challenges.txt")]
|
||||||
|
public static string KasinoRapBattleChallengeFile = "Kasino.RapBattle.ChallengeFile";
|
||||||
|
[BuiltInSetting("Whether the rap battle cheat code is active. Burned out permanently (set false) the first time both rappers invoke it in the same battle", SettingValueType.Boolean, "true", BooleanRegex)]
|
||||||
|
public static string KasinoRapBattleCheatEnabled = "Kasino.RapBattle.CheatEnabled";
|
||||||
[BuiltInSetting("Proxy to use when connecting to Kiwi Farms for WS and logging in", SettingValueType.Text)]
|
[BuiltInSetting("Proxy to use when connecting to Kiwi Farms for WS and logging in", SettingValueType.Text)]
|
||||||
public static string KiwiFarmsProxy = "KiwiFarms.Proxy";
|
public static string KiwiFarmsProxy = "KiwiFarms.Proxy";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user