forked from rDrama/rDrama
Merge branch 'frost' of https://github.com/Aevann1/rDrama into frost
commit
41f9a128ac
|
@ -0,0 +1,138 @@
|
||||||
|
.casino-games {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.casino-game {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Slots */
|
||||||
|
#slots-block {
|
||||||
|
max-width: 700px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.casino-slots-results {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.casino-slots-results .reel {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
border: 2px solid black;
|
||||||
|
background-color: var(--gray);
|
||||||
|
border: 1px solid var(--black);
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.casino-slots-outcome {
|
||||||
|
visibility: hidden;
|
||||||
|
text-align: right;
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Blackjack */
|
||||||
|
#blackjack-block {
|
||||||
|
max-width: 800px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
.blackjack-table .hand .playing-card {
|
||||||
|
width: 60px;
|
||||||
|
height: 90px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.casino-blackjack-outcome {
|
||||||
|
visibility: hidden;
|
||||||
|
text-align: right;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blackjack-table {
|
||||||
|
max-width: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blackjack-table .hand {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blackjack-table .hand .playing-card {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 60px;
|
||||||
|
height: 90px;
|
||||||
|
border: 2px solid black;
|
||||||
|
background-color: var(--gray);
|
||||||
|
border: 1px solid var(--black);
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blackjack-table .hand .playing-card.dealt {
|
||||||
|
background-color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.casino-blackjack-actions {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lottery */
|
||||||
|
.casino-lottery {
|
||||||
|
margin-top: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Blocks */
|
||||||
|
.casino-block {
|
||||||
|
padding: 1rem;
|
||||||
|
border: 4px solid #361506;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: #092711;
|
||||||
|
margin: 2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.casino-block-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 32px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 4px;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.casino-block-inner {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.casino-block-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: center;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
.casino-block-left {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.casino-block-game {
|
||||||
|
margin-right: 2rem;
|
||||||
|
}
|
|
@ -5383,7 +5383,6 @@ audio, video {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 2rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.lottery-page--wrapper > div {
|
.lottery-page--wrapper > div {
|
||||||
|
@ -5987,6 +5986,7 @@ g {
|
||||||
.fa-snowflake:before{content:"\f2dc"}
|
.fa-snowflake:before{content:"\f2dc"}
|
||||||
.fa-sparkles:before{content:"\f890"}
|
.fa-sparkles:before{content:"\f890"}
|
||||||
.fa-ticket:before{content:"\f145"}
|
.fa-ticket:before{content:"\f145"}
|
||||||
|
.fa-usd:before{content:"\f155"}
|
||||||
.fa-spider:before{content:"\f717"}
|
.fa-spider:before{content:"\f717"}
|
||||||
.fa-square:before{content:"\f0c8"}
|
.fa-square:before{content:"\f0c8"}
|
||||||
.fa-stocking:before{content:"\f7d5"}
|
.fa-stocking:before{content:"\f7d5"}
|
||||||
|
|
|
@ -0,0 +1,345 @@
|
||||||
|
// Shared
|
||||||
|
function updatePlayerCoins(updated) {
|
||||||
|
if (updated.coins) {
|
||||||
|
document.getElementById('user-coins-amount').innerText = updated.coins;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updated.procoins) {
|
||||||
|
document.getElementById('user-bux-amount').innerText = updated.procoins;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slots
|
||||||
|
function pullSlots() {
|
||||||
|
const wager = document.getElementById("casinoSlotsBet").value;
|
||||||
|
const currency = document.querySelector(
|
||||||
|
'input[name="casinoSlotsCurrency"]:checked'
|
||||||
|
).value;
|
||||||
|
|
||||||
|
document.getElementById("casinoSlotsBet").disabled = true;
|
||||||
|
document.getElementById("casinoSlotsPull").disabled = true;
|
||||||
|
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("post", "/casino/slots");
|
||||||
|
xhr.onload = handleSlotsResponse.bind(null, xhr);
|
||||||
|
|
||||||
|
const form = new FormData();
|
||||||
|
form.append("formkey", formkey());
|
||||||
|
form.append("wager", wager);
|
||||||
|
form.append("currency", currency);
|
||||||
|
|
||||||
|
xhr.send(form);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSlotsResponse(xhr) {
|
||||||
|
let response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = JSON.parse(xhr.response);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
const succeeded =
|
||||||
|
xhr.status >= 200 && xhr.status < 300 && response && !response.error;
|
||||||
|
const slotsResult = document.getElementById("casinoSlotsResult");
|
||||||
|
slotsResult.classList.remove("text-success", "text-danger");
|
||||||
|
|
||||||
|
if (succeeded) {
|
||||||
|
const { game_state, gambler } = response;
|
||||||
|
const state = JSON.parse(game_state);
|
||||||
|
const reels = Array.from(document.querySelectorAll(".reel"));
|
||||||
|
const symbols = state.symbols.split(",");
|
||||||
|
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
reels[i].innerHTML = symbols[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
slotsResult.style.visibility = "visible";
|
||||||
|
slotsResult.innerText = state.text;
|
||||||
|
|
||||||
|
if (state.text.includes("Won")) {
|
||||||
|
if (state.text.includes("Jackpot")) {
|
||||||
|
slotsResult.classList.add("text-warning");
|
||||||
|
} else {
|
||||||
|
slotsResult.classList.add("text-success");
|
||||||
|
}
|
||||||
|
} else if (state.text.includes("Lost")) {
|
||||||
|
slotsResult.classList.add("text-danger");
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePlayerCoins(gambler);
|
||||||
|
} else {
|
||||||
|
slotsResult.style.visibility = "visible";
|
||||||
|
slotsResult.innerText = response.error;
|
||||||
|
slotsResult.classList.add("text-danger");
|
||||||
|
|
||||||
|
console.error(response.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("casinoSlotsBet").disabled = false;
|
||||||
|
document.getElementById("casinoSlotsPull").disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blackjack
|
||||||
|
// When the casino loads, look up the "blackjack status" of a player to either start a new game or continue an existing game.
|
||||||
|
if (
|
||||||
|
document.readyState === "complete" ||
|
||||||
|
(document.readyState !== "loading" && !document.documentElement.doScroll)
|
||||||
|
) {
|
||||||
|
checkBlackjackStatus();
|
||||||
|
} else {
|
||||||
|
document.addEventListener("DOMContentLoaded", checkBlackjackStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkBlackjackStatus() {
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("get", "/casino/blackjack");
|
||||||
|
xhr.onload = handleBlackjackStatusResponse.bind(null, xhr);
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleBlackjackStatusResponse(xhr) {
|
||||||
|
let response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = JSON.parse(xhr.response);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
const succeeded =
|
||||||
|
xhr.status >= 200 && xhr.status < 300 && response && !response.error;
|
||||||
|
|
||||||
|
if (succeeded) {
|
||||||
|
if (response.active) {
|
||||||
|
updateBlackjack(response.game_state);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error("error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// When starting a new game or taking an action in an existing one, a new state will be returned, and the DOM must be updated.
|
||||||
|
function updateBlackjack(state) {
|
||||||
|
const { player, dealer, status } = state;
|
||||||
|
const lettersToSuits = {
|
||||||
|
S: "♠️",
|
||||||
|
H: "♥️",
|
||||||
|
C: "♣️",
|
||||||
|
D: "♦️",
|
||||||
|
"?": "?",
|
||||||
|
};
|
||||||
|
const suitsToColors = {
|
||||||
|
"♠️": "black",
|
||||||
|
"♥️": "red",
|
||||||
|
"♣️": "black",
|
||||||
|
"♦️": "red",
|
||||||
|
"?": "black",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Clear everything.
|
||||||
|
Array.from(document.querySelectorAll(".playing-card")).forEach((card) => {
|
||||||
|
card.innerText = "";
|
||||||
|
card.style.color = "unset";
|
||||||
|
card.classList.remove("dealt");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Show dealer cards.
|
||||||
|
const dealerSlots = Array.from(
|
||||||
|
document.querySelectorAll('.playing-card[data-who="dealer"]')
|
||||||
|
);
|
||||||
|
for (let i = 0; i < dealer.length; i++) {
|
||||||
|
const slot = dealerSlots[i];
|
||||||
|
|
||||||
|
if (slot) {
|
||||||
|
// Technically, the dealer can use more than 5 cards, though it's rare.
|
||||||
|
// In that case, the result message is good enough.
|
||||||
|
// Thanks, Carp. 🐠
|
||||||
|
slot.classList.add("dealt");
|
||||||
|
|
||||||
|
if (i > 0 && status === "active") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rank = dealer[i][0];
|
||||||
|
const suit = lettersToSuits[dealer[i][1]];
|
||||||
|
const card = rank + suit;
|
||||||
|
slot.innerText = card;
|
||||||
|
slot.style.color = suitsToColors[suit];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show player cards.
|
||||||
|
const playerSlots = Array.from(
|
||||||
|
document.querySelectorAll('.playing-card[data-who="player"]')
|
||||||
|
);
|
||||||
|
for (let i = 0; i < player.length; i++) {
|
||||||
|
const slot = playerSlots[i];
|
||||||
|
const rank = player[i][0];
|
||||||
|
const suit = lettersToSuits[player[i][1]];
|
||||||
|
const card = rank + suit;
|
||||||
|
slot.innerText = card;
|
||||||
|
slot.style.color = suitsToColors[suit];
|
||||||
|
slot.classList.add("dealt");
|
||||||
|
}
|
||||||
|
|
||||||
|
updateBlackjackActions(state);
|
||||||
|
|
||||||
|
if (status !== "active") {
|
||||||
|
revealBlackjackResult(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function revealBlackjackResult(state) {
|
||||||
|
const blackjackResult = document.getElementById("casinoBlackjackResult");
|
||||||
|
const lookup = {
|
||||||
|
bust: ["Bust. Didn't work out for you, did it?", "danger"],
|
||||||
|
push: ["Pushed. This whole hand never happened.", "secondary"],
|
||||||
|
insured_loss: ["Lost, but at least you had insurance.", "secondary"],
|
||||||
|
lost: ["Lost. That was pathetic.", "danger"],
|
||||||
|
won: ["Won. This time.", "success"],
|
||||||
|
blackjack: ["Blackjack! Must be your lucky day.", "warning"],
|
||||||
|
};
|
||||||
|
const [resultText, resultClass] = lookup[state.status];
|
||||||
|
|
||||||
|
blackjackResult.style.visibility = "visible";
|
||||||
|
blackjackResult.innerText = resultText;
|
||||||
|
blackjackResult.classList.add(`text-${resultClass}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildBlackjackAction(id, method, title, fullWidth = false) {
|
||||||
|
return `
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-${
|
||||||
|
fullWidth ? "primary" : "secondary"
|
||||||
|
} lottery-page--action"
|
||||||
|
id="${id}"
|
||||||
|
onclick="${method}()"
|
||||||
|
style="${fullWidth ? "width: 100%;" : ""}"
|
||||||
|
>
|
||||||
|
${title}
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearBlackjackActions() {
|
||||||
|
const actionWrapper = document.getElementById("casinoBlackjackActions");
|
||||||
|
actionWrapper.innerHTML = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateBlackjackActions(state) {
|
||||||
|
const actionWrapper = document.getElementById("casinoBlackjackActions");
|
||||||
|
|
||||||
|
clearBlackjackActions();
|
||||||
|
|
||||||
|
if (state.status === "active") {
|
||||||
|
document.getElementById("casinoBlackjackWager").style.display = "none";
|
||||||
|
|
||||||
|
const actionLookup = {
|
||||||
|
hit: buildBlackjackAction("casinoBlackjackHit", "hitBlackjack", "Hit"),
|
||||||
|
stay: buildBlackjackAction(
|
||||||
|
"casinoBlackjackStay",
|
||||||
|
"stayBlackjack",
|
||||||
|
"Stay"
|
||||||
|
),
|
||||||
|
double_down: buildBlackjackAction(
|
||||||
|
"casinoBlackjackDouble",
|
||||||
|
"doubleBlackjack",
|
||||||
|
"Double Down"
|
||||||
|
),
|
||||||
|
insure: buildBlackjackAction(
|
||||||
|
"casinoBlackjackInsure",
|
||||||
|
"insureBlackjack",
|
||||||
|
"Insure"
|
||||||
|
),
|
||||||
|
};
|
||||||
|
const actions = state.actions.map((action) => actionLookup[action]);
|
||||||
|
|
||||||
|
actionWrapper.innerHTML = actions.join("\n");
|
||||||
|
} else {
|
||||||
|
// Game is over, deal a new game.
|
||||||
|
document.getElementById("casinoBlackjackWager").style.display = "flex";
|
||||||
|
|
||||||
|
const deal = buildBlackjackAction(
|
||||||
|
"casinoBlackjackDeal",
|
||||||
|
"dealBlackjack",
|
||||||
|
"Deal",
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
actionWrapper.innerHTML = deal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dealBlackjack() {
|
||||||
|
const wager = document.getElementById("casinoBlackjackBet").value;
|
||||||
|
const currency = document.querySelector(
|
||||||
|
'input[name="casinoBlackjackCurrency"]:checked'
|
||||||
|
).value;
|
||||||
|
|
||||||
|
document.getElementById("casinoBlackjackBet").disabled = true;
|
||||||
|
document.getElementById("casinoBlackjackDeal").disabled = true;
|
||||||
|
document.getElementById("casinoBlackjackWager").style.display = "none";
|
||||||
|
document.getElementById("casinoBlackjackResult").style.visibility = "hidden";
|
||||||
|
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("post", "/casino/blackjack");
|
||||||
|
xhr.onload = handleBlackjackResponse.bind(null, xhr);
|
||||||
|
|
||||||
|
const form = new FormData();
|
||||||
|
form.append("formkey", formkey());
|
||||||
|
form.append("wager", wager);
|
||||||
|
form.append("currency", currency);
|
||||||
|
|
||||||
|
xhr.send(form);
|
||||||
|
}
|
||||||
|
|
||||||
|
function takeBlackjackAction(action) {
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("post", "/casino/blackjack/action");
|
||||||
|
xhr.onload = handleBlackjackResponse.bind(null, xhr);
|
||||||
|
|
||||||
|
const form = new FormData();
|
||||||
|
form.append("formkey", formkey());
|
||||||
|
form.append("action", action);
|
||||||
|
|
||||||
|
xhr.send(form);
|
||||||
|
}
|
||||||
|
|
||||||
|
const hitBlackjack = takeBlackjackAction.bind(null, "hit");
|
||||||
|
const stayBlackjack = takeBlackjackAction.bind(null, "stay");
|
||||||
|
const doubleBlackjack = takeBlackjackAction.bind(null, "double_down");
|
||||||
|
const insureBlackjack = takeBlackjackAction.bind(null, "insure");
|
||||||
|
|
||||||
|
function handleBlackjackResponse(xhr) {
|
||||||
|
let response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = JSON.parse(xhr.response);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
const succeeded =
|
||||||
|
xhr.status >= 200 && xhr.status < 300 && response && !response.error;
|
||||||
|
const blackjackResult = document.getElementById("casinoBlackjackResult");
|
||||||
|
blackjackResult.classList.remove("text-success", "text-danger");
|
||||||
|
|
||||||
|
if (succeeded) {
|
||||||
|
if (response.game_state) {
|
||||||
|
updateBlackjack(response.game_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.gambler) {
|
||||||
|
updatePlayerCoins(response.gambler);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
blackjackResult.style.visibility = "visible";
|
||||||
|
blackjackResult.innerText = response.error;
|
||||||
|
blackjackResult.classList.add("text-danger");
|
||||||
|
|
||||||
|
console.error(response.error);
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,4 +23,5 @@ from .views import *
|
||||||
from .notifications import *
|
from .notifications import *
|
||||||
from .follows import *
|
from .follows import *
|
||||||
from .lottery import *
|
from .lottery import *
|
||||||
|
from .casino_game import *
|
||||||
from .hats import *
|
from .hats import *
|
|
@ -0,0 +1,27 @@
|
||||||
|
from sqlalchemy import *
|
||||||
|
from files.__main__ import Base
|
||||||
|
from files.helpers.lazy import lazy
|
||||||
|
from files.helpers.const import *
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
class Casino_Game(Base):
|
||||||
|
__tablename__ = "casino_games"
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
user_id = Column(Integer, ForeignKey("users.id"))
|
||||||
|
created_utc = Column(Integer)
|
||||||
|
active = Column(Boolean, default=True)
|
||||||
|
currency = Column(String)
|
||||||
|
wager = Column(Integer)
|
||||||
|
winnings = Column(Integer)
|
||||||
|
kind = Column(String)
|
||||||
|
game_state = Column(JSON)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
if "created_utc" not in kwargs:
|
||||||
|
kwargs["created_utc"] = int(time.time())
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<CasinoGame(id={self.id})>"
|
|
@ -60,8 +60,6 @@ class Comment(Base):
|
||||||
body = Column(String)
|
body = Column(String)
|
||||||
body_html = Column(String)
|
body_html = Column(String)
|
||||||
ban_reason = Column(String)
|
ban_reason = Column(String)
|
||||||
slots_result = Column(String)
|
|
||||||
blackjack_result = Column(String)
|
|
||||||
wordle_result = Column(String)
|
wordle_result = Column(String)
|
||||||
treasure_amount = Column(String)
|
treasure_amount = Column(String)
|
||||||
|
|
||||||
|
@ -412,7 +410,7 @@ class Comment(Base):
|
||||||
|
|
||||||
if self.is_banned: return True
|
if self.is_banned: return True
|
||||||
|
|
||||||
if (self.slots_result or self.blackjack_result or self.wordle_result) and (not self.body or len(self.body_html) <= 100) and 9 > self.level > 1: return True
|
if (self.wordle_result) and (not self.body or len(self.body_html) <= 100) and 9 > self.level > 1: return True
|
||||||
|
|
||||||
if v and v.filter_words and self.body and any(x in self.body for x in v.filter_words): return True
|
if v and v.filter_words and self.body and any(x in self.body for x in v.filter_words): return True
|
||||||
|
|
||||||
|
@ -450,71 +448,3 @@ class Comment(Base):
|
||||||
|
|
||||||
body += '</span>'
|
body += '</span>'
|
||||||
return body
|
return body
|
||||||
|
|
||||||
@lazy
|
|
||||||
def blackjack_html(self, v):
|
|
||||||
if not self.blackjack_result: return ''
|
|
||||||
|
|
||||||
split_result = self.blackjack_result.split('_')
|
|
||||||
blackjack_status = split_result[3]
|
|
||||||
player_hand = split_result[0].replace('X', '10')
|
|
||||||
dealer_hand = split_result[1].split('/')[0] if blackjack_status == 'active' else split_result[1]
|
|
||||||
dealer_hand = dealer_hand.replace('X', '10')
|
|
||||||
wager = int(split_result[4])
|
|
||||||
try: kind = split_result[5]
|
|
||||||
except: kind = "coins"
|
|
||||||
currency_kind = "Coins" if kind == "coins" else "Marseybux"
|
|
||||||
|
|
||||||
try: is_insured = split_result[6]
|
|
||||||
except: is_insured = "0"
|
|
||||||
|
|
||||||
body = f"<span id='blackjack-{self.id}' class='ml-2'><em>{player_hand} vs. {dealer_hand}</em>"
|
|
||||||
|
|
||||||
if blackjack_status == 'active' and v and v.id == self.author_id:
|
|
||||||
body += f'''
|
|
||||||
<button
|
|
||||||
class="action-{self.id} btn btn-success small"
|
|
||||||
style="text-transform: uppercase; padding: 2px"
|
|
||||||
onclick="handle_action('blackjack','{self.id}','hit')">
|
|
||||||
Hit
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="action-{self.id} btn btn-danger small"
|
|
||||||
style="text-transform: uppercase; padding: 2px"
|
|
||||||
onclick="handle_action('blackjack','{self.id}','stay')">
|
|
||||||
Stay
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="action-{self.id} btn btn-secondary small"
|
|
||||||
style="text-transform: uppercase; padding: 2px"
|
|
||||||
onclick="handle_action('blackjack','{self.id}','doubledown')">
|
|
||||||
Double Down
|
|
||||||
</button>
|
|
||||||
'''
|
|
||||||
|
|
||||||
if dealer_hand[0][0] == 'A' and not is_insured == "1":
|
|
||||||
body += f'''
|
|
||||||
<button
|
|
||||||
class="action-{self.id} btn btn-secondary small"
|
|
||||||
style="text-transform: uppercase; padding: 2px"
|
|
||||||
onclick="handle_action('blackjack','{self.id}','insurance')">
|
|
||||||
Insure
|
|
||||||
</button>
|
|
||||||
'''
|
|
||||||
|
|
||||||
elif blackjack_status == 'push':
|
|
||||||
body += f"<strong class='ml-2'>Pushed. Refunded {wager} {currency_kind}.</strong>"
|
|
||||||
elif blackjack_status == 'bust':
|
|
||||||
body += f"<strong class='ml-2'>Bust. Lost {wager} {currency_kind}.</strong>"
|
|
||||||
elif blackjack_status == 'lost':
|
|
||||||
body += f"<strong class='ml-2'>Lost {wager} {currency_kind}.</strong>"
|
|
||||||
elif blackjack_status == 'won':
|
|
||||||
body += f"<strong class='ml-2'>Won {wager} {currency_kind}.</strong>"
|
|
||||||
elif blackjack_status == 'blackjack':
|
|
||||||
body += f"<strong class='ml-2'>Blackjack! Won {floor(wager * 3/2)} {currency_kind}.</strong>"
|
|
||||||
|
|
||||||
if is_insured == "1":
|
|
||||||
body += f" <em class='text-success'>Insured.</em>"
|
|
||||||
|
|
||||||
body += '</span>'
|
|
||||||
return body
|
|
|
@ -168,9 +168,6 @@ def execute_snappy(post, v):
|
||||||
snappy.coins += 1
|
snappy.coins += 1
|
||||||
g.db.add(snappy)
|
g.db.add(snappy)
|
||||||
|
|
||||||
if body.startswith('!slots'):
|
|
||||||
check_for_slots_command(body, snappy, c)
|
|
||||||
|
|
||||||
if FEATURES['PINS'] and (body.startswith(':#marseypin:') or body.startswith(':#marseypin2:')):
|
if FEATURES['PINS'] and (body.startswith(':#marseypin:') or body.startswith(':#marseypin2:')):
|
||||||
post.stickied = "Snappy"
|
post.stickied = "Snappy"
|
||||||
post.stickied_utc = int(time.time()) + 3600
|
post.stickied_utc = int(time.time()) + 3600
|
||||||
|
|
|
@ -1,23 +1,279 @@
|
||||||
|
import json
|
||||||
from json.encoder import INFINITY
|
from json.encoder import INFINITY
|
||||||
import random
|
import random
|
||||||
from math import floor
|
from math import floor
|
||||||
from files.helpers.const import *
|
from files.helpers.const import *
|
||||||
|
from files.classes.casino_game import Casino_Game
|
||||||
|
from flask import g
|
||||||
|
|
||||||
deck_count = 4
|
deck_count = 4
|
||||||
ranks = ("2", "3", "4", "5", "6", "7", "8", "9", "X", "J", "Q", "K", "A")
|
ranks = ("2", "3", "4", "5", "6", "7", "8", "9", "X", "J", "Q", "K", "A")
|
||||||
suits = ("♠️", "♥️", "♣️", "♦️")
|
suits = ("S", "H", "C", "D")
|
||||||
coins_command_word = "!blackjack"
|
|
||||||
marseybux_command_word = "!blackjackmb"
|
|
||||||
minimum_bet = 100
|
minimum_bet = 100
|
||||||
maximum_bet = INFINITY
|
maximum_bet = INFINITY
|
||||||
|
|
||||||
|
|
||||||
|
def build_game(gambler, currency_kind, wager):
|
||||||
|
casino_game = Casino_Game()
|
||||||
|
casino_game.user_id = gambler.id
|
||||||
|
casino_game.currency = currency_kind
|
||||||
|
casino_game.wager = wager
|
||||||
|
casino_game.winnings = 0
|
||||||
|
casino_game.kind = 'blackjack'
|
||||||
|
casino_game.game_state = json.dumps(build_initial_state())
|
||||||
|
g.db.add(casino_game)
|
||||||
|
g.db.flush()
|
||||||
|
|
||||||
|
|
||||||
|
def build_initial_state():
|
||||||
|
player, dealer, deck = deal_initial_cards()
|
||||||
|
state = {
|
||||||
|
"player": player,
|
||||||
|
"dealer": dealer,
|
||||||
|
"deck": deck,
|
||||||
|
"actions": [],
|
||||||
|
"insurance": False,
|
||||||
|
"doubled_down": False,
|
||||||
|
"status": "active"
|
||||||
|
}
|
||||||
|
|
||||||
|
state['actions'] = determine_actions(state)
|
||||||
|
|
||||||
|
return state
|
||||||
|
|
||||||
|
|
||||||
|
def save_game_state(game, new_state):
|
||||||
|
game.game_state = json.dumps(new_state)
|
||||||
|
g.db.add(game)
|
||||||
|
|
||||||
|
|
||||||
|
def get_active_game(gambler):
|
||||||
|
game = g.db.query(Casino_Game) \
|
||||||
|
.filter(Casino_Game.active == True and
|
||||||
|
Casino_Game.kind == 'blackjack' and
|
||||||
|
Casino_Game.user_id == gambler.id).first()
|
||||||
|
|
||||||
|
if game:
|
||||||
|
return game, json.loads(game.game_state)
|
||||||
|
else:
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
|
||||||
|
def get_safe_game_state(gambler):
|
||||||
|
game, game_state = get_active_game(gambler)
|
||||||
|
|
||||||
|
if game:
|
||||||
|
return {
|
||||||
|
"player": game_state['player'],
|
||||||
|
"dealer": [game_state['dealer'][0], "?"],
|
||||||
|
"actions": game_state['actions'],
|
||||||
|
"insurance": game_state['insurance'],
|
||||||
|
"doubled_down": game_state['doubled_down'],
|
||||||
|
"status": game_state['status']
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def apply_blackjack_result(gambler):
|
||||||
|
game, game_state = get_active_game(gambler)
|
||||||
|
|
||||||
|
if game and game.active:
|
||||||
|
result = game_state['status']
|
||||||
|
|
||||||
|
if result == 'push' or result == 'insured_loss':
|
||||||
|
reward = 0
|
||||||
|
elif result == 'won':
|
||||||
|
reward = game.wager
|
||||||
|
elif result == 'blackjack':
|
||||||
|
reward = floor(game.wager * 3/2)
|
||||||
|
else:
|
||||||
|
reward = -game.wager
|
||||||
|
|
||||||
|
gambler.winnings += reward
|
||||||
|
|
||||||
|
if (reward > -1):
|
||||||
|
currency_value = int(getattr(gambler, game.currency, 0))
|
||||||
|
setattr(gambler, game.currency,
|
||||||
|
currency_value + game.wager + reward)
|
||||||
|
|
||||||
|
game.active = False
|
||||||
|
game.winnings = reward
|
||||||
|
g.db.add(game)
|
||||||
|
|
||||||
|
|
||||||
|
def deal_blackjack_game(gambler, wager_value, currency):
|
||||||
|
over_min = wager_value >= minimum_bet
|
||||||
|
under_max = wager_value <= maximum_bet
|
||||||
|
using_dramacoin = currency == "dramacoin"
|
||||||
|
using_marseybux = not using_dramacoin
|
||||||
|
has_proper_funds = (using_dramacoin and gambler.coins >= wager_value) or (
|
||||||
|
using_marseybux and gambler.procoins >= wager_value)
|
||||||
|
currency_prop = "coins" if using_dramacoin else "procoins"
|
||||||
|
currency_value = getattr(gambler, currency_prop, 0)
|
||||||
|
|
||||||
|
if (over_min and under_max and has_proper_funds):
|
||||||
|
# Charge the gambler for the game, reduce their winnings, and start the game.
|
||||||
|
setattr(gambler, currency_prop, currency_value - wager_value)
|
||||||
|
gambler.winnings -= wager_value
|
||||||
|
|
||||||
|
build_game(gambler, currency_prop, wager_value)
|
||||||
|
|
||||||
|
game, game_state = get_active_game(gambler)
|
||||||
|
player_value = get_hand_value(game_state['player'])
|
||||||
|
dealer_value = get_hand_value(game_state['dealer'])
|
||||||
|
|
||||||
|
if player_value == 21 and dealer_value == 21:
|
||||||
|
game_state["status"] = 'push'
|
||||||
|
save_game_state(game, game_state)
|
||||||
|
apply_blackjack_result(gambler)
|
||||||
|
elif player_value == 21:
|
||||||
|
game_state["status"] = 'blackjack'
|
||||||
|
save_game_state(game, game_state)
|
||||||
|
apply_blackjack_result(gambler)
|
||||||
|
|
||||||
|
g.db.flush()
|
||||||
|
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# region Actions
|
||||||
|
|
||||||
|
|
||||||
|
def gambler_hit(gambler):
|
||||||
|
game, game_state = get_active_game(gambler.id)
|
||||||
|
|
||||||
|
if game:
|
||||||
|
player = game_state['player']
|
||||||
|
deck = game_state['deck']
|
||||||
|
doubled_down = game_state['doubled_down']
|
||||||
|
player.append(deck.pop(0))
|
||||||
|
player_value = get_hand_value(player)
|
||||||
|
went_bust = player_value == -1
|
||||||
|
five_card_charlied = len(player) >= 5
|
||||||
|
|
||||||
|
if went_bust:
|
||||||
|
game_state['status'] = 'bust'
|
||||||
|
save_game_state(game, game_state)
|
||||||
|
apply_blackjack_result(gambler)
|
||||||
|
elif five_card_charlied:
|
||||||
|
game_state['status'] = 'won'
|
||||||
|
save_game_state(game, game_state)
|
||||||
|
apply_blackjack_result(gambler)
|
||||||
|
else:
|
||||||
|
save_game_state(game, game_state)
|
||||||
|
|
||||||
|
if doubled_down or player_value == 21:
|
||||||
|
forced_stay_success, forced_stay_state = gambler_stayed(gambler)
|
||||||
|
return forced_stay_success, forced_stay_state
|
||||||
|
else:
|
||||||
|
return True, game_state
|
||||||
|
else:
|
||||||
|
return False, game_state
|
||||||
|
|
||||||
|
|
||||||
|
def gambler_stayed(gambler):
|
||||||
|
game, game_state = get_active_game(gambler.id)
|
||||||
|
|
||||||
|
if game:
|
||||||
|
player = game_state['player']
|
||||||
|
dealer = game_state['dealer']
|
||||||
|
deck = game_state['deck']
|
||||||
|
insured = game_state['insurance']
|
||||||
|
|
||||||
|
player_value = get_hand_value(player)
|
||||||
|
dealer_value = get_hand_value(dealer)
|
||||||
|
|
||||||
|
if dealer_value == 21 and insured:
|
||||||
|
game_state["status"] = 'insured_loss'
|
||||||
|
save_game_state(game, game_state)
|
||||||
|
apply_blackjack_result(gambler)
|
||||||
|
else:
|
||||||
|
while dealer_value < 17 and dealer_value != -1:
|
||||||
|
next = deck.pop(0)
|
||||||
|
dealer.append(next)
|
||||||
|
dealer_value = get_hand_value(dealer)
|
||||||
|
|
||||||
|
if player_value > dealer_value or dealer_value == -1:
|
||||||
|
game_state["status"] = 'won'
|
||||||
|
elif dealer_value > player_value:
|
||||||
|
game_state["status"] = 'lost'
|
||||||
|
else:
|
||||||
|
game_state["status"] = 'push'
|
||||||
|
|
||||||
|
save_game_state(game, game_state)
|
||||||
|
apply_blackjack_result(gambler)
|
||||||
|
|
||||||
|
return True, game_state
|
||||||
|
else:
|
||||||
|
return False, game_state
|
||||||
|
|
||||||
|
|
||||||
|
def gambler_doubled_down(gambler):
|
||||||
|
game, game_state = get_active_game(gambler.id)
|
||||||
|
|
||||||
|
if game and not game_state['doubled_down']:
|
||||||
|
currency_value = getattr(gambler, game.currency, 0)
|
||||||
|
|
||||||
|
if (currency_value < game.wager):
|
||||||
|
return False
|
||||||
|
|
||||||
|
setattr(gambler, game.currency, currency_value - game.wager)
|
||||||
|
game.wager *= 2
|
||||||
|
game_state['doubled_down'] = True
|
||||||
|
save_game_state(game, game_state)
|
||||||
|
|
||||||
|
g.db.flush()
|
||||||
|
|
||||||
|
last_hit_success, last_hit_state = gambler_hit(gambler)
|
||||||
|
|
||||||
|
return last_hit_success, last_hit_state
|
||||||
|
else:
|
||||||
|
return False, game_state
|
||||||
|
|
||||||
|
|
||||||
|
def gambler_purchased_insurance(gambler):
|
||||||
|
game, game_state = get_active_game(gambler.id)
|
||||||
|
|
||||||
|
if game and not game_state['insurance']:
|
||||||
|
insurance_cost = game.wager / 2
|
||||||
|
currency_value = getattr(gambler, game.currency, 0)
|
||||||
|
|
||||||
|
if (currency_value < insurance_cost):
|
||||||
|
return False, game_state
|
||||||
|
|
||||||
|
setattr(gambler, game.currency, currency_value - insurance_cost)
|
||||||
|
game_state['insurance'] = True
|
||||||
|
game_state['actions'] = determine_actions(game_state)
|
||||||
|
save_game_state(game, game_state)
|
||||||
|
|
||||||
|
return True, game_state
|
||||||
|
else:
|
||||||
|
return False, game_state
|
||||||
|
|
||||||
|
# endregion
|
||||||
|
|
||||||
|
# region Utilities
|
||||||
|
|
||||||
|
|
||||||
def shuffle(x):
|
def shuffle(x):
|
||||||
random.shuffle(x)
|
random.shuffle(x)
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
||||||
|
def determine_actions(state):
|
||||||
|
actions = ['hit', 'stay', 'double_down']
|
||||||
|
|
||||||
|
if (state['dealer'][0][0] == "A" and not state['insurance']):
|
||||||
|
actions.append('insure')
|
||||||
|
|
||||||
|
return actions
|
||||||
|
|
||||||
|
|
||||||
def deal_initial_cards():
|
def deal_initial_cards():
|
||||||
deck = shuffle([rank + suit for rank in ranks for suit in suits for _ in range(deck_count)])
|
deck = shuffle(
|
||||||
|
[rank + suit for rank in ranks for suit in suits for _ in range(deck_count)])
|
||||||
p1, d1, p2, d2, *rest_of_deck = deck
|
p1, d1, p2, d2, *rest_of_deck = deck
|
||||||
return [p1, p2], [d1, d2], rest_of_deck
|
return [p1, p2], [d1, d2], rest_of_deck
|
||||||
|
|
||||||
|
@ -38,151 +294,4 @@ def get_hand_value(hand):
|
||||||
|
|
||||||
return max(possibilities)
|
return max(possibilities)
|
||||||
|
|
||||||
|
# endregion
|
||||||
def format_cards(hand):
|
|
||||||
return map(lambda x: "".join(x), hand)
|
|
||||||
|
|
||||||
|
|
||||||
def format_all(player_hand, dealer_hand, deck, status, wager, kind, is_insured=0):
|
|
||||||
formatted_player_hand = format_cards(player_hand)
|
|
||||||
formatted_dealer_hand = format_cards(dealer_hand)
|
|
||||||
formatted_deck = format_cards(deck)
|
|
||||||
|
|
||||||
return f'{"/".join(formatted_player_hand)}_{"/".join(formatted_dealer_hand)}_{"/".join(formatted_deck)}_{status}_{wager}_{kind}_{str(is_insured)}'
|
|
||||||
|
|
||||||
|
|
||||||
def check_for_blackjack_commands(in_text, from_user, from_comment):
|
|
||||||
if not FEATURES['GAMBLING']: return
|
|
||||||
|
|
||||||
for command_word in (coins_command_word, marseybux_command_word):
|
|
||||||
currency_prop = "coins" if command_word == coins_command_word else "procoins"
|
|
||||||
currency_value = getattr(from_user, currency_prop, 0)
|
|
||||||
|
|
||||||
if command_word in in_text:
|
|
||||||
for word in in_text.split():
|
|
||||||
if command_word in word:
|
|
||||||
try:
|
|
||||||
wager = word[len(command_word):]
|
|
||||||
wager_value = int(wager)
|
|
||||||
except: break
|
|
||||||
|
|
||||||
if (wager_value < minimum_bet): break
|
|
||||||
elif (wager_value > maximum_bet): break
|
|
||||||
elif (wager_value <= currency_value):
|
|
||||||
setattr(from_user, currency_prop, currency_value - wager_value)
|
|
||||||
|
|
||||||
player_hand, dealer_hand, rest_of_deck = deal_initial_cards()
|
|
||||||
status = 'active'
|
|
||||||
player_value = get_hand_value(player_hand)
|
|
||||||
dealer_value = get_hand_value(dealer_hand)
|
|
||||||
|
|
||||||
if player_value == 21 and dealer_value == 21:
|
|
||||||
status = 'push'
|
|
||||||
apply_game_result(from_comment, wager, status, currency_prop)
|
|
||||||
elif player_value == 21:
|
|
||||||
status = 'blackjack'
|
|
||||||
apply_game_result(from_comment, wager, status, currency_prop)
|
|
||||||
|
|
||||||
from_comment.blackjack_result = format_all(player_hand, dealer_hand, rest_of_deck, status, wager, currency_prop, 0)
|
|
||||||
|
|
||||||
def player_hit(from_comment, did_double_down=False):
|
|
||||||
player_hand, dealer_hand, deck, status, wager, kind, is_insured = from_comment.blackjack_result.split("_")
|
|
||||||
player_hand = player_hand.split("/")
|
|
||||||
dealer_hand = dealer_hand.split("/")
|
|
||||||
deck = deck.split("/")
|
|
||||||
player_hand.append(deck.pop(0))
|
|
||||||
player_value = get_hand_value(player_hand)
|
|
||||||
|
|
||||||
if player_value == -1:
|
|
||||||
status = 'bust'
|
|
||||||
apply_game_result(from_comment, wager, status, kind)
|
|
||||||
elif len(player_hand) >= 5:
|
|
||||||
status = 'won'
|
|
||||||
apply_game_result(from_comment, wager, status, kind)
|
|
||||||
|
|
||||||
from_comment.blackjack_result = format_all(player_hand, dealer_hand, deck, status, wager, kind, int(is_insured))
|
|
||||||
|
|
||||||
if (did_double_down or player_value == 21) and status == 'active':
|
|
||||||
player_stayed(from_comment)
|
|
||||||
|
|
||||||
def player_stayed(from_comment):
|
|
||||||
player_hand, dealer_hand, deck, status, wager, kind, is_insured = from_comment.blackjack_result.split("_")
|
|
||||||
player_hand = player_hand.split("/")
|
|
||||||
player_value = get_hand_value(player_hand)
|
|
||||||
dealer_hand = dealer_hand.split("/")
|
|
||||||
dealer_value = get_hand_value(dealer_hand)
|
|
||||||
deck = deck.split("/")
|
|
||||||
|
|
||||||
if dealer_value == 21 and is_insured == "1":
|
|
||||||
currency_value = getattr(from_comment.author, kind, 0)
|
|
||||||
setattr(from_comment.author, kind, currency_value + int(wager))
|
|
||||||
else:
|
|
||||||
while dealer_value < 17 and dealer_value != -1:
|
|
||||||
next = deck.pop(0)
|
|
||||||
dealer_hand.append(next)
|
|
||||||
dealer_value = get_hand_value(dealer_hand)
|
|
||||||
|
|
||||||
if player_value > dealer_value or dealer_value == -1: status = 'won'
|
|
||||||
elif dealer_value > player_value: status = 'lost'
|
|
||||||
else: status = 'push'
|
|
||||||
|
|
||||||
from_comment.blackjack_result = format_all(player_hand, dealer_hand, deck, status, wager, kind, int(is_insured))
|
|
||||||
|
|
||||||
apply_game_result(from_comment, wager, status, kind)
|
|
||||||
|
|
||||||
def player_doubled_down(from_comment):
|
|
||||||
# When doubling down, the player receives one additional card (a "hit") and their initial bet is doubled.
|
|
||||||
player_hand, dealer_hand, deck, status, wager, kind, is_insured = from_comment.blackjack_result.split("_")
|
|
||||||
wager_value = int(wager)
|
|
||||||
currency_value = getattr(from_comment.author, kind, 0)
|
|
||||||
|
|
||||||
# Gotsta have enough coins
|
|
||||||
if (currency_value < wager_value): return
|
|
||||||
|
|
||||||
# Double the initial wager
|
|
||||||
setattr(from_comment.author, kind, currency_value - wager_value)
|
|
||||||
wager_value *= 2
|
|
||||||
|
|
||||||
# Apply the changes to the stored hand.
|
|
||||||
player_hand = player_hand.split("/")
|
|
||||||
dealer_hand = dealer_hand.split("/")
|
|
||||||
deck = deck.split("/")
|
|
||||||
from_comment.blackjack_result = format_all(player_hand, dealer_hand, deck, status, str(wager_value), kind, int(is_insured))
|
|
||||||
|
|
||||||
player_hit(from_comment, True)
|
|
||||||
|
|
||||||
def player_bought_insurance(from_comment):
|
|
||||||
# When buying insurance, the player pays a side bet equal to 1/2 the original bet.
|
|
||||||
# In the event the dealer actually had a blackjack, they receive a 2:1 payout limiting the negative effect.
|
|
||||||
player_hand, dealer_hand, deck, status, wager, kind, is_insured = from_comment.blackjack_result.split("_")
|
|
||||||
wager_value = int(wager)
|
|
||||||
insurance_cost = wager_value / 2
|
|
||||||
currency_value = getattr(from_comment.author, kind, 0)
|
|
||||||
|
|
||||||
# Gotsta have enough coins
|
|
||||||
if (currency_value < insurance_cost): return
|
|
||||||
|
|
||||||
# Charge for (and grant) insurance
|
|
||||||
setattr(from_comment.author, kind, currency_value - insurance_cost)
|
|
||||||
is_insured = 1
|
|
||||||
|
|
||||||
# Apply the changes to the stored hand.
|
|
||||||
player_hand = player_hand.split("/")
|
|
||||||
dealer_hand = dealer_hand.split("/")
|
|
||||||
deck = deck.split("/")
|
|
||||||
from_comment.blackjack_result = format_all(player_hand, dealer_hand, deck, status, str(wager_value), kind, int(is_insured))
|
|
||||||
|
|
||||||
def apply_game_result(from_comment, wager, result, kind):
|
|
||||||
wager_value = int(wager)
|
|
||||||
user = from_comment.author
|
|
||||||
|
|
||||||
if result == 'push': reward = 0
|
|
||||||
elif result == 'won': reward = wager_value
|
|
||||||
elif result == 'blackjack': reward = floor(wager_value * 3/2)
|
|
||||||
else: reward = -wager_value
|
|
||||||
|
|
||||||
user.winnings += reward
|
|
||||||
|
|
||||||
if (reward > -1):
|
|
||||||
currency_value = int(getattr(user, kind, 0))
|
|
||||||
setattr(user, kind, currency_value + wager_value + reward)
|
|
||||||
|
|
|
@ -206,7 +206,7 @@ POLL_THREAD = 0
|
||||||
WELCOME_MSG = f"Welcome to {SITE_NAME}!"
|
WELCOME_MSG = f"Welcome to {SITE_NAME}!"
|
||||||
ROLES={}
|
ROLES={}
|
||||||
|
|
||||||
LOTTERY_ENABLED = True
|
CASINO_ENABLED = True
|
||||||
LOTTERY_TICKET_COST = 12
|
LOTTERY_TICKET_COST = 12
|
||||||
LOTTERY_SINK_RATE = 3
|
LOTTERY_SINK_RATE = 3
|
||||||
LOTTERY_DURATION = 60 * 60 * 24 * 7
|
LOTTERY_DURATION = 60 * 60 * 24 * 7
|
||||||
|
|
|
@ -55,7 +55,7 @@ def inject_constants():
|
||||||
"PIZZASHILL_ID":PIZZASHILL_ID, "DEFAULT_COLOR":DEFAULT_COLOR,
|
"PIZZASHILL_ID":PIZZASHILL_ID, "DEFAULT_COLOR":DEFAULT_COLOR,
|
||||||
"COLORS":COLORS, "time":time, "PERMS":PERMS, "FEATURES":FEATURES,
|
"COLORS":COLORS, "time":time, "PERMS":PERMS, "FEATURES":FEATURES,
|
||||||
"HOLE_NAME":HOLE_NAME, "HOLE_STYLE_FLAIR":HOLE_STYLE_FLAIR, "HOLE_REQUIRED":HOLE_REQUIRED,
|
"HOLE_NAME":HOLE_NAME, "HOLE_STYLE_FLAIR":HOLE_STYLE_FLAIR, "HOLE_REQUIRED":HOLE_REQUIRED,
|
||||||
"LOTTERY_ENABLED":LOTTERY_ENABLED, "GUMROAD_LINK":GUMROAD_LINK,
|
"CASINO_ENABLED":CASINO_ENABLED, "GUMROAD_LINK":GUMROAD_LINK,
|
||||||
"DEFAULT_THEME":DEFAULT_THEME, "DESCRIPTION":DESCRIPTION,
|
"DEFAULT_THEME":DEFAULT_THEME, "DESCRIPTION":DESCRIPTION,
|
||||||
"has_sidebar":has_sidebar, "has_logo":has_logo, "has_app":has_app,
|
"has_sidebar":has_sidebar, "has_logo":has_logo, "has_app":has_app,
|
||||||
"FP":FP, "NOTIF_MODACTION_JL_MIN":NOTIF_MODACTION_JL_MIN, "cache":cache, "ONLINE_STR":ONLINE_STR, "patron":patron, "approved_embed_hosts":approved_embed_hosts, "dues":dues}
|
"FP":FP, "NOTIF_MODACTION_JL_MIN":NOTIF_MODACTION_JL_MIN, "cache":cache, "ONLINE_STR":ONLINE_STR, "patron":patron, "approved_embed_hosts":approved_embed_hosts, "dues":dues}
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
|
import json
|
||||||
from json.encoder import INFINITY
|
from json.encoder import INFINITY
|
||||||
import random
|
import random
|
||||||
from .const import *
|
from .const import *
|
||||||
|
from files.classes.casino_game import Casino_Game
|
||||||
|
from flask import g
|
||||||
|
|
||||||
command_word = "!slots"
|
if SITE_NAME == 'rDrama':
|
||||||
casino_word = "!slotsmb"
|
minimum_bet = 100
|
||||||
if SITE_NAME == 'rDrama': minimum_bet = 100
|
else:
|
||||||
else: minimum_bet = 10
|
minimum_bet = 10
|
||||||
maximum_bet = INFINITY
|
maximum_bet = INFINITY
|
||||||
payout_to_symbols = {
|
payout_to_symbols = {
|
||||||
2: ["👣", "🍀", "🌈", "⭐️"],
|
2: ["👣", "🍀", "🌈", "⭐️"],
|
||||||
|
@ -14,74 +17,50 @@ payout_to_symbols = {
|
||||||
12: ["🐱"]
|
12: ["🐱"]
|
||||||
}
|
}
|
||||||
|
|
||||||
def shuffle(stuff):
|
|
||||||
random.shuffle(stuff)
|
|
||||||
return stuff
|
|
||||||
|
|
||||||
def check_for_slots_command(in_text, from_user, from_comment):
|
def casino_slot_pull(gambler, wager_value, currency):
|
||||||
if not FEATURES['GAMBLING']: return
|
over_min = wager_value >= minimum_bet
|
||||||
|
under_max = wager_value <= maximum_bet
|
||||||
|
using_dramacoin = currency == "dramacoin"
|
||||||
|
using_marseybux = not using_dramacoin
|
||||||
|
has_proper_funds = (using_dramacoin and gambler.coins >= wager_value) or (
|
||||||
|
using_marseybux and gambler.procoins >= wager_value)
|
||||||
|
currency_prop = "coins" if using_dramacoin else "procoins"
|
||||||
|
currency_value = getattr(gambler, currency_prop, 0)
|
||||||
|
|
||||||
in_text = in_text.lower()
|
if (over_min and under_max and has_proper_funds):
|
||||||
if command_word in in_text:
|
setattr(gambler, currency_prop, currency_value - wager_value)
|
||||||
for word in in_text.split():
|
gambler.winnings -= wager_value
|
||||||
if command_word in word:
|
|
||||||
try:
|
|
||||||
wager = word[len(command_word):]
|
|
||||||
wager_value = int(wager)
|
|
||||||
except: break
|
|
||||||
|
|
||||||
if (wager_value < minimum_bet): break
|
|
||||||
elif (wager_value > maximum_bet): break
|
|
||||||
elif (wager_value > from_user.coins): break
|
|
||||||
|
|
||||||
from_user.coins -= wager_value
|
|
||||||
from_user.winnings -= wager_value
|
|
||||||
|
|
||||||
payout = determine_payout()
|
payout = determine_payout()
|
||||||
symbols = build_symbols(payout)
|
|
||||||
text = build_text(wager_value, payout, from_user, "Coins")
|
|
||||||
reward = wager_value * payout
|
reward = wager_value * payout
|
||||||
|
|
||||||
from_user.coins += reward
|
currency_value = getattr(gambler, currency_prop, 0)
|
||||||
from_user.winnings += reward
|
setattr(gambler, currency_prop, currency_value + reward)
|
||||||
|
gambler.winnings += reward
|
||||||
|
|
||||||
from_comment.slots_result = f'{symbols} {text}'
|
|
||||||
|
|
||||||
if casino_word in in_text:
|
|
||||||
for word in in_text.split():
|
|
||||||
if casino_word in word:
|
|
||||||
try:
|
|
||||||
wager = word[len(casino_word):]
|
|
||||||
wager_value = int(wager)
|
|
||||||
except: break
|
|
||||||
|
|
||||||
if (wager_value < minimum_bet): break
|
|
||||||
elif (wager_value > maximum_bet): break
|
|
||||||
elif (wager_value > from_user.procoins): break
|
|
||||||
|
|
||||||
from_user.procoins -= wager_value
|
|
||||||
from_user.winnings -= wager_value
|
|
||||||
|
|
||||||
payout = determine_payout()
|
|
||||||
symbols = build_symbols(payout)
|
symbols = build_symbols(payout)
|
||||||
text = build_text(wager_value, payout, from_user, "Marseybux")
|
text = build_text(wager_value, payout, currency)
|
||||||
reward = wager_value * payout
|
|
||||||
|
|
||||||
from_user.procoins += reward
|
game_state = {
|
||||||
from_user.winnings += reward
|
"symbols": symbols,
|
||||||
|
"text": text
|
||||||
|
}
|
||||||
|
casino_game = Casino_Game()
|
||||||
|
casino_game.active = False
|
||||||
|
casino_game.user_id = gambler.id
|
||||||
|
casino_game.currency = currency_prop
|
||||||
|
casino_game.wager = wager_value
|
||||||
|
casino_game.winnings = reward - wager_value
|
||||||
|
casino_game.kind = 'slots'
|
||||||
|
casino_game.game_state = json.dumps(game_state)
|
||||||
|
g.db.add(casino_game)
|
||||||
|
|
||||||
from_comment.slots_result = f'{symbols} {text}'
|
return True, casino_game.game_state
|
||||||
|
else:
|
||||||
|
return False, "{}"
|
||||||
|
|
||||||
|
|
||||||
def determine_payout():
|
|
||||||
value = random.randint(1, 100)
|
|
||||||
if value == 100: return 12
|
|
||||||
elif value >= 96: return 5
|
|
||||||
elif value >= 88: return 3
|
|
||||||
elif value >= 72: return 2
|
|
||||||
elif value >= 61: return 1
|
|
||||||
else: return 0
|
|
||||||
|
|
||||||
def build_symbols(for_payout):
|
def build_symbols(for_payout):
|
||||||
all_symbols = []
|
all_symbols = []
|
||||||
|
|
||||||
|
@ -92,7 +71,7 @@ def build_symbols(for_payout):
|
||||||
shuffle(all_symbols)
|
shuffle(all_symbols)
|
||||||
|
|
||||||
if for_payout == 0:
|
if for_payout == 0:
|
||||||
return "".join([all_symbols[0], all_symbols[1], all_symbols[2]])
|
return "".join([all_symbols[0], ",", all_symbols[1], ",", all_symbols[2]])
|
||||||
elif for_payout == 1:
|
elif for_payout == 1:
|
||||||
indices = shuffle([0, 1, 2])
|
indices = shuffle([0, 1, 2])
|
||||||
symbol_set = ["", "", ""]
|
symbol_set = ["", "", ""]
|
||||||
|
@ -105,15 +84,41 @@ def build_symbols(for_payout):
|
||||||
symbol_set[match_b] = matching_symbol
|
symbol_set[match_b] = matching_symbol
|
||||||
symbol_set[nonmatch] = other_symbol
|
symbol_set[nonmatch] = other_symbol
|
||||||
|
|
||||||
return "".join(symbol_set)
|
return "".join([symbol_set[0], ",", symbol_set[1], ",", symbol_set[2]])
|
||||||
else:
|
else:
|
||||||
relevantSymbols = shuffle(payout_to_symbols[for_payout])
|
relevantSymbols = shuffle(payout_to_symbols[for_payout])
|
||||||
symbol = relevantSymbols[0]
|
symbol = relevantSymbols[0]
|
||||||
|
|
||||||
return "".join([symbol, symbol, symbol])
|
return "".join([symbol, ",", symbol, ",", symbol])
|
||||||
|
|
||||||
def build_text(wager_value, result, user, currency):
|
|
||||||
if result == 0: return f'Lost {wager_value} {currency}'
|
def build_text(wager_value, result, currency):
|
||||||
elif result == 1: return 'Broke Even'
|
if result == 0:
|
||||||
elif result == 12: return f'Jackpot! Won {wager_value * (result-1)} {currency}'
|
return f'Lost {wager_value} {currency}'
|
||||||
else: return f'Won {wager_value * (result-1)} {currency}'
|
elif result == 1:
|
||||||
|
return 'Broke Even'
|
||||||
|
elif result == 12:
|
||||||
|
return f'Jackpot! Won {wager_value * (result-1)} {currency}'
|
||||||
|
else:
|
||||||
|
return f'Won {wager_value * (result-1)} {currency}'
|
||||||
|
|
||||||
|
|
||||||
|
def determine_payout():
|
||||||
|
value = random.randint(1, 100)
|
||||||
|
if value == 100:
|
||||||
|
return 12
|
||||||
|
elif value >= 96:
|
||||||
|
return 5
|
||||||
|
elif value >= 88:
|
||||||
|
return 3
|
||||||
|
elif value >= 72:
|
||||||
|
return 2
|
||||||
|
elif value >= 61:
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def shuffle(stuff):
|
||||||
|
random.shuffle(stuff)
|
||||||
|
return stuff
|
||||||
|
|
|
@ -14,7 +14,7 @@ def check_for_treasure(in_text, from_comment):
|
||||||
|
|
||||||
if not FEATURES['GAMBLING']: return
|
if not FEATURES['GAMBLING']: return
|
||||||
|
|
||||||
if '!slots' not in in_text and '!blackjack' not in in_text and '!wordle' not in in_text:
|
if '!wordle' not in in_text:
|
||||||
seed = randint(1, 1000)
|
seed = randint(1, 1000)
|
||||||
is_special = seed == 1000
|
is_special = seed == 1000
|
||||||
is_standard = seed >= 990
|
is_standard = seed >= 990
|
||||||
|
|
|
@ -166,11 +166,11 @@ def admin_level_required(x):
|
||||||
|
|
||||||
return wrapper_maker
|
return wrapper_maker
|
||||||
|
|
||||||
def lottery_required(f):
|
def casino_required(f):
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
v = get_logged_in_user()
|
v = get_logged_in_user()
|
||||||
|
|
||||||
if not LOTTERY_ENABLED: abort(404)
|
if not CASINO_ENABLED: abort(404)
|
||||||
|
|
||||||
return make_response(f(v=v))
|
return make_response(f(v=v))
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ from .awards import *
|
||||||
from .giphy import *
|
from .giphy import *
|
||||||
from .subs import *
|
from .subs import *
|
||||||
from .lottery import *
|
from .lottery import *
|
||||||
|
from .casino import *
|
||||||
from .polls import *
|
from .polls import *
|
||||||
from .notifications import *
|
from .notifications import *
|
||||||
from .hats import *
|
from .hats import *
|
|
@ -0,0 +1,118 @@
|
||||||
|
import json
|
||||||
|
from files.__main__ import app
|
||||||
|
from files.helpers.wrappers import *
|
||||||
|
from files.helpers.alerts import *
|
||||||
|
from files.helpers.get import *
|
||||||
|
from files.helpers.const import *
|
||||||
|
from files.helpers.wrappers import *
|
||||||
|
from files.helpers.blackjack import *
|
||||||
|
from files.helpers.slots import *
|
||||||
|
from files.helpers.lottery import *
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/casino")
|
||||||
|
@auth_required
|
||||||
|
def casino(v):
|
||||||
|
participants = get_users_participating_in_lottery()
|
||||||
|
return render_template("casino.html", v=v, participants=participants)
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/casino/slots")
|
||||||
|
@auth_required
|
||||||
|
def pull_slots(v):
|
||||||
|
try:
|
||||||
|
wager = int(request.values.get("wager"))
|
||||||
|
except:
|
||||||
|
return {"error": "Invalid wager."}
|
||||||
|
|
||||||
|
try:
|
||||||
|
currency = request.values.get("currency")
|
||||||
|
except:
|
||||||
|
return {"error": "Invalid currency (expected 'dramacoin' or 'marseybux')."}
|
||||||
|
|
||||||
|
if (currency == "dramacoin" and wager > v.coins) or (currency == "marseybux" and wager > v.procoins):
|
||||||
|
return {"error": f"Not enough {currency} to make that bet."}
|
||||||
|
|
||||||
|
success, game_state = casino_slot_pull(v, wager, currency)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
return {"game_state": game_state, "gambler": { "coins": v.coins, "procoins": v.procoins }}
|
||||||
|
else:
|
||||||
|
return {"error": "Wager must be more than 100 {currency}."}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/casino/blackjack")
|
||||||
|
@auth_required
|
||||||
|
def get_player_blackjack_status(v):
|
||||||
|
game, game_state = get_active_game(v)
|
||||||
|
|
||||||
|
if game and game.active:
|
||||||
|
safe_state = get_safe_game_state(v)
|
||||||
|
return {"active": True, "game_state": safe_state}
|
||||||
|
else:
|
||||||
|
return {"active": False, "game_state": game_state}
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/casino/blackjack")
|
||||||
|
@auth_required
|
||||||
|
def deal_blackjack(v):
|
||||||
|
try:
|
||||||
|
wager = int(request.values.get("wager"))
|
||||||
|
except:
|
||||||
|
return {"error": "Invalid wager."}
|
||||||
|
|
||||||
|
try:
|
||||||
|
currency = request.values.get("currency")
|
||||||
|
except:
|
||||||
|
return {"error": "Invalid currency (expected 'dramacoin' or 'marseybux')."}
|
||||||
|
|
||||||
|
if (currency == "dramacoin" and wager > v.coins) or (currency == "marseybux" and wager > v.procoins):
|
||||||
|
return {"error": f"Not enough {currency} to make that bet."}
|
||||||
|
|
||||||
|
success = deal_blackjack_game(v, wager, currency)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
game, game_state = get_active_game(v)
|
||||||
|
|
||||||
|
if game and game.active:
|
||||||
|
safe_state = get_safe_game_state(v)
|
||||||
|
return {"game_state": safe_state, "gambler": { "coins": v.coins, "procoins": v.procoins }}
|
||||||
|
else:
|
||||||
|
return {"game_state": game_state, "gambler": { "coins": v.coins, "procoins": v.procoins }}
|
||||||
|
|
||||||
|
else:
|
||||||
|
return {"error": "Wager must be more than 100 {currency}."}
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/casino/blackjack/action")
|
||||||
|
@auth_required
|
||||||
|
def player_took_blackjack_action(v):
|
||||||
|
try:
|
||||||
|
action = request.values.get("action")
|
||||||
|
except:
|
||||||
|
return {"error": "Invalid action."}
|
||||||
|
|
||||||
|
was_successful = False
|
||||||
|
state = None
|
||||||
|
|
||||||
|
if action == 'hit':
|
||||||
|
success, game_state = gambler_hit(v)
|
||||||
|
was_successful = success
|
||||||
|
state = game_state
|
||||||
|
elif action == 'stay':
|
||||||
|
success, game_state = gambler_stayed(v)
|
||||||
|
was_successful = success
|
||||||
|
state = game_state
|
||||||
|
elif action == 'double_down':
|
||||||
|
success, game_state = gambler_doubled_down(v)
|
||||||
|
was_successful = success
|
||||||
|
state = game_state
|
||||||
|
elif action == 'insure':
|
||||||
|
success, game_state = gambler_purchased_insurance(v)
|
||||||
|
was_successful = success
|
||||||
|
state = game_state
|
||||||
|
|
||||||
|
if was_successful:
|
||||||
|
return {"active": True, "game_state": state, "gambler": { "coins": v.coins, "procoins": v.procoins }}
|
||||||
|
else:
|
||||||
|
return {"active": False, "game_state": None}
|
|
@ -338,7 +338,7 @@ def comment(v):
|
||||||
body_html = sanitize(body_for_sanitize, limit_pings=5)
|
body_html = sanitize(body_for_sanitize, limit_pings=5)
|
||||||
|
|
||||||
|
|
||||||
if parent_post.id not in ADMIGGERS and '!slots' not in body.lower() and '!blackjack' not in body.lower() and '!wordle' not in body.lower() and AGENDAPOSTER_PHRASE not in body.lower():
|
if parent_post.id not in ADMIGGERS and '!wordle' not in body.lower() and AGENDAPOSTER_PHRASE not in body.lower():
|
||||||
existing = g.db.query(Comment.id).filter(Comment.author_id == v.id,
|
existing = g.db.query(Comment.id).filter(Comment.author_id == v.id,
|
||||||
Comment.deleted_utc == 0,
|
Comment.deleted_utc == 0,
|
||||||
Comment.parent_comment_id == parent_comment_id,
|
Comment.parent_comment_id == parent_comment_id,
|
||||||
|
@ -655,12 +655,7 @@ def comment(v):
|
||||||
c.upvotes += 3
|
c.upvotes += 3
|
||||||
g.db.add(c)
|
g.db.add(c)
|
||||||
|
|
||||||
if not v.rehab:
|
if v.marseyawarded and parent_post.id not in ADMIGGERS and marseyaward_body_regex.search(body_html):
|
||||||
check_for_slots_command(body, v, c)
|
|
||||||
|
|
||||||
check_for_blackjack_commands(body, v, c)
|
|
||||||
|
|
||||||
if not c.slots_result and not c.blackjack_result and v.marseyawarded and parent_post.id not in ADMIGGERS and marseyaward_body_regex.search(body_html):
|
|
||||||
return {"error":"You can only type marseys!"}, 403
|
return {"error":"You can only type marseys!"}, 403
|
||||||
|
|
||||||
check_for_treasure(body, c)
|
check_for_treasure(body, c)
|
||||||
|
@ -669,7 +664,7 @@ def comment(v):
|
||||||
answer = random.choice(WORDLE_LIST)
|
answer = random.choice(WORDLE_LIST)
|
||||||
c.wordle_result = f'_active_{answer}'
|
c.wordle_result = f'_active_{answer}'
|
||||||
|
|
||||||
if not c.slots_result and not c.blackjack_result and not c.wordle_result and not rts:
|
if not c.wordle_result and not rts:
|
||||||
parent_post.comment_count += 1
|
parent_post.comment_count += 1
|
||||||
g.db.add(parent_post)
|
g.db.add(parent_post)
|
||||||
|
|
||||||
|
@ -980,29 +975,6 @@ def unsave_comment(cid, v):
|
||||||
|
|
||||||
return {"message": "Comment unsaved!"}
|
return {"message": "Comment unsaved!"}
|
||||||
|
|
||||||
@app.post("/blackjack/<cid>")
|
|
||||||
@limiter.limit("1/second;30/minute;200/hour;2500/day")
|
|
||||||
@limiter.limit("1/second;30/minute;200/hour;2500/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}')
|
|
||||||
@auth_required
|
|
||||||
def handle_blackjack_action(cid, v):
|
|
||||||
comment = get_comment(cid)
|
|
||||||
|
|
||||||
if v.id != comment.author_id:
|
|
||||||
abort(403)
|
|
||||||
|
|
||||||
if 'active' in comment.blackjack_result:
|
|
||||||
try: action = request.values.get("thing").strip().lower()
|
|
||||||
except: abort(400)
|
|
||||||
|
|
||||||
if action == 'hit': player_hit(comment)
|
|
||||||
elif action == 'stay': player_stayed(comment)
|
|
||||||
elif action == 'doubledown': player_doubled_down(comment)
|
|
||||||
elif action == 'insurance': player_bought_insurance(comment)
|
|
||||||
|
|
||||||
g.db.add(comment)
|
|
||||||
g.db.add(v)
|
|
||||||
return {"response" : comment.blackjack_html(v)}
|
|
||||||
|
|
||||||
|
|
||||||
def diff_words(answer, guess):
|
def diff_words(answer, guess):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -9,7 +9,7 @@ import requests
|
||||||
|
|
||||||
@app.post("/lottery/end")
|
@app.post("/lottery/end")
|
||||||
@admin_level_required(3)
|
@admin_level_required(3)
|
||||||
@lottery_required
|
@casino_required
|
||||||
def lottery_end(v):
|
def lottery_end(v):
|
||||||
success, message = end_lottery_session()
|
success, message = end_lottery_session()
|
||||||
return {"message": message} if success else {"error": message}
|
return {"message": message} if success else {"error": message}
|
||||||
|
@ -17,7 +17,7 @@ def lottery_end(v):
|
||||||
|
|
||||||
@app.post("/lottery/start")
|
@app.post("/lottery/start")
|
||||||
@admin_level_required(3)
|
@admin_level_required(3)
|
||||||
@lottery_required
|
@casino_required
|
||||||
def lottery_start(v):
|
def lottery_start(v):
|
||||||
start_new_lottery_session()
|
start_new_lottery_session()
|
||||||
return {"message": "Lottery started."}
|
return {"message": "Lottery started."}
|
||||||
|
@ -26,7 +26,7 @@ def lottery_start(v):
|
||||||
@app.post("/lottery/buy")
|
@app.post("/lottery/buy")
|
||||||
@limiter.limit("3/second;100/minute;500/hour;1000/day")
|
@limiter.limit("3/second;100/minute;500/hour;1000/day")
|
||||||
@auth_required
|
@auth_required
|
||||||
@lottery_required
|
@casino_required
|
||||||
def lottery_buy(v):
|
def lottery_buy(v):
|
||||||
try: quantity = int(request.values.get("quantity"))
|
try: quantity = int(request.values.get("quantity"))
|
||||||
except: return {"error": "Invalid ticket quantity."}
|
except: return {"error": "Invalid ticket quantity."}
|
||||||
|
@ -44,22 +44,15 @@ def lottery_buy(v):
|
||||||
@app.get("/lottery/active")
|
@app.get("/lottery/active")
|
||||||
@limiter.limit("3/second;100/minute;500/hour;1000/day")
|
@limiter.limit("3/second;100/minute;500/hour;1000/day")
|
||||||
@auth_required
|
@auth_required
|
||||||
@lottery_required
|
@casino_required
|
||||||
def lottery_active(v):
|
def lottery_active(v):
|
||||||
lottery, participants = get_active_lottery_stats()
|
lottery, participants = get_active_lottery_stats()
|
||||||
|
|
||||||
return {"message": "", "stats": {"user": v.lottery_stats, "lottery": lottery, "participants": participants}}
|
return {"message": "", "stats": {"user": v.lottery_stats, "lottery": lottery, "participants": participants}}
|
||||||
|
|
||||||
@app.get("/lottery")
|
|
||||||
@auth_required
|
|
||||||
@lottery_required
|
|
||||||
def lottery(v):
|
|
||||||
lottery_stats, participant_stats = get_active_lottery_stats()
|
|
||||||
return render_template("lottery.html", v=v, lottery_stats=lottery_stats, participant_stats=participant_stats)
|
|
||||||
|
|
||||||
@app.get("/admin/lottery/participants")
|
@app.get("/admin/lottery/participants")
|
||||||
@admin_level_required(2)
|
@admin_level_required(2)
|
||||||
@lottery_required
|
@casino_required
|
||||||
def lottery_admin(v):
|
def lottery_admin(v):
|
||||||
participants = get_users_participating_in_lottery()
|
participants = get_users_participating_in_lottery()
|
||||||
return render_template("admin/lottery.html", v=v, participants=participants)
|
return render_template("admin/lottery.html", v=v, participants=participants)
|
||||||
|
|
|
@ -176,8 +176,8 @@ def post_id(pid, anything=None, v=None, sub=None):
|
||||||
|
|
||||||
comments = sort_comments(sort, comments)
|
comments = sort_comments(sort, comments)
|
||||||
|
|
||||||
first = [c[0] for c in comments.filter(or_(and_(Comment.slots_result == None, Comment.blackjack_result == None, Comment.wordle_result == None), func.length(Comment.body_html) > 100)).all()]
|
first = [c[0] for c in comments.filter(or_(and_(Comment.wordle_result == None), func.length(Comment.body_html) > 100)).all()]
|
||||||
second = [c[0] for c in comments.filter(or_(Comment.slots_result != None, Comment.blackjack_result != None, Comment.wordle_result != None), func.length(Comment.body_html) <= 100).all()]
|
second = [c[0] for c in comments.filter(or_(Comment.wordle_result != None), func.length(Comment.body_html) <= 100).all()]
|
||||||
comments = first + second
|
comments = first + second
|
||||||
else:
|
else:
|
||||||
pinned = g.db.query(Comment).filter(Comment.parent_submission == post.id, Comment.stickied != None).all()
|
pinned = g.db.query(Comment).filter(Comment.parent_submission == post.id, Comment.stickied != None).all()
|
||||||
|
@ -186,8 +186,8 @@ def post_id(pid, anything=None, v=None, sub=None):
|
||||||
|
|
||||||
comments = sort_comments(sort, comments)
|
comments = sort_comments(sort, comments)
|
||||||
|
|
||||||
first = comments.filter(or_(and_(Comment.slots_result == None, Comment.blackjack_result == None, Comment.wordle_result == None), func.length(Comment.body_html) > 100)).all()
|
first = comments.filter(or_(and_(Comment.wordle_result == None), func.length(Comment.body_html) > 100)).all()
|
||||||
second = comments.filter(or_(Comment.slots_result != None, Comment.blackjack_result != None, Comment.wordle_result != None), func.length(Comment.body_html) <= 100).all()
|
second = comments.filter(or_(Comment.wordle_result != None), func.length(Comment.body_html) <= 100).all()
|
||||||
comments = first + second
|
comments = first + second
|
||||||
|
|
||||||
offset = 0
|
offset = 0
|
||||||
|
@ -302,16 +302,16 @@ def viewmore(v, pid, sort, offset):
|
||||||
|
|
||||||
comments = sort_comments(sort, comments)
|
comments = sort_comments(sort, comments)
|
||||||
|
|
||||||
first = [c[0] for c in comments.filter(or_(and_(Comment.slots_result == None, Comment.blackjack_result == None, Comment.wordle_result == None), func.length(Comment.body_html) > 100)).all()]
|
first = [c[0] for c in comments.filter(or_(and_(Comment.wordle_result == None), func.length(Comment.body_html) > 100)).all()]
|
||||||
second = [c[0] for c in comments.filter(or_(Comment.slots_result != None, Comment.blackjack_result != None, Comment.wordle_result != None), func.length(Comment.body_html) <= 100).all()]
|
second = [c[0] for c in comments.filter(or_(Comment.wordle_result != None), func.length(Comment.body_html) <= 100).all()]
|
||||||
comments = first + second
|
comments = first + second
|
||||||
else:
|
else:
|
||||||
comments = g.db.query(Comment).join(Comment.author).filter(User.shadowbanned == None, Comment.parent_submission == pid, Comment.level == 1, Comment.stickied == None, Comment.id.notin_(ids))
|
comments = g.db.query(Comment).join(Comment.author).filter(User.shadowbanned == None, Comment.parent_submission == pid, Comment.level == 1, Comment.stickied == None, Comment.id.notin_(ids))
|
||||||
|
|
||||||
comments = sort_comments(sort, comments)
|
comments = sort_comments(sort, comments)
|
||||||
|
|
||||||
first = comments.filter(or_(and_(Comment.slots_result == None, Comment.blackjack_result == None, Comment.wordle_result == None), func.length(Comment.body_html) > 100)).all()
|
first = comments.filter(or_(and_(Comment.wordle_result == None), func.length(Comment.body_html) > 100)).all()
|
||||||
second = comments.filter(or_(Comment.slots_result != None, Comment.blackjack_result != None, Comment.wordle_result != None), func.length(Comment.body_html) <= 100).all()
|
second = comments.filter(or_(Comment.wordle_result != None), func.length(Comment.body_html) <= 100).all()
|
||||||
comments = first + second
|
comments = first + second
|
||||||
comments = comments[offset:]
|
comments = comments[offset:]
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{% if LOTTERY_ENABLED -%}
|
{% if CASINO_ENABLED -%}
|
||||||
<h4>Lottery</h4>
|
<h4>Lottery</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/admin/lottery/participants">Participants</a></li>
|
<li><a href="/admin/lottery/participants">Participants</a></li>
|
||||||
|
|
|
@ -0,0 +1,253 @@
|
||||||
|
{% extends "default.html" %} {% block content %}
|
||||||
|
<link rel="stylesheet" href="/assets/css/casino.css?v=12" />
|
||||||
|
<script src="/assets/js/casino.js?v=2002"></script>
|
||||||
|
|
||||||
|
<!-- New -->
|
||||||
|
<div class="casino-games">
|
||||||
|
<!-- Slots -->
|
||||||
|
<div id="slots-block" class="casino-block">
|
||||||
|
<div class="casino-block-title">
|
||||||
|
Slots
|
||||||
|
<hr style="flex: 1; margin-left: 1rem" />
|
||||||
|
</div>
|
||||||
|
<div class="casino-block-inner">
|
||||||
|
<div class="casino-block-left">
|
||||||
|
<!-- Game -->
|
||||||
|
<div class="casino-block-game">
|
||||||
|
<div>
|
||||||
|
<div class="casino-slots-results" style="flex: 1">
|
||||||
|
<div class="reel">
|
||||||
|
<img src="/i/rDrama/coins.webp?v=3009" alt="coin" />
|
||||||
|
</div>
|
||||||
|
<div class="reel">
|
||||||
|
<img src="/i/rDrama/coins.webp?v=3009" alt="coin" />
|
||||||
|
</div>
|
||||||
|
<div class="reel">
|
||||||
|
<img src="/i/rDrama/coins.webp?v=3009" alt="coin" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="casino-slots-outcome" id="casinoSlotsResult">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Bet -->
|
||||||
|
<div class="casino-block-bet">
|
||||||
|
<div class="lottery-page--stat">
|
||||||
|
<div class="lottery-page--stat-keys" style="margin-right: 1rem">
|
||||||
|
<div>Enter Bet</div>
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
id="casinoSlotsBet"
|
||||||
|
class="form-control"
|
||||||
|
autocomplete="off"
|
||||||
|
value="100"
|
||||||
|
min="100"
|
||||||
|
step="1"
|
||||||
|
aria-label="Bet"
|
||||||
|
name="casinoSlotsBet"
|
||||||
|
type="number"
|
||||||
|
style="flex: 1; max-width: 200px; text-align: right"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="lottery-page--stat-values">
|
||||||
|
<div class="form-check">
|
||||||
|
<input
|
||||||
|
class="form-check-input"
|
||||||
|
type="radio"
|
||||||
|
name="casinoSlotsCurrency"
|
||||||
|
id="casinoSlotsCurrencyDramacoin"
|
||||||
|
value="dramacoin"
|
||||||
|
checked
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="form-check-label"
|
||||||
|
for="casinoSlotsCurrencyDramacoin"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="/i/rDrama/coins.webp?v=3009"
|
||||||
|
alt="coin"
|
||||||
|
width="40"
|
||||||
|
data-bs-toggle="tooltip"
|
||||||
|
data-bs-placement="bottom"
|
||||||
|
title="Dramacoin"
|
||||||
|
aria-label="Dramacoin"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input
|
||||||
|
class="form-check-input"
|
||||||
|
type="radio"
|
||||||
|
name="casinoSlotsCurrency"
|
||||||
|
id="casinoSlotsCurrencyMarseybux"
|
||||||
|
value="marseybux"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="form-check-label"
|
||||||
|
for="casinoSlotsCurrencyMarseybux"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="/i/marseybux.webp?v=2000"
|
||||||
|
alt="marseybux"
|
||||||
|
width="40"
|
||||||
|
data-bs-toggle="tooltip"
|
||||||
|
data-bs-placement="bottom"
|
||||||
|
title="Marseybux"
|
||||||
|
aria-label="Marseybux"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-success lottery-page--action"
|
||||||
|
id="casinoSlotsPull"
|
||||||
|
style="width: 100%"
|
||||||
|
onclick="pullSlots()"
|
||||||
|
>
|
||||||
|
Pull
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Blackjack -->
|
||||||
|
<div id="blackjack-block" class="casino-block">
|
||||||
|
<div class="casino-block-title">
|
||||||
|
Blackjack
|
||||||
|
<hr style="flex: 1; margin-left: 1rem" />
|
||||||
|
</div>
|
||||||
|
<div class="casino-block-inner">
|
||||||
|
<div class="casino-block-left">
|
||||||
|
<!-- Game -->
|
||||||
|
<div class="casino-block-game">
|
||||||
|
<div class="casino-game">
|
||||||
|
<div style="flex: 1">
|
||||||
|
<div class="blackjack-table">
|
||||||
|
<div style="display: flex; align-items: center">
|
||||||
|
<small style="margin-right: 0.5rem">Dealer</small>
|
||||||
|
<hr style="flex: 1" />
|
||||||
|
</div>
|
||||||
|
<div class="hand" id="casinoBlackjackDealerHand">
|
||||||
|
<div class="playing-card" data-who="dealer"></div>
|
||||||
|
<div class="playing-card" data-who="dealer"></div>
|
||||||
|
<div class="playing-card" data-who="dealer"></div>
|
||||||
|
<div class="playing-card" data-who="dealer"></div>
|
||||||
|
<div class="playing-card" data-who="dealer"></div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div class="hand" id="casinoBlackjackPlayerHand">
|
||||||
|
<div class="playing-card" data-who="player"></div>
|
||||||
|
<div class="playing-card" data-who="player"></div>
|
||||||
|
<div class="playing-card" data-who="player"></div>
|
||||||
|
<div class="playing-card" data-who="player"></div>
|
||||||
|
<div class="playing-card" data-who="player"></div>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex; align-items: center">
|
||||||
|
<hr style="flex: 1; margin-right: 0.5rem" />
|
||||||
|
<small>Player</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="casinoBlackjackResult"
|
||||||
|
class="casino-blackjack-outcome"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Bet -->
|
||||||
|
<div class="casino-block-bet">
|
||||||
|
<div id="casinoBlackjackWager" class="lottery-page--stat">
|
||||||
|
<div class="lottery-page--stat-keys" style="margin-right: 1rem">
|
||||||
|
<div>Enter Bet</div>
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
id="casinoBlackjackBet"
|
||||||
|
class="form-control"
|
||||||
|
autocomplete="off"
|
||||||
|
value="100"
|
||||||
|
min="100"
|
||||||
|
step="1"
|
||||||
|
aria-label="Bet"
|
||||||
|
name="casinoBlackjackBet"
|
||||||
|
type="number"
|
||||||
|
style="flex: 1; max-width: 200px; text-align: right"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="lottery-page--stat-values">
|
||||||
|
<div class="form-check">
|
||||||
|
<input
|
||||||
|
class="form-check-input"
|
||||||
|
type="radio"
|
||||||
|
name="casinoBlackjackCurrency"
|
||||||
|
id="casinoBlackjackCurrencyDramacoin"
|
||||||
|
value="dramacoin"
|
||||||
|
checked
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="form-check-label"
|
||||||
|
for="casinoBlackjackCurrencyDramacoin"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="/i/rDrama/coins.webp?v=3009"
|
||||||
|
alt="coin"
|
||||||
|
width="40"
|
||||||
|
data-bs-toggle="tooltip"
|
||||||
|
data-bs-placement="bottom"
|
||||||
|
title="Dramacoin"
|
||||||
|
aria-label="Dramacoin"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input
|
||||||
|
class="form-check-input"
|
||||||
|
type="radio"
|
||||||
|
name="casinoBlackjackCurrency"
|
||||||
|
id="casinoBlackjackCurrencyMarseybux"
|
||||||
|
value="marseybux"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="form-check-label"
|
||||||
|
for="casinoBlackjackCurrencyMarseybux"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="/i/marseybux.webp?v=2000"
|
||||||
|
alt="marseybux"
|
||||||
|
width="40"
|
||||||
|
data-bs-toggle="tooltip"
|
||||||
|
data-bs-placement="bottom"
|
||||||
|
title="Marseybux"
|
||||||
|
aria-label="Marseybux"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="casinoBlackjackActions" class="casino-blackjack-actions">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-success lottery-page--action"
|
||||||
|
id="casinoBlackjackDeal"
|
||||||
|
style="width: 100%"
|
||||||
|
onclick="dealBlackjack()"
|
||||||
|
>
|
||||||
|
Deal
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="casino-lottery">{% include "lottery.html" %}</div>
|
||||||
|
{% endblock %}
|
|
@ -209,14 +209,6 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if c.slots_result %}
|
|
||||||
<em style="position: relative; top: 2px; margin-left: 0.5rem">{{c.slots_result}}</em>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if c.blackjack_result %}
|
|
||||||
{{c.blackjack_html(v) | safe}}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if c.wordle_result %}
|
{% if c.wordle_result %}
|
||||||
{{c.wordle_html(v) | safe}}
|
{{c.wordle_html(v) | safe}}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -606,28 +606,6 @@ line breaks
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% if FEATURES['GAMBLING'] %}
|
|
||||||
<tr>
|
|
||||||
<td>!slots100</td>
|
|
||||||
<td>Play slots using coins - minimum 100 coins</td>
|
|
||||||
</tr>
|
|
||||||
{% if FEATURES['PROCOINS'] %}
|
|
||||||
<tr>
|
|
||||||
<td>!slotsmb100</td>
|
|
||||||
<td>Play slots using marseybux - minimum 100 marseybux</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
<tr>
|
|
||||||
<td>!blackjack100</td>
|
|
||||||
<td>Play blackjack using coins - minimum 100 coins</td>
|
|
||||||
</tr>
|
|
||||||
{% if FEATURES['PROCOINS'] %}
|
|
||||||
<tr>
|
|
||||||
<td>!blackjackmb100</td>
|
|
||||||
<td>Play blackjack using marseybux - minimum 100 marseybux</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% if FEATURES['WORDLE'] %}
|
{% if FEATURES['WORDLE'] %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>!wordle</td>
|
<td>!wordle</td>
|
||||||
|
|
|
@ -123,9 +123,9 @@
|
||||||
|
|
||||||
<a class="mobile-nav-icon d-md-none" href="/random_user"><i class="fas fa-music align-middle text-gray-500 black"></i></a>
|
<a class="mobile-nav-icon d-md-none" href="/random_user"><i class="fas fa-music align-middle text-gray-500 black"></i></a>
|
||||||
|
|
||||||
{% if v and LOTTERY_ENABLED %}
|
{% if v and CASINO_ENABLED %}
|
||||||
<a class="mobile-nav-icon d-md-none" href="/lottery">
|
<a class="mobile-nav-icon d-md-none" href="/casino">
|
||||||
<i class="fas fa-ticket align-middle text-gray-500 black"></i>
|
<i class="fas fa-usd align-middle text-gray-500 black"></i>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
@ -179,9 +179,9 @@
|
||||||
<a class="nav-link" href="/random_user" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Random User"><i class="fas fa-music"></i></a>
|
<a class="nav-link" href="/random_user" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Random User"><i class="fas fa-music"></i></a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{% if LOTTERY_ENABLED %}
|
{% if CASINO_ENABLED %}
|
||||||
<li class="nav-item d-flex align-items-center justify-content-center text-center mx-1">
|
<li class="nav-item d-flex align-items-center justify-content-center text-center mx-1">
|
||||||
<a class="nav-link" href="/lottery" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Lottery"><i class="fas fa-ticket"></i></a>
|
<a class="nav-link" href="/casino" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Casino"><i class="fas fa-usd"></i></a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
{% extends "default.html" %} {% block content %}
|
|
||||||
<div>
|
<div>
|
||||||
<div class="lottery-page--wrapper">
|
<div class="lottery-page--wrapper">
|
||||||
<div class="lottery-page--image">
|
<div class="lottery-page--image">
|
||||||
|
@ -103,7 +102,7 @@
|
||||||
aria-label="Quantity"
|
aria-label="Quantity"
|
||||||
name="ticketPurchaseQuantity"
|
name="ticketPurchaseQuantity"
|
||||||
type="number"
|
type="number"
|
||||||
style="flex: 1; max-width: 100px; text-align: center;"
|
style="flex: 1; max-width: 100px; text-align: center"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -188,4 +187,3 @@
|
||||||
|
|
||||||
<script src="{{asset('js/lottery.js')}}"></script>
|
<script src="{{asset('js/lottery.js')}}"></script>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{%-
|
{%-
|
||||||
set CACHE_VER = {
|
set CACHE_VER = {
|
||||||
'css/main.css': 506,
|
'css/main.css': 507,
|
||||||
'css/catalog.css': 2,
|
'css/catalog.css': 2,
|
||||||
|
|
||||||
'css/4chan.css': 61,
|
'css/4chan.css': 61,
|
||||||
|
|
|
@ -356,8 +356,6 @@ CREATE TABLE public.comments (
|
||||||
top_comment_id integer,
|
top_comment_id integer,
|
||||||
stickied_utc integer,
|
stickied_utc integer,
|
||||||
ghost boolean DEFAULT false NOT NULL,
|
ghost boolean DEFAULT false NOT NULL,
|
||||||
slots_result character varying(36),
|
|
||||||
blackjack_result character varying(860),
|
|
||||||
treasure_amount character varying(10),
|
treasure_amount character varying(10),
|
||||||
wordle_result character varying(115)
|
wordle_result character varying(115)
|
||||||
);
|
);
|
||||||
|
|
|
@ -598,8 +598,6 @@ Ayoo, you're fat as fuck!
|
||||||
{[para]}
|
{[para]}
|
||||||
AVOCADO NIGGER!
|
AVOCADO NIGGER!
|
||||||
{[para]}
|
{[para]}
|
||||||
!slots
|
|
||||||
{[para]}
|
|
||||||
You're poor, figure it out. Imagine being at the super market looking at the cost of nectors and shit. Fuck you, dude.
|
You're poor, figure it out. Imagine being at the super market looking at the cost of nectors and shit. Fuck you, dude.
|
||||||
{[para]}
|
{[para]}
|
||||||
Want to go rape some fire hydrants?
|
Want to go rape some fire hydrants?
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
CREATE TYPE casino_game_kind AS ENUM ('blackjack', 'slots');
|
||||||
|
|
||||||
|
CREATE TYPE casino_game_currency AS ENUM ('coins', 'procoins');
|
||||||
|
|
||||||
|
CREATE TABLE casino_games (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
user_id integer NOT NULL REFERENCES users(id),
|
||||||
|
created_utc integer NOT NULL,
|
||||||
|
active boolean NOT NULL DEFAULT true,
|
||||||
|
currency casino_game_currency NOT NULL,
|
||||||
|
wager integer NOT NULL,
|
||||||
|
winnings integer NOT NULL,
|
||||||
|
kind casino_game_kind NOT NULL,
|
||||||
|
game_state jsonb NOT NULL
|
||||||
|
);
|
Loading…
Reference in New Issue