diff --git a/files/assets/css/4chan.css b/files/assets/css/4chan.css
index b2450c29c..c2d8970e3 100644
--- a/files/assets/css/4chan.css
+++ b/files/assets/css/4chan.css
@@ -144,8 +144,8 @@ blockquote a {
.sidebar
{
- border-radius: 6px;
- margin-top: 6px;
+ border-radius: 6px;
+ margin-top: 6px;
}
h5.post-title a:visited {
diff --git a/files/assets/css/awards.css b/files/assets/css/awards.css
index a98860993..33d25e52c 100644
--- a/files/assets/css/awards.css
+++ b/files/assets/css/awards.css
@@ -32,7 +32,7 @@
.ricardo img {
max-height: 15rem !important;
- max-height: min(30vw,15rem) !important;
+ max-height: min(30vw,15rem) !important;
}
.ricardoleft {
diff --git a/files/assets/css/catalog.css b/files/assets/css/catalog.css
index ed75fa65a..60964d344 100644
--- a/files/assets/css/catalog.css
+++ b/files/assets/css/catalog.css
@@ -1,70 +1,70 @@
#posts {
- display: grid;
- grid-template: auto / auto auto auto;
+ display: grid;
+ grid-template: auto / auto auto auto;
}
@media (min-width: 1668px) {
- #frontpage .post-img {
- height:105px;
- width:150px;
- }
+ #frontpage .post-img {
+ height:105px;
+ width:150px;
+ }
- #frontpage .post-title {
- font-size: 18px;
- }
+ #frontpage .post-title {
+ font-size: 18px;
+ }
- #frontpage .post-meta, .post-actions button, .post-actions a {
- font-size:14px;
- }
+ #frontpage .post-meta, .post-actions button, .post-actions a {
+ font-size:14px;
+ }
}
@media (max-width: 960px) {
- #posts {
- display: grid;
- grid-template: auto / auto auto;
- }
+ #posts {
+ display: grid;
+ grid-template: auto / auto auto;
+ }
}
@media (max-width: 768px) {
- #posts {
- display: grid;
- grid-template: auto / auto;
- }
+ #posts {
+ display: grid;
+ grid-template: auto / auto;
+ }
}
#frontpage .sidebar {
- display:none !important;
+ display:none !important;
}
#frontpage .container {
- max-width: 1750px;
+ max-width: 1750px;
}
#frontpage .voting.d-md-flex {
- display: none !important;
+ display: none !important;
}
#frontpage .voting.d-md-none {
- display: block !important;
+ display: block !important;
}
#frontpage .card-footer {
- display: block !important;
+ display: block !important;
}
#frontpage .post-actions.d-md-block {
- display: none !important;
+ display: none !important;
}
#fronpage.card {
- padding: 0.5rem !important;
+ padding: 0.5rem !important;
}
#frontpage .modal.d-md-none.show {
- display: inline-block !important;
- max-width: 30rem;
+ display: inline-block !important;
+ max-width: 30rem;
}
#frontpage .fa-expand-alt {
- display:none;
+ display:none;
}
diff --git a/files/assets/css/classic_dark.css b/files/assets/css/classic_dark.css
index 885ed7c2c..84000507c 100644
--- a/files/assets/css/classic_dark.css
+++ b/files/assets/css/classic_dark.css
@@ -1,7 +1,7 @@
@import 'classic.css?v=4031';
:root {
- --muted: #999;
- --black: #999;
- --bgc: #222;
+ --muted: #999;
+ --black: #999;
+ --bgc: #222;
}
diff --git a/files/assets/css/coffee.css b/files/assets/css/coffee.css
index 427bfed3d..fded876ba 100644
--- a/files/assets/css/coffee.css
+++ b/files/assets/css/coffee.css
@@ -96,8 +96,8 @@ blockquote {
.sidebar
{
- border-radius: 6px;
- margin-top: 6px;
+ border-radius: 6px;
+ margin-top: 6px;
}
h5.post-title a:visited {
diff --git a/files/assets/css/dark.css b/files/assets/css/dark.css
index 6f72727a1..873de18f3 100644
--- a/files/assets/css/dark.css
+++ b/files/assets/css/dark.css
@@ -71,12 +71,12 @@ pre {
.sidebar
{
- border-radius: 6px;
- margin-top: 6px;
+ border-radius: 6px;
+ margin-top: 6px;
}
.modal-content {
- background-color: var(--gray-900);
+ background-color: var(--gray-900);
}
.modal .comment-actions .list-group-item {
@@ -97,5 +97,5 @@ h5.post-title a:visited {
}
.empty-state-img {
- filter: brightness(99);
+ filter: brightness(99);
}
diff --git a/files/assets/css/dramblr.css b/files/assets/css/dramblr.css
index 7e5b0d86b..39f3725a5 100644
--- a/files/assets/css/dramblr.css
+++ b/files/assets/css/dramblr.css
@@ -135,7 +135,7 @@ color: var(--gray-700);
.post-title
{
- color: var(--gray-300) !important;
+ color: var(--gray-300) !important;
}
.tooltip-inner {
diff --git a/files/assets/css/main.css b/files/assets/css/main.css
index 5ca58d273..9b85dfd1e 100644
--- a/files/assets/css/main.css
+++ b/files/assets/css/main.css
@@ -1,12 +1,12 @@
@charset "UTF-8";
button {
background: none;
- border: none;
- padding: 0;
- margin: 0;
+ border: none;
+ padding: 0;
+ margin: 0;
color: var(--primary);
- text-decoration: none;
- background-color: transparent;
+ text-decoration: none;
+ background-color: transparent;
}
*, *::before, *::after {
box-sizing: border-box;
@@ -334,7 +334,7 @@ pre code {
.shadow {
/* box-shadow: 0 0.1px 3px rgba(190, 113, 113, 0.05), 0 0 0 0.1px rgba(0, 0, 0, 0.05); */
- box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.4);
+ box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.4);
}
.shadow-none {
box-shadow: none !important;
@@ -796,14 +796,14 @@ input[type=submit].btn-follow, input[type=reset].btn-follow, input[type=button].
}
@keyframes expand
{
- 0% { opacity: 0.0; transform: scaleY(0.7); }
- 100% { opacity: 1.0; transform: scaleY(1.0); }
+ 0% { opacity: 0.0; transform: scaleY(0.7); }
+ 100% { opacity: 1.0; transform: scaleY(1.0); }
}
.dropdown-menu-right.show
{
- transform-origin: top;
- animation: expand .20s 1;
+ transform-origin: top;
+ animation: expand .20s 1;
}
@@ -825,12 +825,12 @@ input[type=submit].btn-follow, input[type=reset].btn-follow, input[type=button].
background-clip: padding-box;
border: 1px solid rgba(0, 0, 0, 0.4);
border-radius: 0.35rem;
- box-shadow: 0px 2px 20px rgba(0, 0, 0, 0.3);
+ box-shadow: 0px 2px 20px rgba(0, 0, 0, 0.3);
}
.dropdown-menu-right {
right: 0;
left: auto;
- left: -2px !important;
+ left: -2px !important;
}
@media (min-width: 992px) {
.dropdown-menu-lg-left {
@@ -1123,11 +1123,11 @@ nav
align-items: center;
justify-content: space-between;
padding: 0.5rem 1rem;
- transition: border-bottom .2s;
+ transition: border-bottom .2s;
}
.navbar-active
{
- border-bottom: 1px solid rgba(18, 18, 18, .4);
+ border-bottom: 1px solid rgba(18, 18, 18, .4);
}
.navbar .container, .navbar .container-fluid {
display: flex;
@@ -3071,7 +3071,7 @@ label.terms {
padding: 0.5rem 1rem;
border-radius: 0.35rem;
color: var(--black);
- transition: background .1s, transform .2s;
+ transition: background .1s, transform .2s;
}
.dropdown-item:hover, .dropdown-item:focus, .dropdown-item.active {
color: var(--black);
@@ -3079,7 +3079,7 @@ label.terms {
background-color: var(--gray-300);
}
.dropdown-item:active {
- transform: scale(0.95);
+ transform: scale(0.95);
}
@@ -3134,7 +3134,7 @@ small, .small {
.active-anim.arrow-up::before
{
- color: var(--primary);
+ color: var(--primary);
}
@@ -3153,78 +3153,78 @@ small, .small {
}
.arrow-up, .arrow-down
{
- position: relative;
- display: inline-block;
+ position: relative;
+ display: inline-block;
}
.arrow-up.active-anim
{
- animation: bounce-top .7s 1 0s;
- -webkit-animation: bounce-top .7s 1 0s;
+ animation: bounce-top .7s 1 0s;
+ -webkit-animation: bounce-top .7s 1 0s;
}
.arrow-down.active-anim
{
- animation: bounce-bot .7s 1 0s;
- -webkit-animation: bounce-bot .7s 1 0s;
+ animation: bounce-bot .7s 1 0s;
+ -webkit-animation: bounce-bot .7s 1 0s;
}
@keyframes bounce-top {
- 20% {
- transform: translateY(-9px);
- animation-timing-function: ease-in;
- opacity: 1;
- }
- 52% {
- transform: translateY(-6px);
- animation-timing-function: ease-in;
- opacity: 1;
- }
- 69% {
- transform: translateY(-3px);
- animation-timing-function: ease-in;
- opacity: 1;
- }
- 35%,
- 63%,
- 79%,
- 100% {
- transform: translateY(0px);
- animation-timing-function: ease-out;
- }
+ 20% {
+ transform: translateY(-9px);
+ animation-timing-function: ease-in;
+ opacity: 1;
+ }
+ 52% {
+ transform: translateY(-6px);
+ animation-timing-function: ease-in;
+ opacity: 1;
+ }
+ 69% {
+ transform: translateY(-3px);
+ animation-timing-function: ease-in;
+ opacity: 1;
+ }
+ 35%,
+ 63%,
+ 79%,
+ 100% {
+ transform: translateY(0px);
+ animation-timing-function: ease-out;
+ }
}
@keyframes bounce-bot {
- 30% {
- transform: translateY(6px);
- animation-timing-function: ease-in;
- opacity: 1;
- }
- 52% {
- transform: translateY(3px);
- animation-timing-function: ease-in;
- opacity: 1;
- }
- 69% {
- transform: translateY(2px);
- animation-timing-function: ease-in;
- opacity: 1;
- }
- 100% {
- transform: translateY(0px);
- animation-timing-function: ease-out;
- }
+ 30% {
+ transform: translateY(6px);
+ animation-timing-function: ease-in;
+ opacity: 1;
+ }
+ 52% {
+ transform: translateY(3px);
+ animation-timing-function: ease-in;
+ opacity: 1;
+ }
+ 69% {
+ transform: translateY(2px);
+ animation-timing-function: ease-in;
+ opacity: 1;
+ }
+ 100% {
+ transform: translateY(0px);
+ animation-timing-function: ease-out;
+ }
}
.comment-write.collapsed
{
- animation: expand-reply .3s 1;
+ animation: expand-reply .3s 1;
}
@keyframes expand-reply
{
- 0% { opacity: .6; padding-top: 0px; height: 0px; overflow: hidden; }
- 100% { opacity: 1;padding-top: 0px; height: 182px; overflow: hidden; }
+ 0% { opacity: .6; padding-top: 0px; height: 0px; overflow: hidden; }
+ 100% { opacity: 1;padding-top: 0px; height: 182px; overflow: hidden; }
}
.active.arrow-down::before {
@@ -3261,7 +3261,7 @@ small, .small {
}
.score-up-anim
{
- color: var(--primary);
+ color: var(--primary);
}
.score-down {
color: #38B2AC !important;
@@ -3272,13 +3272,13 @@ small, .small {
.voting .arrow-up,
.voting .arrow-down
{
- display: block;
+ display: block;
}
.catalog .voting .arrow-up,
.catalog .voting .arrow-down
{
- display: inline-block;
+ display: inline-block;
}
@@ -4207,9 +4207,9 @@ pre .com, code .com {
-ms-transition: all 0.15s ease;
transition: all 0.15s ease;
width: 25vw;
- height: 35vh;
+ height: 35vh;
-o-object-fit: contain;
- object-fit: contain;
+ object-fit: contain;
}
@media (max-width: 767.98px) {
.gif-categories img {
@@ -4244,7 +4244,7 @@ pre .com, code .com {
}
.modal-backdrop.show
{
- background-color: rgba(33, 38, 45, .8);
+ background-color: rgba(33, 38, 45, .8);
}
@media (max-width: 767.98px) {
@@ -4376,13 +4376,13 @@ pre .com, code .com {
font-size: 1.5rem;
color: var(--gray-200);
opacity: 1;
- }
- #voting .arrow-up,
- .voting .arrow-up,
- .voting .arrow-down
- {
- display: inline-block;
- }
+ }
+ #voting .arrow-up,
+ .voting .arrow-up,
+ .voting .arrow-down
+ {
+ display: inline-block;
+ }
.active.arrow-up::before, .active.arrow-up:hover::before {
color: var(--primary);
@@ -4819,30 +4819,30 @@ input[type=radio] ~ .custom-control-label::before {
}
span[data-bs-toggle], .pat-preview {
- position: relative;
- display: inline-block;
+ position: relative;
+ display: inline-block;
}
img[src="/i/hand.webp"] {
- position: absolute;
- width: 90%;
- height: 90%;
- margin-top: -10%;
- z-index: 1;
+ position: absolute;
+ width: 90%;
+ height: 90%;
+ margin-top: -10%;
+ z-index: 1;
}
img[src="/i/hand.webp"]+img {
- animation: pat-pfp-anim 0.3s infinite;
- transform-origin: bottom center;
- margin-top: 10%;
- text-align: center;
- object-fit: contain;
+ animation: pat-pfp-anim 0.3s infinite;
+ transform-origin: bottom center;
+ margin-top: 10%;
+ text-align: center;
+ object-fit: contain;
}
img[src="/i/hand.webp"]+img[src^="/pp/"], img[src="/i/hand.webp"]+img[src$="/pic"] {
border-radius: 50%;
}
@keyframes pat-pfp-anim {
- 0% { transform: scale(1, 0.8) }
- 50% { transform: scale(0.8, 1) }
- 100% { transform: scale(1, 0.8) }
+ 0% { transform: scale(1, 0.8) }
+ 50% { transform: scale(0.8, 1) }
+ 100% { transform: scale(1, 0.8) }
}
/* Fix for
being populated with in many contexts. */
@@ -5211,8 +5211,8 @@ li > .sidebar {
.sidebar
{
- border-radius: 6px;
- margin-top: 6px;
+ border-radius: 6px;
+ margin-top: 6px;
}
@@ -5305,20 +5305,20 @@ th, td {
}
.glow .post-title, .glow a, .glow .post-meta *, .glow .user-info *, .glow .comment-text, .glow .comment-actions *, .glow {
- color:lightgreen !important;
- text-shadow:1px 1px 1px darkgreen, 0 0 5px green;
+ color:lightgreen !important;
+ text-shadow:1px 1px 1px darkgreen, 0 0 5px green;
}
.glow .score-up, .glow .active.arrow-up::before, .glow .arrow-up::after, .glow .arrow-up:hover::before {
- color: lime !important;
+ color: lime !important;
}
.glow .score-down, .glow .active.arrow-down::before, .glow .arrow-down::after, .glow .arrow-down:hover::before {
- color: lime !important;
+ color: lime !important;
}
.glow .arrow-up::before, .glow .arrow-down::before, .glow .score {
- color: lightgreen;
+ color: lightgreen;
}
.glow .post-body a, .glow .comment-text a {
@@ -5468,14 +5468,14 @@ audio, video {
.lottery-page--wrapper {
flex-direction: column;
justify-content: center;
- padding: 2rem;
+ padding: 2rem;
}
- .lottery-page--wrapper > div
- {
- width: 300px;
- height: 300px;
- }
+ .lottery-page--wrapper > div
+ {
+ width: 300px;
+ height: 300px;
+ }
.lottery-page--action {
margin-bottom: 1rem;
@@ -5647,14 +5647,14 @@ g {
}
.ext-link {
- position:absolute;
- bottom: 0;
- right: 0;
- font-size:14px;
- color:white;
- background-color:var(--primary);
- padding:3px;
- border-radius:.35rem;
+ position:absolute;
+ bottom: 0;
+ right: 0;
+ font-size:14px;
+ color:white;
+ background-color:var(--primary);
+ padding:3px;
+ border-radius:.35rem;
}
/* ------- Font Awesome ------- */
@@ -6042,8 +6042,8 @@ g {
.post-preview {
padding: 11px 14px 0 14px !important;
- margin-bottom: 0.5rem !important;
- margin-top: 0.5rem !important;
+ margin-bottom: 0.5rem !important;
+ margin-top: 0.5rem !important;
}
@@ -6054,7 +6054,7 @@ g {
}
.showmore {
- width: 99%;
+ width: 99%;
padding: 5px;
margin: 5px 1px;
border-radius: 5px;
@@ -6063,7 +6063,7 @@ g {
background: -webkit-linear-gradient(left, red, orange, yellow, green, blue, indigo, violet );
text-shadow:-1px -1px 0 black,1px -1px 0 black,-1px 1px 0 black,1px 1px 0 black;
font-weight: 600;
- border: 2px solid var(--primary);
+ border: 2px solid var(--primary);
font-size: 20px;
}
@@ -6089,66 +6089,66 @@ g {
.ghostdiv
{
- display: block;
- white-space: pre-wrap;
- word-break: break-word;
- /* Attempt to copy the textarea/input padding */
- padding: 15px;
+ display: block;
+ white-space: pre-wrap;
+ word-break: break-word;
+ /* Attempt to copy the textarea/input padding */
+ padding: 15px;
}
#speed-carot-modal
{
- background-color: var(--gray-700);
- max-height: 500px;
- overflow-y: auto;
- overflow-x: hidden;
- border-radius: 4px;
- border: 1px solid rgba(255, 255, 255, 0.3);
- box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2);
+ background-color: var(--gray-700);
+ max-height: 500px;
+ overflow-y: auto;
+ overflow-x: hidden;
+ border-radius: 4px;
+ border: 1px solid rgba(255, 255, 255, 0.3);
+ box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2);
z-index:999;
}
#speed-carot-modal .speed-modal-option
{
- border-bottom: 1px solid #606060;
- padding: 4px;
- cursor: pointer;
+ border-bottom: 1px solid #606060;
+ padding: 4px;
+ cursor: pointer;
}
#speed-carot-modal .speed-modal-option:hover,
#speed-carot-modal .speed-modal-option:focus,
#speed-carot-modal .speed-modal-option.selected
{
- background-color: rgba(255, 255, 255, 0.2);
+ background-color: rgba(255, 255, 255, 0.2);
}
#speed-carot-modal .speed-modal-image
{
- object-fit: contain;
- width: 30px;
- height: 30px;
+ object-fit: contain;
+ width: 30px;
+ height: 30px;
}
#speed-carot-modal .speed-modal-option span
{
- overflow: hidden;
- display: inline-block;
- vertical-align: middle;
- margin-left: 10px;
- margin-right: 10px;
+ overflow: hidden;
+ display: inline-block;
+ vertical-align: middle;
+ margin-left: 10px;
+ margin-right: 10px;
}
.rainbow-text:not(a) {
- background-image: repeating-linear-gradient(135deg, violet, rgb(178, 94, 238), lightblue, green, yellow, orange, #ff7f7f 50%) !important;
- color: transparent !important;
- background-clip: text !important;
- -webkit-background-clip: text !important;
- font-weight: 700 !important;
+ background-image: repeating-linear-gradient(135deg, violet, rgb(178, 94, 238), lightblue, green, yellow, orange, #ff7f7f 50%) !important;
+ color: transparent !important;
+ background-clip: text !important;
+ -webkit-background-clip: text !important;
+ font-weight: 700 !important;
}
.rainbow-text:not(a) > p {
- color: transparent !important;
+ color: transparent !important;
}
.btn-rainbow {
@@ -6219,7 +6219,7 @@ blockquote + blockquote, div > blockquote:first-child, blockquote:last-child {
}
div.markdown {
height: auto;
- white-space: pre-wrap;
+ white-space: pre-wrap;
}
@media (max-width: 768px) or (min-width: 992px) {
#sidebar-btn {
@@ -6236,11 +6236,11 @@ div.markdown {
}
.directory--link:hover * {
- color: var(--primary) !important;
+ color: var(--primary) !important;
}
::-webkit-input-placeholder {
- opacity: 0.7 !important;
+ opacity: 0.7 !important;
}
.text-brown {
diff --git a/files/assets/css/midnight.css b/files/assets/css/midnight.css
index 07e64ba44..122df504a 100644
--- a/files/assets/css/midnight.css
+++ b/files/assets/css/midnight.css
@@ -44,8 +44,8 @@ body, .navbar-light, .navbar-dark, .card, .modal-content, .comment-write textare
.sidebar
{
- border-radius: 6px;
- margin-top: 6px;
+ border-radius: 6px;
+ margin-top: 6px;
}
.table th, .table td {
diff --git a/files/assets/css/rDrama.css b/files/assets/css/rDrama.css
index d6e50d2db..dfde27d55 100644
--- a/files/assets/css/rDrama.css
+++ b/files/assets/css/rDrama.css
@@ -1,7 +1,7 @@
.mod:before {
- content: '(((';
+ content: '(((';
}
.mod:after {
- content: ')))';
-}
\ No newline at end of file
+ content: ')))';
+}
diff --git a/files/assets/css/tron.css b/files/assets/css/tron.css
index 5021cc0a4..c1e8baa31 100644
--- a/files/assets/css/tron.css
+++ b/files/assets/css/tron.css
@@ -221,8 +221,8 @@
.sidebar
{
- border-radius: 6px;
- margin-top: 6px;
+ border-radius: 6px;
+ margin-top: 6px;
}
.tooltip-inner {
diff --git a/files/assets/css/win98.css b/files/assets/css/win98.css
index 0109a4013..af4dd5646 100644
--- a/files/assets/css/win98.css
+++ b/files/assets/css/win98.css
@@ -158,8 +158,8 @@ blockquote {
.sidebar
{
- border-radius: 0px;
- margin-top: 6px;
+ border-radius: 0px;
+ margin-top: 6px;
}
h5.post-title a:visited {
diff --git a/files/classes/leaderboard.py b/files/classes/leaderboard.py
index b7fe8933a..00ba45182 100644
--- a/files/classes/leaderboard.py
+++ b/files/classes/leaderboard.py
@@ -20,7 +20,7 @@ class Leaderboard:
value_func = None
def __init__(self, header_name:str, table_header_name:str, html_id:str, table_column_name:str,
- user_relative_url:Optional[str], query_function:Callable[..., Tuple[Any, Any, Any]],
+ user_relative_url:Optional[str], query_function:Callable[..., Tuple[Any, Any, Any]],
criteria, v:User, value_func:Optional[Callable[[User], Union[int, Column]]], db:scoped_session, users, limit=LEADERBOARD_LIMIT):
self.header_name = header_name
self.table_header_name = table_header_name
diff --git a/files/helpers/casino.py b/files/helpers/casino.py
index 089cb0304..fd3f59a61 100644
--- a/files/helpers/casino.py
+++ b/files/helpers/casino.py
@@ -9,99 +9,99 @@ from files.helpers.wrappers import *
def get_game_feed(game):
- games = g.db.query(Casino_Game) \
- .filter(Casino_Game.active == False, Casino_Game.kind == game) \
- .order_by(Casino_Game.created_utc.desc()).limit(30).all()
+ games = g.db.query(Casino_Game) \
+ .filter(Casino_Game.active == False, Casino_Game.kind == game) \
+ .order_by(Casino_Game.created_utc.desc()).limit(30).all()
- def format_game(game):
- user = g.db.query(User).filter(User.id == game.user_id).one()
- wonlost = 'lost' if game.winnings < 0 else 'won'
- relevant_currency = "coin" if game.currency == "coins" else "marseybux"
+ def format_game(game):
+ user = g.db.query(User).filter(User.id == game.user_id).one()
+ wonlost = 'lost' if game.winnings < 0 else 'won'
+ relevant_currency = "coin" if game.currency == "coins" else "marseybux"
- return {
- "user": user.username,
- "won_or_lost": wonlost,
- "amount": abs(game.winnings),
- "currency": relevant_currency
- }
+ return {
+ "user": user.username,
+ "won_or_lost": wonlost,
+ "amount": abs(game.winnings),
+ "currency": relevant_currency
+ }
- return list(map(format_game, games))
+ return list(map(format_game, games))
def get_game_leaderboard(game):
- timestamp_24h_ago = time.time() - 86400
- timestamp_all_time = 1662825600 # "All Time" starts on release day
+ timestamp_24h_ago = time.time() - 86400
+ timestamp_all_time = 1662825600 # "All Time" starts on release day
- biggest_win_all_time = g.db.query(Casino_Game.user_id, User.username, Casino_Game.currency, Casino_Game.winnings).select_from(
- Casino_Game).join(User).order_by(Casino_Game.winnings.desc()).filter(Casino_Game.kind == game, Casino_Game.created_utc > timestamp_all_time).limit(1).one_or_none()
+ biggest_win_all_time = g.db.query(Casino_Game.user_id, User.username, Casino_Game.currency, Casino_Game.winnings).select_from(
+ Casino_Game).join(User).order_by(Casino_Game.winnings.desc()).filter(Casino_Game.kind == game, Casino_Game.created_utc > timestamp_all_time).limit(1).one_or_none()
- biggest_win_last_24h = g.db.query(Casino_Game.user_id, User.username, Casino_Game.currency, Casino_Game.winnings).select_from(
- Casino_Game).join(User).order_by(Casino_Game.winnings.desc()).filter(Casino_Game.kind == game, Casino_Game.created_utc > timestamp_24h_ago).limit(1).one_or_none()
+ biggest_win_last_24h = g.db.query(Casino_Game.user_id, User.username, Casino_Game.currency, Casino_Game.winnings).select_from(
+ Casino_Game).join(User).order_by(Casino_Game.winnings.desc()).filter(Casino_Game.kind == game, Casino_Game.created_utc > timestamp_24h_ago).limit(1).one_or_none()
- biggest_loss_all_time = g.db.query(Casino_Game.user_id, User.username, Casino_Game.currency, Casino_Game.winnings).select_from(
- Casino_Game).join(User).order_by(Casino_Game.winnings.asc()).filter(Casino_Game.kind == game, Casino_Game.created_utc > timestamp_all_time).limit(1).one_or_none()
+ biggest_loss_all_time = g.db.query(Casino_Game.user_id, User.username, Casino_Game.currency, Casino_Game.winnings).select_from(
+ Casino_Game).join(User).order_by(Casino_Game.winnings.asc()).filter(Casino_Game.kind == game, Casino_Game.created_utc > timestamp_all_time).limit(1).one_or_none()
- biggest_loss_last_24h = g.db.query(Casino_Game.user_id, User.username, Casino_Game.currency, Casino_Game.winnings).select_from(
- Casino_Game).join(User).order_by(Casino_Game.winnings.asc()).filter(Casino_Game.kind == game, Casino_Game.created_utc > timestamp_24h_ago).limit(1).one_or_none()
+ biggest_loss_last_24h = g.db.query(Casino_Game.user_id, User.username, Casino_Game.currency, Casino_Game.winnings).select_from(
+ Casino_Game).join(User).order_by(Casino_Game.winnings.asc()).filter(Casino_Game.kind == game, Casino_Game.created_utc > timestamp_24h_ago).limit(1).one_or_none()
- if not biggest_win_all_time:
- biggest_win_all_time = [None, None, None, 0]
+ if not biggest_win_all_time:
+ biggest_win_all_time = [None, None, None, 0]
- if not biggest_win_last_24h:
- biggest_win_last_24h = [None, None, None, 0]
+ if not biggest_win_last_24h:
+ biggest_win_last_24h = [None, None, None, 0]
- if not biggest_loss_all_time:
- biggest_loss_all_time = [None, None, None, 0]
+ if not biggest_loss_all_time:
+ biggest_loss_all_time = [None, None, None, 0]
- if not biggest_loss_last_24h:
- biggest_loss_last_24h = [None, None, None, 0]
+ if not biggest_loss_last_24h:
+ biggest_loss_last_24h = [None, None, None, 0]
- return {
- "all_time": {
- "biggest_win": {
+ return {
+ "all_time": {
+ "biggest_win": {
"user": biggest_win_all_time[1],
"currency": biggest_win_all_time[2],
"amount": biggest_win_all_time[3]
},
- "biggest_loss": {
+ "biggest_loss": {
"user": biggest_loss_all_time[1],
"currency": biggest_loss_all_time[2],
"amount": abs(biggest_loss_all_time[3])
}
- },
- "last_24h": {
- "biggest_win": {
+ },
+ "last_24h": {
+ "biggest_win": {
"user": biggest_win_last_24h[1],
"currency": biggest_win_last_24h[2],
"amount": biggest_win_last_24h[3]
},
- "biggest_loss": {
+ "biggest_loss": {
"user": biggest_loss_last_24h[1],
"currency": biggest_loss_last_24h[2],
"amount": abs(biggest_loss_last_24h[3])
}
- }
- }
+ }
+ }
def distribute_wager_badges(user, wager, won):
- badges_earned = []
+ badges_earned = []
- if won:
- if wager >= 1000:
- badges_earned.append(160)
- if wager >= 10000:
- badges_earned.append(161)
- if wager >= 100000:
- badges_earned.append(162)
- else:
- if wager >= 1000:
- badges_earned.append(157)
- if wager >= 10000:
- badges_earned.append(158)
- if wager >= 100000:
- badges_earned.append(159)
+ if won:
+ if wager >= 1000:
+ badges_earned.append(160)
+ if wager >= 10000:
+ badges_earned.append(161)
+ if wager >= 100000:
+ badges_earned.append(162)
+ else:
+ if wager >= 1000:
+ badges_earned.append(157)
+ if wager >= 10000:
+ badges_earned.append(158)
+ if wager >= 100000:
+ badges_earned.append(159)
- for badge in badges_earned:
- badge_grant(user, badge)
+ for badge in badges_earned:
+ badge_grant(user, badge)
diff --git a/files/helpers/cloudflare.py b/files/helpers/cloudflare.py
index 9007d0804..4dafa3516 100644
--- a/files/helpers/cloudflare.py
+++ b/files/helpers/cloudflare.py
@@ -8,35 +8,35 @@ CLOUDFLARE_REQUEST_TIMEOUT_SECS = 5
DEFAULT_CLOUDFLARE_ZONE = 'blahblahblah'
def _request_from_cloudflare(url:str, method:str, post_data_str) -> bool:
- if CF_ZONE == DEFAULT_CLOUDFLARE_ZONE: return False
- try:
- res = str(requests.request(method, f"{CLOUDFLARE_API_URL}/zones/{CF_ZONE}/{url}", headers=CF_HEADERS, data=post_data_str, timeout=CLOUDFLARE_REQUEST_TIMEOUT_SECS))
- except:
- return False
- return res == ""
+ if CF_ZONE == DEFAULT_CLOUDFLARE_ZONE: return False
+ try:
+ res = str(requests.request(method, f"{CLOUDFLARE_API_URL}/zones/{CF_ZONE}/{url}", headers=CF_HEADERS, data=post_data_str, timeout=CLOUDFLARE_REQUEST_TIMEOUT_SECS))
+ except:
+ return False
+ return res == ""
def get_security_level() -> Optional[str]:
- res = None
- try:
- res = requests.get(f'{CLOUDFLARE_API_URL}/zones/{CF_ZONE}/settings/security_level', headers=CF_HEADERS, timeout=CLOUDFLARE_REQUEST_TIMEOUT_SECS).json()['result']['value']
- except:
- pass
- return res
+ res = None
+ try:
+ res = requests.get(f'{CLOUDFLARE_API_URL}/zones/{CF_ZONE}/settings/security_level', headers=CF_HEADERS, timeout=CLOUDFLARE_REQUEST_TIMEOUT_SECS).json()['result']['value']
+ except:
+ pass
+ return res
def set_security_level(under_attack="high") -> bool:
- return _request_from_cloudflare("settings/security_level", "PATCH", f'{{"value":"{under_attack}"}}')
+ return _request_from_cloudflare("settings/security_level", "PATCH", f'{{"value":"{under_attack}"}}')
def purge_entire_cache() -> bool:
- return _request_from_cloudflare("purge_cache", "POST", '{"purge_everything":true}')
+ return _request_from_cloudflare("purge_cache", "POST", '{"purge_everything":true}')
def purge_files_in_cache(files:Union[List[str],str]) -> bool:
- if CF_ZONE == DEFAULT_CLOUDFLARE_ZONE: return False
- if isinstance(files, str):
- files = [files]
- post_data = {"files": files}
- res = None
- try:
- res = requests.post(f'{CLOUDFLARE_API_URL}/zones/{CF_ZONE}/purge_cache', headers=CF_HEADERS, data=json.dumps(post_data), timeout=CLOUDFLARE_REQUEST_TIMEOUT_SECS)
- except:
- return False
- return res == ""
\ No newline at end of file
+ if CF_ZONE == DEFAULT_CLOUDFLARE_ZONE: return False
+ if isinstance(files, str):
+ files = [files]
+ post_data = {"files": files}
+ res = None
+ try:
+ res = requests.post(f'{CLOUDFLARE_API_URL}/zones/{CF_ZONE}/purge_cache', headers=CF_HEADERS, data=json.dumps(post_data), timeout=CLOUDFLARE_REQUEST_TIMEOUT_SECS)
+ except:
+ return False
+ return res == ""
diff --git a/files/helpers/const.py b/files/helpers/const.py
index 46cf9188a..f64ff7708 100644
--- a/files/helpers/const.py
+++ b/files/helpers/const.py
@@ -866,13 +866,13 @@ AWARDS = {
"price": 1500
},
"spider": {
- "kind": "spider",
- "title": "Spider!",
- "description": f"Summons a spider to terrorize the recipient for 24 hours.",
- "icon": "fas fa-spider",
- "color": "text-brown",
- "price": 2000
- },
+ "kind": "spider",
+ "title": "Spider!",
+ "description": f"Summons a spider to terrorize the recipient for 24 hours.",
+ "icon": "fas fa-spider",
+ "color": "text-brown",
+ "price": 2000
+ },
"agendaposter": {
"kind": "agendaposter",
"title": "Chud",
diff --git a/files/helpers/get.py b/files/helpers/get.py
index b0293bfed..336ceb11a 100644
--- a/files/helpers/get.py
+++ b/files/helpers/get.py
@@ -199,58 +199,58 @@ def get_comment(i:Union[str, int], v:Optional[User]=None, graceful=False) -> Opt
return add_vote_and_block_props(comment, v, CommentVote)
def add_block_props(target:Union[Submission, Comment, User], v:Optional[User]):
- if not v: return target
- id = None
+ if not v: return target
+ id = None
- if any(isinstance(target, cls) for cls in [Submission, Comment]):
- id = target.author_id
- elif isinstance(target, User):
- id = target.id
- else:
- raise TypeError("add_block_props only supports non-None submissions, comments, and users")
-
- if hasattr(target, 'is_blocking') and hasattr(target, 'is_blocked'):
- return target
+ if any(isinstance(target, cls) for cls in [Submission, Comment]):
+ id = target.author_id
+ elif isinstance(target, User):
+ id = target.id
+ else:
+ raise TypeError("add_block_props only supports non-None submissions, comments, and users")
+
+ if hasattr(target, 'is_blocking') and hasattr(target, 'is_blocked'):
+ return target
- if v.id == id or id == AUTOJANNY_ID: # users can't block or be blocked by themselves or AutoJanny
- target.is_blocking = False
- target.is_blocked = False
- return target
+ if v.id == id or id == AUTOJANNY_ID: # users can't block or be blocked by themselves or AutoJanny
+ target.is_blocking = False
+ target.is_blocked = False
+ return target
- block = g.db.query(UserBlock).filter(
- or_(
- and_(
- UserBlock.user_id == v.id,
- UserBlock.target_id == id
- ),
- and_(
- UserBlock.user_id == id,
- UserBlock.target_id == v.id
- )
- )
- ).first()
- target.is_blocking = block and block.user_id == v.id
- target.is_blocked = block and block.target_id == v.id
- return target
+ block = g.db.query(UserBlock).filter(
+ or_(
+ and_(
+ UserBlock.user_id == v.id,
+ UserBlock.target_id == id
+ ),
+ and_(
+ UserBlock.user_id == id,
+ UserBlock.target_id == v.id
+ )
+ )
+ ).first()
+ target.is_blocking = block and block.user_id == v.id
+ target.is_blocked = block and block.target_id == v.id
+ return target
def add_vote_props(target:Union[Submission, Comment], v:Optional[User], vote_cls):
- if hasattr(target, 'voted'): return target
+ if hasattr(target, 'voted'): return target
- vt = g.db.query(vote_cls.vote_type).filter_by(user_id=v.id)
- if vote_cls == Vote:
- vt = vt.filter_by(submission_id=target.id)
- elif vote_cls == CommentVote:
- vt = vt.filter_by(comment_id=target.id)
- else:
- vt = None
- if vt: vt = vt.one_or_none()
- target.voted = vt.vote_type if vt else 0
- return target
+ vt = g.db.query(vote_cls.vote_type).filter_by(user_id=v.id)
+ if vote_cls == Vote:
+ vt = vt.filter_by(submission_id=target.id)
+ elif vote_cls == CommentVote:
+ vt = vt.filter_by(comment_id=target.id)
+ else:
+ vt = None
+ if vt: vt = vt.one_or_none()
+ target.voted = vt.vote_type if vt else 0
+ return target
def add_vote_and_block_props(target:Union[Submission, Comment], v:Optional[User], vote_cls):
- if not v: return target
- target = add_block_props(target, v)
- return add_vote_props(target, v, vote_cls)
+ if not v: return target
+ target = add_block_props(target, v)
+ return add_vote_props(target, v, vote_cls)
def get_comments(cids:Iterable[int], v:Optional[User]=None) -> List[Comment]:
if not cids: return []
diff --git a/files/helpers/roulette.py b/files/helpers/roulette.py
index 6feccd733..f658e5cf3 100644
--- a/files/helpers/roulette.py
+++ b/files/helpers/roulette.py
@@ -8,290 +8,290 @@ from flask import g
class RouletteAction(str, Enum):
- STRAIGHT_UP_BET = "STRAIGHT_UP_BET"
- LINE_BET = "LINE_BET"
- COLUMN_BET = "COLUMN_BET"
- DOZEN_BET = "DOZEN_BET"
- EVEN_ODD_BET = "EVEN_ODD_BET"
- RED_BLACK_BET = "RED_BLACK_BET"
- HIGH_LOW_BET = "HIGH_LOW_BET"
+ STRAIGHT_UP_BET = "STRAIGHT_UP_BET"
+ LINE_BET = "LINE_BET"
+ COLUMN_BET = "COLUMN_BET"
+ DOZEN_BET = "DOZEN_BET"
+ EVEN_ODD_BET = "EVEN_ODD_BET"
+ RED_BLACK_BET = "RED_BLACK_BET"
+ HIGH_LOW_BET = "HIGH_LOW_BET"
class RouletteEvenOdd(str, Enum):
- EVEN = "EVEN"
- ODD = "ODD"
+ EVEN = "EVEN"
+ ODD = "ODD"
class RouletteRedBlack(str, Enum):
- RED = "RED"
- BLACK = "BLACK"
+ RED = "RED"
+ BLACK = "BLACK"
class RouletteHighLow(str, Enum):
- HIGH = "HIGH"
- LOW = "LOW"
+ HIGH = "HIGH"
+ LOW = "LOW"
REDS = (1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36)
BLACKS = (2, 4, 6, 8, 10, 11, 13, 15, 17, 20, 22, 24, 26, 28, 29, 31, 33, 35)
LINES = {
- 1: (1, 2, 3, 4, 5, 6),
- 2: (7, 8, 9, 10, 11, 12),
- 3: (13, 14, 15, 16, 17, 18),
- 4: (19, 20, 21, 22, 23, 24),
- 5: (25, 26, 27, 28, 29, 30),
- 6: (31, 32, 33, 34, 35, 36)
+ 1: (1, 2, 3, 4, 5, 6),
+ 2: (7, 8, 9, 10, 11, 12),
+ 3: (13, 14, 15, 16, 17, 18),
+ 4: (19, 20, 21, 22, 23, 24),
+ 5: (25, 26, 27, 28, 29, 30),
+ 6: (31, 32, 33, 34, 35, 36)
}
COLUMNS = {
- 1: (1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34),
- 2: (2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35),
- 3: (3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36)
+ 1: (1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34),
+ 2: (2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35),
+ 3: (3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36)
}
DOZENS = {
- 1: (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12),
- 2: (13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24),
- 3: (25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36)
+ 1: (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12),
+ 2: (13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24),
+ 3: (25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36)
}
PAYOUT_MULITPLIERS = {
- RouletteAction.STRAIGHT_UP_BET: 35,
- RouletteAction.LINE_BET: 5,
- RouletteAction.COLUMN_BET: 2,
- RouletteAction.DOZEN_BET: 2,
- RouletteAction.EVEN_ODD_BET: 1,
- RouletteAction.RED_BLACK_BET: 1,
- RouletteAction.HIGH_LOW_BET: 1,
+ RouletteAction.STRAIGHT_UP_BET: 35,
+ RouletteAction.LINE_BET: 5,
+ RouletteAction.COLUMN_BET: 2,
+ RouletteAction.DOZEN_BET: 2,
+ RouletteAction.EVEN_ODD_BET: 1,
+ RouletteAction.RED_BLACK_BET: 1,
+ RouletteAction.HIGH_LOW_BET: 1,
}
def get_active_roulette_games():
- return g.db.query(Casino_Game).filter(
- Casino_Game.active == True,
- Casino_Game.kind == 'roulette'
- ).all()
+ return g.db.query(Casino_Game).filter(
+ Casino_Game.active == True,
+ Casino_Game.kind == 'roulette'
+ ).all()
def charge_gambler(gambler, amount, currency):
- charged = gambler.charge_account(currency, amount)
+ charged = gambler.charge_account(currency, amount)
- if not charged:
- raise Exception("Gambler cannot afford charge.")
+ if not charged:
+ raise Exception("Gambler cannot afford charge.")
def gambler_placed_roulette_bet(gambler, bet, which, amount, currency):
- if not bet in (
- RouletteAction.STRAIGHT_UP_BET,
- RouletteAction.LINE_BET,
- RouletteAction.COLUMN_BET,
- RouletteAction.DOZEN_BET,
- RouletteAction.EVEN_ODD_BET,
- RouletteAction.RED_BLACK_BET,
- RouletteAction.HIGH_LOW_BET
- ):
- raise Exception(
- f'Illegal bet {bet} passed to Roulette#gambler_placed_roulette_bet')
+ if not bet in (
+ RouletteAction.STRAIGHT_UP_BET,
+ RouletteAction.LINE_BET,
+ RouletteAction.COLUMN_BET,
+ RouletteAction.DOZEN_BET,
+ RouletteAction.EVEN_ODD_BET,
+ RouletteAction.RED_BLACK_BET,
+ RouletteAction.HIGH_LOW_BET
+ ):
+ raise Exception(
+ f'Illegal bet {bet} passed to Roulette#gambler_placed_roulette_bet')
- active_games = get_active_roulette_games()
+ active_games = get_active_roulette_games()
- if len(active_games) == 0:
- parent_id = int(time.time())
- else:
- parent_id = json.loads(active_games[0].game_state)['parent_id']
+ if len(active_games) == 0:
+ parent_id = int(time.time())
+ else:
+ parent_id = json.loads(active_games[0].game_state)['parent_id']
- charge_gambler(gambler, amount, currency)
+ charge_gambler(gambler, amount, currency)
- game = Casino_Game()
- game.user_id = gambler.id
- game.currency = currency
- game.wager = amount
- game.winnings = 0
- game.kind = 'roulette'
- game.game_state = json.dumps(
- {"parent_id": parent_id, "bet": bet, "which": which})
- game.active = True
- g.db.add(game)
- g.db.commit()
+ game = Casino_Game()
+ game.user_id = gambler.id
+ game.currency = currency
+ game.wager = amount
+ game.winnings = 0
+ game.kind = 'roulette'
+ game.game_state = json.dumps(
+ {"parent_id": parent_id, "bet": bet, "which": which})
+ game.active = True
+ g.db.add(game)
+ g.db.commit()
def get_roulette_bets_and_betters():
- participants = []
- bets = {
- RouletteAction.STRAIGHT_UP_BET: [],
- RouletteAction.LINE_BET: [],
- RouletteAction.COLUMN_BET: [],
- RouletteAction.DOZEN_BET: [],
- RouletteAction.EVEN_ODD_BET: [],
- RouletteAction.RED_BLACK_BET: [],
- RouletteAction.HIGH_LOW_BET: [],
- }
- active_games = get_active_roulette_games()
+ participants = []
+ bets = {
+ RouletteAction.STRAIGHT_UP_BET: [],
+ RouletteAction.LINE_BET: [],
+ RouletteAction.COLUMN_BET: [],
+ RouletteAction.DOZEN_BET: [],
+ RouletteAction.EVEN_ODD_BET: [],
+ RouletteAction.RED_BLACK_BET: [],
+ RouletteAction.HIGH_LOW_BET: [],
+ }
+ active_games = get_active_roulette_games()
- for game in active_games:
- if not game.user_id in participants:
- participants.append(game.user_id)
+ for game in active_games:
+ if not game.user_id in participants:
+ participants.append(game.user_id)
- user = get_account(game.user_id)
- game_state = json.loads(game.game_state)
- bet = game_state['bet']
- bets[bet].append({
- 'game_id': game.id,
- 'gambler': game.user_id,
- 'gambler_username': user.username,
- 'gambler_profile_url': user.profile_url,
- 'bet': bet,
- 'which': game_state['which'],
- 'wager': {
- 'amount': game.wager,
- 'currency': game.currency
- }
- })
+ user = get_account(game.user_id)
+ game_state = json.loads(game.game_state)
+ bet = game_state['bet']
+ bets[bet].append({
+ 'game_id': game.id,
+ 'gambler': game.user_id,
+ 'gambler_username': user.username,
+ 'gambler_profile_url': user.profile_url,
+ 'bet': bet,
+ 'which': game_state['which'],
+ 'wager': {
+ 'amount': game.wager,
+ 'currency': game.currency
+ }
+ })
- return participants, bets, active_games
+ return participants, bets, active_games
def spin_roulette_wheel():
- participants, bets, active_games = get_roulette_bets_and_betters()
+ participants, bets, active_games = get_roulette_bets_and_betters()
- if len(participants) > 0:
- number = randint(0, 37) # 37 is 00
+ if len(participants) > 0:
+ number = randint(0, 37) # 37 is 00
- if number > 0 and number < 37: # 0 and 00 do not pay anything
- winners, payouts, rewards_by_game_id = determine_roulette_winners(number, bets)
- else:
- winners = []
- payouts = {}
- rewards_by_game_id = {}
+ if number > 0 and number < 37: # 0 and 00 do not pay anything
+ winners, payouts, rewards_by_game_id = determine_roulette_winners(number, bets)
+ else:
+ winners = []
+ payouts = {}
+ rewards_by_game_id = {}
- # Pay out to the winners and send a notification.
- for user_id in winners:
- gambler = get_account(user_id)
- gambler_payout = payouts[user_id]
- coin_winnings = gambler_payout['coins']
- procoin_winnings = gambler_payout['procoins']
+ # Pay out to the winners and send a notification.
+ for user_id in winners:
+ gambler = get_account(user_id)
+ gambler_payout = payouts[user_id]
+ coin_winnings = gambler_payout['coins']
+ procoin_winnings = gambler_payout['procoins']
- gambler.pay_account('coins', coin_winnings)
- gambler.pay_account('procoins', procoin_winnings)
+ gambler.pay_account('coins', coin_winnings)
+ gambler.pay_account('procoins', procoin_winnings)
- # Notify the winners.
- notification_text = f"Winning number: {number}\nCongratulations! One or more of your roulette bets paid off!\n"
+ # Notify the winners.
+ notification_text = f"Winning number: {number}\nCongratulations! One or more of your roulette bets paid off!\n"
- if coin_winnings > 0:
- notification_text = notification_text + \
- f"* You received {coin_winnings} coins.\n"
+ if coin_winnings > 0:
+ notification_text = notification_text + \
+ f"* You received {coin_winnings} coins.\n"
- if procoin_winnings > 0:
- notification_text = notification_text + \
- f"* You received {procoin_winnings} marseybux.\n"
+ if procoin_winnings > 0:
+ notification_text = notification_text + \
+ f"* You received {procoin_winnings} marseybux.\n"
- send_repeatable_notification(user_id, notification_text)
+ send_repeatable_notification(user_id, notification_text)
- # Give condolences.
- for participant in participants:
- if not participant in winners:
- send_repeatable_notification(
- participant, f"Winning number: {number}\nSorry, none of your recent roulette bets paid off.")
+ # Give condolences.
+ for participant in participants:
+ if not participant in winners:
+ send_repeatable_notification(
+ participant, f"Winning number: {number}\nSorry, none of your recent roulette bets paid off.")
- g.db.flush()
+ g.db.flush()
- # Adjust game winnings.
- for game in active_games:
- if rewards_by_game_id.get(game.id):
- game.winnings = rewards_by_game_id[game.id]
- else:
- game.winnings = -game.wager
+ # Adjust game winnings.
+ for game in active_games:
+ if rewards_by_game_id.get(game.id):
+ game.winnings = rewards_by_game_id[game.id]
+ else:
+ game.winnings = -game.wager
- game.active = False
- g.db.add(game)
+ game.active = False
+ g.db.add(game)
- # Commit early when dirty because of long-running tasks after roulette
- g.db.commit()
+ # Commit early when dirty because of long-running tasks after roulette
+ g.db.commit()
def determine_roulette_winners(number, bets):
- winners = []
- payouts = {}
- rewards_by_game_id = {}
+ winners = []
+ payouts = {}
+ rewards_by_game_id = {}
- def add_to_winnings(bet):
- game_id = int(bet['game_id'])
- gambler_id = bet['gambler']
- wager_amount = bet['wager']['amount']
- bet_kind = bet['bet']
- reward = wager_amount * PAYOUT_MULITPLIERS[bet_kind]
- payout = wager_amount + reward
- currency = bet['wager']['currency']
+ def add_to_winnings(bet):
+ game_id = int(bet['game_id'])
+ gambler_id = bet['gambler']
+ wager_amount = bet['wager']['amount']
+ bet_kind = bet['bet']
+ reward = wager_amount * PAYOUT_MULITPLIERS[bet_kind]
+ payout = wager_amount + reward
+ currency = bet['wager']['currency']
- if not gambler_id in winners:
- winners.append(gambler_id)
+ if not gambler_id in winners:
+ winners.append(gambler_id)
- if not payouts.get(gambler_id):
- payouts[gambler_id] = {
- 'coins': 0,
- 'procoins': 0
- }
+ if not payouts.get(gambler_id):
+ payouts[gambler_id] = {
+ 'coins': 0,
+ 'procoins': 0
+ }
- if not rewards_by_game_id.get(game_id):
- rewards_by_game_id[game_id] = reward
+ if not rewards_by_game_id.get(game_id):
+ rewards_by_game_id[game_id] = reward
- payouts[gambler_id][currency] += payout
+ payouts[gambler_id][currency] += payout
- # Straight-Up Bet
- for bet in bets[RouletteAction.STRAIGHT_UP_BET]:
- if int(bet['which']) == number:
- add_to_winnings(bet)
+ # Straight-Up Bet
+ for bet in bets[RouletteAction.STRAIGHT_UP_BET]:
+ if int(bet['which']) == number:
+ add_to_winnings(bet)
- # Line Bet
- line = -1
- for i in range(1, 7):
- if number in LINES[i]:
- line = i
+ # Line Bet
+ line = -1
+ for i in range(1, 7):
+ if number in LINES[i]:
+ line = i
- for bet in bets[RouletteAction.LINE_BET]:
- if int(bet['which']) == line:
- add_to_winnings(bet)
+ for bet in bets[RouletteAction.LINE_BET]:
+ if int(bet['which']) == line:
+ add_to_winnings(bet)
- # Column Bet
- column = -1
- for i in range(1, 4):
- if number in COLUMNS[i]:
- column = i
+ # Column Bet
+ column = -1
+ for i in range(1, 4):
+ if number in COLUMNS[i]:
+ column = i
- for bet in bets[RouletteAction.COLUMN_BET]:
- if int(bet['which']) == column:
- add_to_winnings(bet)
+ for bet in bets[RouletteAction.COLUMN_BET]:
+ if int(bet['which']) == column:
+ add_to_winnings(bet)
- # Dozen Bet
- dozen = -1
- for i in range(1, 4):
- if number in DOZENS[i]:
- dozen = i
+ # Dozen Bet
+ dozen = -1
+ for i in range(1, 4):
+ if number in DOZENS[i]:
+ dozen = i
- for bet in bets[RouletteAction.DOZEN_BET]:
- if int(bet['which']) == dozen:
- add_to_winnings(bet)
+ for bet in bets[RouletteAction.DOZEN_BET]:
+ if int(bet['which']) == dozen:
+ add_to_winnings(bet)
- # Even/Odd Bet
- even_odd = RouletteEvenOdd.EVEN if number % 2 == 0 else RouletteEvenOdd.ODD
+ # Even/Odd Bet
+ even_odd = RouletteEvenOdd.EVEN if number % 2 == 0 else RouletteEvenOdd.ODD
- for bet in bets[RouletteAction.EVEN_ODD_BET]:
- if bet['which'] == even_odd:
- add_to_winnings(bet)
+ for bet in bets[RouletteAction.EVEN_ODD_BET]:
+ if bet['which'] == even_odd:
+ add_to_winnings(bet)
- # Red/Black Bet
- red_black = RouletteRedBlack.RED if number in REDS else RouletteRedBlack.BLACK
+ # Red/Black Bet
+ red_black = RouletteRedBlack.RED if number in REDS else RouletteRedBlack.BLACK
- for bet in bets[RouletteAction.RED_BLACK_BET]:
- if bet['which'] == red_black:
- add_to_winnings(bet)
+ for bet in bets[RouletteAction.RED_BLACK_BET]:
+ if bet['which'] == red_black:
+ add_to_winnings(bet)
- # High/Low Bet
- high_low = RouletteHighLow.HIGH if number > 18 else RouletteHighLow.LOW
+ # High/Low Bet
+ high_low = RouletteHighLow.HIGH if number > 18 else RouletteHighLow.LOW
- for bet in bets[RouletteAction.HIGH_LOW_BET]:
- if bet['which'] == high_low:
- add_to_winnings(bet)
+ for bet in bets[RouletteAction.HIGH_LOW_BET]:
+ if bet['which'] == high_low:
+ add_to_winnings(bet)
- return winners, payouts, rewards_by_game_id
+ return winners, payouts, rewards_by_game_id
def get_roulette_bets():
- return get_roulette_bets_and_betters()[1]
+ return get_roulette_bets_and_betters()[1]
diff --git a/files/helpers/twentyone.py b/files/helpers/twentyone.py
index 4990068da..8a6c2c4ad 100644
--- a/files/helpers/twentyone.py
+++ b/files/helpers/twentyone.py
@@ -8,20 +8,20 @@ from flask import g
class BlackjackStatus(str, Enum):
- PLAYING = "PLAYING"
- STAYED = "STAYED"
- PUSHED = "PUSHED"
- WON = "WON"
- LOST = "LOST"
- BLACKJACK = "BLACKJACK"
+ PLAYING = "PLAYING"
+ STAYED = "STAYED"
+ PUSHED = "PUSHED"
+ WON = "WON"
+ LOST = "LOST"
+ BLACKJACK = "BLACKJACK"
class BlackjackAction(str, Enum):
- DEAL = "DEAL"
- HIT = "HIT"
- STAY = "STAY"
- DOUBLE_DOWN = "DOUBLE_DOWN"
- BUY_INSURANCE = "BUY_INSURANCE"
+ DEAL = "DEAL"
+ HIT = "HIT"
+ STAY = "STAY"
+ DOUBLE_DOWN = "DOUBLE_DOWN"
+ BUY_INSURANCE = "BUY_INSURANCE"
ranks = ("2", "3", "4", "5", "6", "7", "8", "9", "X", "J", "Q", "K", "A")
@@ -32,350 +32,350 @@ minimum_bet = 5
def get_initial_state():
- return {
- "player": [],
- "player_value": 0,
- "dealer": [],
- "dealer_value": 0,
- "player_bought_insurance": False,
- "player_doubled_down": False,
- "status": BlackjackStatus.PLAYING,
- "actions": [BlackjackAction.DEAL],
- "wager": {
- "amount": 0,
- "currency": "coins"
- },
- "payout": 0
- }
+ return {
+ "player": [],
+ "player_value": 0,
+ "dealer": [],
+ "dealer_value": 0,
+ "player_bought_insurance": False,
+ "player_doubled_down": False,
+ "status": BlackjackStatus.PLAYING,
+ "actions": [BlackjackAction.DEAL],
+ "wager": {
+ "amount": 0,
+ "currency": "coins"
+ },
+ "payout": 0
+ }
def build_casino_game(gambler, wager, currency):
- initial_state = get_initial_state()
- initial_state['wager']['amount'] = wager
- initial_state['wager']['currency'] = currency
+ initial_state = get_initial_state()
+ initial_state['wager']['amount'] = wager
+ initial_state['wager']['currency'] = currency
- casino_game = Casino_Game()
- casino_game.user_id = gambler.id
- casino_game.currency = currency
- casino_game.wager = wager
- casino_game.winnings = 0
- casino_game.kind = 'blackjack'
- casino_game.game_state = json.dumps(initial_state)
- casino_game.active = True
- g.db.add(casino_game)
+ casino_game = Casino_Game()
+ casino_game.user_id = gambler.id
+ casino_game.currency = currency
+ casino_game.wager = wager
+ casino_game.winnings = 0
+ casino_game.kind = 'blackjack'
+ casino_game.game_state = json.dumps(initial_state)
+ casino_game.active = True
+ g.db.add(casino_game)
- return casino_game
+ return casino_game
def get_active_twentyone_game(gambler):
- return g.db.query(Casino_Game).filter(
- Casino_Game.active == True,
- Casino_Game.kind == 'blackjack',
- Casino_Game.user_id == gambler.id).first()
+ return g.db.query(Casino_Game).filter(
+ Casino_Game.active == True,
+ Casino_Game.kind == 'blackjack',
+ Casino_Game.user_id == gambler.id).first()
def get_active_twentyone_game_state(gambler):
- active_game = get_active_twentyone_game(gambler)
- full_state = json.loads(active_game.game_state)
- return remove_exploitable_information(full_state)
+ active_game = get_active_twentyone_game(gambler)
+ full_state = json.loads(active_game.game_state)
+ return remove_exploitable_information(full_state)
def charge_gambler(gambler, amount, currency):
- charged = gambler.charge_account(currency, amount)
-
- if not charged:
- raise Exception("Gambler cannot afford charge.")
+ charged = gambler.charge_account(currency, amount)
+
+ if not charged:
+ raise Exception("Gambler cannot afford charge.")
def create_new_game(gambler, wager, currency):
- existing_game = get_active_twentyone_game(gambler)
- over_minimum_bet = wager >= minimum_bet
+ existing_game = get_active_twentyone_game(gambler)
+ over_minimum_bet = wager >= minimum_bet
- if existing_game:
- raise Exception("Gambler already has a game in progress.")
+ if existing_game:
+ raise Exception("Gambler already has a game in progress.")
- if not over_minimum_bet:
- raise Exception(f"Gambler must bet over {minimum_bet} {currency}.")
+ if not over_minimum_bet:
+ raise Exception(f"Gambler must bet over {minimum_bet} {currency}.")
- try:
- charge_gambler(gambler, wager, currency)
- new_game = build_casino_game(gambler, wager, currency)
- g.db.add(new_game)
- g.db.commit()
- except:
- raise Exception(f"Gambler cannot afford to bet {wager} {currency}.")
+ try:
+ charge_gambler(gambler, wager, currency)
+ new_game = build_casino_game(gambler, wager, currency)
+ g.db.add(new_game)
+ g.db.commit()
+ except:
+ raise Exception(f"Gambler cannot afford to bet {wager} {currency}.")
def handle_blackjack_deal(state):
- deck = build_deck(state)
- first = deck.pop()
- second = deck.pop()
- third = deck.pop()
- fourth = deck.pop()
- state['player'] = [first, third]
- state['dealer'] = [second, fourth]
+ deck = build_deck(state)
+ first = deck.pop()
+ second = deck.pop()
+ third = deck.pop()
+ fourth = deck.pop()
+ state['player'] = [first, third]
+ state['dealer'] = [second, fourth]
- return state
+ return state
def handle_blackjack_hit(state):
- deck = build_deck(state)
- next_card = deck.pop()
- state['player'].append(next_card)
+ deck = build_deck(state)
+ next_card = deck.pop()
+ state['player'].append(next_card)
- return state
+ return state
def handle_blackjack_stay(state):
- state['status'] = BlackjackStatus.STAYED
+ state['status'] = BlackjackStatus.STAYED
- return state
+ return state
def handle_blackjack_double_down(state):
- state['player_doubled_down'] = True
- state = handle_blackjack_hit(state)
- state = handle_blackjack_stay(state)
+ state['player_doubled_down'] = True
+ state = handle_blackjack_hit(state)
+ state = handle_blackjack_stay(state)
- return state
+ return state
def handle_blackjack_buy_insurance(state):
- state['player_bought_insurance'] = True
+ state['player_bought_insurance'] = True
- return state
+ return state
def check_for_completion(state):
- after_initial_deal = len(
- state['player']) == 2 and len(state['dealer']) == 2
- player_hand_value = get_value_of_hand(state['player'])
- dealer_hand_value = get_value_of_hand(state['dealer'])
+ after_initial_deal = len(
+ state['player']) == 2 and len(state['dealer']) == 2
+ player_hand_value = get_value_of_hand(state['player'])
+ dealer_hand_value = get_value_of_hand(state['dealer'])
- # Both player and dealer were initially dealt 21: Push.
- if after_initial_deal and player_hand_value == 21 and dealer_hand_value == 21:
- state['status'] = BlackjackStatus.PUSHED
- return True, state
+ # Both player and dealer were initially dealt 21: Push.
+ if after_initial_deal and player_hand_value == 21 and dealer_hand_value == 21:
+ state['status'] = BlackjackStatus.PUSHED
+ return True, state
- # Player was originally dealt 21, dealer was not: Blackjack.
- if after_initial_deal and player_hand_value == 21:
- state['status'] = BlackjackStatus.BLACKJACK
- return True, state
+ # Player was originally dealt 21, dealer was not: Blackjack.
+ if after_initial_deal and player_hand_value == 21:
+ state['status'] = BlackjackStatus.BLACKJACK
+ return True, state
- # Player went bust: Lost.
- if player_hand_value == -1:
- state['status'] = BlackjackStatus.LOST
- return True, state
+ # Player went bust: Lost.
+ if player_hand_value == -1:
+ state['status'] = BlackjackStatus.LOST
+ return True, state
- # Player chose to stay: Deal rest for dealer then determine winner.
- if state['status'] == BlackjackStatus.STAYED:
- deck = build_deck(state)
+ # Player chose to stay: Deal rest for dealer then determine winner.
+ if state['status'] == BlackjackStatus.STAYED:
+ deck = build_deck(state)
- while dealer_hand_value < 17 and dealer_hand_value != -1:
- next_card = deck.pop()
- state['dealer'].append(next_card)
- dealer_hand_value = get_value_of_hand(state['dealer'])
+ while dealer_hand_value < 17 and dealer_hand_value != -1:
+ next_card = deck.pop()
+ state['dealer'].append(next_card)
+ dealer_hand_value = get_value_of_hand(state['dealer'])
- if player_hand_value > dealer_hand_value or dealer_hand_value == -1:
- state['status'] = BlackjackStatus.WON
- elif dealer_hand_value > player_hand_value:
- state['status'] = BlackjackStatus.LOST
- else:
- state['status'] = BlackjackStatus.PUSHED
+ if player_hand_value > dealer_hand_value or dealer_hand_value == -1:
+ state['status'] = BlackjackStatus.WON
+ elif dealer_hand_value > player_hand_value:
+ state['status'] = BlackjackStatus.LOST
+ else:
+ state['status'] = BlackjackStatus.PUSHED
- state['player_value'] = get_value_of_hand(state['player'])
- state['dealer_value'] = get_value_of_hand(state['dealer'])
+ state['player_value'] = get_value_of_hand(state['player'])
+ state['dealer_value'] = get_value_of_hand(state['dealer'])
- return True, state
+ return True, state
- return False, state
+ return False, state
def does_insurance_apply(state):
- dealer = state['dealer']
- dealer_hand_value = get_value_of_hand(dealer)
- dealer_first_card_ace = dealer[0][0] == 'A'
- dealer_never_hit = len(dealer) == 2
- return dealer_hand_value == 21 and dealer_first_card_ace and dealer_never_hit
+ dealer = state['dealer']
+ dealer_hand_value = get_value_of_hand(dealer)
+ dealer_first_card_ace = dealer[0][0] == 'A'
+ dealer_never_hit = len(dealer) == 2
+ return dealer_hand_value == 21 and dealer_first_card_ace and dealer_never_hit
def can_purchase_insurance(state):
- dealer = state['dealer']
- dealer_first_card_ace = dealer[0][0] == 'A'
- dealer_never_hit = len(dealer) == 2
- return dealer_first_card_ace and dealer_never_hit and not state['player_bought_insurance']
+ dealer = state['dealer']
+ dealer_first_card_ace = dealer[0][0] == 'A'
+ dealer_never_hit = len(dealer) == 2
+ return dealer_first_card_ace and dealer_never_hit and not state['player_bought_insurance']
def can_double_down(state):
- player = state['player']
- player_hand_value = get_value_of_hand(player)
- player_never_hit = len(player) == 2
- return player_hand_value in (10, 11) and player_never_hit
+ player = state['player']
+ player_hand_value = get_value_of_hand(player)
+ player_never_hit = len(player) == 2
+ return player_hand_value in (10, 11) and player_never_hit
def handle_payout(gambler, state, game):
- status = state['status']
- payout = 0
+ status = state['status']
+ payout = 0
- if status == BlackjackStatus.BLACKJACK:
- game.winnings = floor(game.wager * 3/2)
- payout = game.wager + game.winnings
- elif status == BlackjackStatus.WON:
- game.winnings = game.wager
- payout = game.wager * 2
- elif status == BlackjackStatus.LOST:
- dealer = state['dealer']
- dealer_first_card_ace = dealer[0][0] == 'A'
- dealer_never_hit = len(dealer) == 2
- dealer_hand_value = get_value_of_hand(dealer) == 21
- insurance_applies = dealer_hand_value == 21 and dealer_first_card_ace and dealer_never_hit
+ if status == BlackjackStatus.BLACKJACK:
+ game.winnings = floor(game.wager * 3/2)
+ payout = game.wager + game.winnings
+ elif status == BlackjackStatus.WON:
+ game.winnings = game.wager
+ payout = game.wager * 2
+ elif status == BlackjackStatus.LOST:
+ dealer = state['dealer']
+ dealer_first_card_ace = dealer[0][0] == 'A'
+ dealer_never_hit = len(dealer) == 2
+ dealer_hand_value = get_value_of_hand(dealer) == 21
+ insurance_applies = dealer_hand_value == 21 and dealer_first_card_ace and dealer_never_hit
- if insurance_applies and state['player_bought_insurance']:
- game.winnings = 0
- payout = game.wager
- else:
- game.winnings = -game.wager
- payout = 0
- elif status == BlackjackStatus.PUSHED:
- game.winnings = 0
- payout = game.wager
- else:
- raise Exception("Attempted to payout a game that has not finished.")
+ if insurance_applies and state['player_bought_insurance']:
+ game.winnings = 0
+ payout = game.wager
+ else:
+ game.winnings = -game.wager
+ payout = 0
+ elif status == BlackjackStatus.PUSHED:
+ game.winnings = 0
+ payout = game.wager
+ else:
+ raise Exception("Attempted to payout a game that has not finished.")
- gambler.pay_account(game.currency, payout)
-
- if game.currency == 'coins':
- if status in (BlackjackStatus.BLACKJACK, BlackjackStatus.WON):
- distribute_wager_badges(gambler, game.wager, won=True)
- elif status == BlackjackStatus.LOST:
- distribute_wager_badges(gambler, game.wager, won=False)
+ gambler.pay_account(game.currency, payout)
+
+ if game.currency == 'coins':
+ if status in (BlackjackStatus.BLACKJACK, BlackjackStatus.WON):
+ distribute_wager_badges(gambler, game.wager, won=True)
+ elif status == BlackjackStatus.LOST:
+ distribute_wager_badges(gambler, game.wager, won=False)
- game.active = False
- g.db.add(game)
+ game.active = False
+ g.db.add(game)
- return payout
+ return payout
def remove_exploitable_information(state):
- safe_state = state
-
- if len(safe_state['dealer']) >= 2:
- safe_state['dealer'][1] = '?'
+ safe_state = state
+
+ if len(safe_state['dealer']) >= 2:
+ safe_state['dealer'][1] = '?'
- safe_state['dealer_value'] = '?'
- return safe_state
+ safe_state['dealer_value'] = '?'
+ return safe_state
action_handlers = {
- BlackjackAction.DEAL: handle_blackjack_deal,
- BlackjackAction.HIT: handle_blackjack_hit,
- BlackjackAction.STAY: handle_blackjack_stay,
- BlackjackAction.DOUBLE_DOWN: handle_blackjack_double_down,
- BlackjackAction.BUY_INSURANCE: handle_blackjack_buy_insurance,
+ BlackjackAction.DEAL: handle_blackjack_deal,
+ BlackjackAction.HIT: handle_blackjack_hit,
+ BlackjackAction.STAY: handle_blackjack_stay,
+ BlackjackAction.DOUBLE_DOWN: handle_blackjack_double_down,
+ BlackjackAction.BUY_INSURANCE: handle_blackjack_buy_insurance,
}
def dispatch_action(gambler, action):
- game = get_active_twentyone_game(gambler)
- handler = action_handlers[action]
+ game = get_active_twentyone_game(gambler)
+ handler = action_handlers[action]
- if not game:
- raise Exception(
- 'Gambler has no active blackjack game.')
- if not handler:
- raise Exception(
- f'Illegal action {action} passed to Blackjack#dispatch_action.')
+ if not game:
+ raise Exception(
+ 'Gambler has no active blackjack game.')
+ if not handler:
+ raise Exception(
+ f'Illegal action {action} passed to Blackjack#dispatch_action.')
- state = json.loads(game.game_state)
+ state = json.loads(game.game_state)
- if action == BlackjackAction.BUY_INSURANCE:
- if not can_purchase_insurance(state):
- raise Exception("Insurance cannot be purchased.")
+ if action == BlackjackAction.BUY_INSURANCE:
+ if not can_purchase_insurance(state):
+ raise Exception("Insurance cannot be purchased.")
- charge_gambler(gambler, floor(game.wager / 2), game.currency)
- if action == BlackjackAction.DOUBLE_DOWN:
- if not can_double_down(state):
- raise Exception("Cannot double down.")
+ charge_gambler(gambler, floor(game.wager / 2), game.currency)
+ if action == BlackjackAction.DOUBLE_DOWN:
+ if not can_double_down(state):
+ raise Exception("Cannot double down.")
- charge_gambler(gambler, game.wager, game.currency)
- game.wager *= 2
+ charge_gambler(gambler, game.wager, game.currency)
+ game.wager *= 2
- new_state = handler(state)
- new_state['player_value'] = get_value_of_hand(new_state['player'])
- new_state['dealer_value'] = get_value_of_hand(new_state['dealer'])
- new_state['actions'] = get_available_actions(new_state)
+ new_state = handler(state)
+ new_state['player_value'] = get_value_of_hand(new_state['player'])
+ new_state['dealer_value'] = get_value_of_hand(new_state['dealer'])
+ new_state['actions'] = get_available_actions(new_state)
- game.game_state = json.dumps(new_state)
- g.db.add(game)
+ game.game_state = json.dumps(new_state)
+ g.db.add(game)
- game_over, final_state = check_for_completion(new_state)
+ game_over, final_state = check_for_completion(new_state)
- if game_over:
- payout = handle_payout(gambler, final_state, game)
- final_state['actions'] = [BlackjackAction.DEAL]
- final_state['payout'] = payout
- return final_state
- else:
- safe_state = remove_exploitable_information(new_state)
- return safe_state
+ if game_over:
+ payout = handle_payout(gambler, final_state, game)
+ final_state['actions'] = [BlackjackAction.DEAL]
+ final_state['payout'] = payout
+ return final_state
+ else:
+ safe_state = remove_exploitable_information(new_state)
+ return safe_state
def shuffle(collection):
- random.shuffle(collection)
- return collection
+ random.shuffle(collection)
+ return collection
def build_deck(state):
- card_counts = {}
+ card_counts = {}
- for card in deck:
- card_counts[card] = deck_count
+ for card in deck:
+ card_counts[card] = deck_count
- cards_already_dealt = state['player'].copy()
- cards_already_dealt.extend(state['dealer'].copy())
+ cards_already_dealt = state['player'].copy()
+ cards_already_dealt.extend(state['dealer'].copy())
- for card in cards_already_dealt:
- card_counts[card] = card_counts[card] - 1
+ for card in cards_already_dealt:
+ card_counts[card] = card_counts[card] - 1
- deck_without_already_dealt_cards = []
+ deck_without_already_dealt_cards = []
- for card in deck:
- amount = card_counts[card]
+ for card in deck:
+ amount = card_counts[card]
- for _ in range(amount):
- deck_without_already_dealt_cards.append(card)
+ for _ in range(amount):
+ deck_without_already_dealt_cards.append(card)
- return shuffle(deck_without_already_dealt_cards)
+ return shuffle(deck_without_already_dealt_cards)
def get_value_of_card(card):
- rank = card[0]
- return 0 if rank == "A" else min(ranks.index(rank) + 2, 10)
+ rank = card[0]
+ return 0 if rank == "A" else min(ranks.index(rank) + 2, 10)
def get_value_of_hand(hand):
- without_aces = sum(map(get_value_of_card, hand))
- ace_count = sum("A" in c for c in hand)
- possibilities = []
+ without_aces = sum(map(get_value_of_card, hand))
+ ace_count = sum("A" in c for c in hand)
+ possibilities = []
- for i in range(ace_count + 1):
- value = without_aces + (ace_count - i) + i * 11
- possibilities.append(-1 if value > 21 else value)
+ for i in range(ace_count + 1):
+ value = without_aces + (ace_count - i) + i * 11
+ possibilities.append(-1 if value > 21 else value)
- return max(possibilities)
+ return max(possibilities)
def get_available_actions(state):
- actions = []
+ actions = []
- if state['status'] == BlackjackStatus.PLAYING:
- actions.append(BlackjackAction.HIT)
- actions.append(BlackjackAction.STAY)
+ if state['status'] == BlackjackStatus.PLAYING:
+ actions.append(BlackjackAction.HIT)
+ actions.append(BlackjackAction.STAY)
- if can_double_down(state):
- actions.append(BlackjackAction.DOUBLE_DOWN)
+ if can_double_down(state):
+ actions.append(BlackjackAction.DOUBLE_DOWN)
- if can_purchase_insurance(state):
- actions.append(BlackjackAction.BUY_INSURANCE)
+ if can_purchase_insurance(state):
+ actions.append(BlackjackAction.BUY_INSURANCE)
- return actions
+ return actions
diff --git a/files/routes/casino.py b/files/routes/casino.py
index 3908e185f..b51fb1617 100644
--- a/files/routes/casino.py
+++ b/files/routes/casino.py
@@ -16,10 +16,10 @@ from files.helpers.lottery import *
@auth_required
@feature_required('GAMBLING')
def casino(v):
- if v.rehab:
- return render_template("casino/rehab.html", v=v)
+ if v.rehab:
+ return render_template("casino/rehab.html", v=v)
- return render_template("casino.html", v=v)
+ return render_template("casino.html", v=v)
@app.get("/casino/")
@@ -27,27 +27,27 @@ def casino(v):
@auth_required
@feature_required('GAMBLING')
def casino_game_page(v, game):
- if v.rehab:
- return render_template("casino/rehab.html", v=v)
- elif game not in CASINO_GAME_KINDS:
- abort(404)
+ if v.rehab:
+ return render_template("casino/rehab.html", v=v)
+ elif game not in CASINO_GAME_KINDS:
+ abort(404)
- feed = json.dumps(get_game_feed(game))
- leaderboard = json.dumps(get_game_leaderboard(game))
+ feed = json.dumps(get_game_feed(game))
+ leaderboard = json.dumps(get_game_leaderboard(game))
- game_state = ''
- if game == 'blackjack':
- if get_active_twentyone_game(v):
- game_state = json.dumps(get_active_twentyone_game_state(v))
+ game_state = ''
+ if game == 'blackjack':
+ if get_active_twentyone_game(v):
+ game_state = json.dumps(get_active_twentyone_game_state(v))
- return render_template(
- f"casino/{game}_screen.html",
- v=v,
- game=game,
- feed=feed,
- leaderboard=leaderboard,
- game_state=game_state
- )
+ return render_template(
+ f"casino/{game}_screen.html",
+ v=v,
+ game=game,
+ feed=feed,
+ leaderboard=leaderboard,
+ game_state=game_state
+ )
@app.get("/casino//feed")
@@ -55,13 +55,13 @@ def casino_game_page(v, game):
@auth_required
@feature_required('GAMBLING')
def casino_game_feed(v, game):
- if v.rehab:
- abort(403, "You are under Rehab award effect!")
- elif game not in CASINO_GAME_KINDS:
- abort(404)
+ if v.rehab:
+ abort(403, "You are under Rehab award effect!")
+ elif game not in CASINO_GAME_KINDS:
+ abort(404)
- feed = get_game_feed(game)
- return {"feed": feed}
+ feed = get_game_feed(game)
+ return {"feed": feed}
# Lottershe
@@ -70,11 +70,11 @@ def casino_game_feed(v, game):
@auth_required
@feature_required('GAMBLING')
def lottershe(v):
- if v.rehab:
- return render_template("casino/rehab.html", v=v)
+ if v.rehab:
+ return render_template("casino/rehab.html", v=v)
- participants = get_users_participating_in_lottery()
- return render_template("lottery.html", v=v, participants=participants)
+ participants = get_users_participating_in_lottery()
+ return render_template("lottery.html", v=v, participants=participants)
# Slots
@app.post("/casino/slots")
@@ -82,28 +82,28 @@ def lottershe(v):
@auth_required
@feature_required('GAMBLING')
def pull_slots(v):
- if v.rehab:
- abort(403, "You are under Rehab award effect!")
+ if v.rehab:
+ abort(403, "You are under Rehab award effect!")
- try:
- wager = int(request.values.get("wager"))
- except:
- abort(400, "Invalid wager.")
+ try:
+ wager = int(request.values.get("wager"))
+ except:
+ abort(400, "Invalid wager.")
- try:
- currency = request.values.get("currency")
- except:
- abort(400, "Invalid currency (expected 'coin' or 'marseybux').")
+ try:
+ currency = request.values.get("currency")
+ except:
+ abort(400, "Invalid currency (expected 'coin' or 'marseybux').")
- if (currency == "coin" and wager > v.coins) or (currency == "marseybux" and wager > v.procoins):
- abort(400, f"Not enough {currency} to make that bet")
+ if (currency == "coin" and wager > v.coins) or (currency == "marseybux" and wager > v.procoins):
+ abort(400, f"Not enough {currency} to make that bet")
- success, game_state = casino_slot_pull(v, wager, currency)
+ success, game_state = casino_slot_pull(v, wager, currency)
- if success:
- return {"game_state": game_state, "gambler": {"coins": v.coins, "procoins": v.procoins}}
- else:
- abort(400, f"Wager must be more than 5 {currency}")
+ if success:
+ return {"game_state": game_state, "gambler": {"coins": v.coins, "procoins": v.procoins}}
+ else:
+ abort(400, f"Wager must be more than 5 {currency}")
# 21
@@ -112,19 +112,19 @@ def pull_slots(v):
@auth_required
@feature_required('GAMBLING')
def blackjack_deal_to_player(v):
- if v.rehab:
- abort(403, "You are under Rehab award effect!")
+ if v.rehab:
+ abort(403, "You are under Rehab award effect!")
- try:
- wager = int(request.values.get("wager"))
- currency = request.values.get("currency")
- create_new_game(v, wager, currency)
- state = dispatch_action(v, BlackjackAction.DEAL)
- feed = get_game_feed('blackjack')
+ try:
+ wager = int(request.values.get("wager"))
+ currency = request.values.get("currency")
+ create_new_game(v, wager, currency)
+ state = dispatch_action(v, BlackjackAction.DEAL)
+ feed = get_game_feed('blackjack')
- return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}}
- except Exception as e:
- abort(400, str(e))
+ return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}}
+ except Exception as e:
+ abort(400, str(e))
@app.post("/casino/twentyone/hit")
@@ -132,15 +132,15 @@ def blackjack_deal_to_player(v):
@auth_required
@feature_required('GAMBLING')
def blackjack_player_hit(v):
- if v.rehab:
- abort(403, "You are under Rehab award effect!")
+ if v.rehab:
+ abort(403, "You are under Rehab award effect!")
- try:
- state = dispatch_action(v, BlackjackAction.HIT)
- feed = get_game_feed('blackjack')
- return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}}
- except:
- abort(400, "Unable to hit.")
+ try:
+ state = dispatch_action(v, BlackjackAction.HIT)
+ feed = get_game_feed('blackjack')
+ return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}}
+ except:
+ abort(400, "Unable to hit.")
@app.post("/casino/twentyone/stay")
@@ -148,15 +148,15 @@ def blackjack_player_hit(v):
@auth_required
@feature_required('GAMBLING')
def blackjack_player_stay(v):
- if v.rehab:
- abort(403, "You are under Rehab award effect!")
+ if v.rehab:
+ abort(403, "You are under Rehab award effect!")
- try:
- state = dispatch_action(v, BlackjackAction.STAY)
- feed = get_game_feed('blackjack')
- return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}}
- except:
- abort(400, "Unable to stay.")
+ try:
+ state = dispatch_action(v, BlackjackAction.STAY)
+ feed = get_game_feed('blackjack')
+ return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}}
+ except:
+ abort(400, "Unable to stay.")
@app.post("/casino/twentyone/double-down")
@@ -164,15 +164,15 @@ def blackjack_player_stay(v):
@auth_required
@feature_required('GAMBLING')
def blackjack_player_doubled_down(v):
- if v.rehab:
- abort(403, "You are under Rehab award effect!")
+ if v.rehab:
+ abort(403, "You are under Rehab award effect!")
- try:
- state = dispatch_action(v, BlackjackAction.DOUBLE_DOWN)
- feed = get_game_feed('blackjack')
- return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}}
- except:
- abort(400, "Unable to double down.")
+ try:
+ state = dispatch_action(v, BlackjackAction.DOUBLE_DOWN)
+ feed = get_game_feed('blackjack')
+ return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}}
+ except:
+ abort(400, "Unable to double down.")
@app.post("/casino/twentyone/buy-insurance")
@@ -180,15 +180,15 @@ def blackjack_player_doubled_down(v):
@auth_required
@feature_required('GAMBLING')
def blackjack_player_bought_insurance(v):
- if v.rehab:
- abort(403, "You are under Rehab award effect!")
+ if v.rehab:
+ abort(403, "You are under Rehab award effect!")
- try:
- state = dispatch_action(v, BlackjackAction.BUY_INSURANCE)
- feed = get_game_feed('blackjack')
- return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}}
- except:
- abort(403, "Unable to buy insurance.")
+ try:
+ state = dispatch_action(v, BlackjackAction.BUY_INSURANCE)
+ feed = get_game_feed('blackjack')
+ return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}}
+ except:
+ abort(403, "Unable to buy insurance.")
# Roulette
@app.get("/casino/roulette/bets")
@@ -196,12 +196,12 @@ def blackjack_player_bought_insurance(v):
@auth_required
@feature_required('GAMBLING')
def roulette_get_bets(v):
- if v.rehab:
- abort(403, "You are under Rehab award effect!")
+ if v.rehab:
+ abort(403, "You are under Rehab award effect!")
- bets = get_roulette_bets()
+ bets = get_roulette_bets()
- return {"success": True, "bets": bets, "gambler": {"coins": v.coins, "procoins": v.procoins}}
+ return {"success": True, "bets": bets, "gambler": {"coins": v.coins, "procoins": v.procoins}}
@app.post("/casino/roulette/place-bet")
@@ -209,22 +209,22 @@ def roulette_get_bets(v):
@auth_required
@feature_required('GAMBLING')
def roulette_player_placed_bet(v):
- if v.rehab:
- abort(403, "You are under Rehab award effect!")
+ if v.rehab:
+ abort(403, "You are under Rehab award effect!")
- try:
- bet = request.values.get("bet")
- which = request.values.get("which")
- amount = int(request.values.get("wager"))
- currency = request.values.get("currency")
+ try:
+ bet = request.values.get("bet")
+ which = request.values.get("which")
+ amount = int(request.values.get("wager"))
+ currency = request.values.get("currency")
- if amount < 5:
- abort(400, f"Minimum bet is 5 {currency}.")
+ if amount < 5:
+ abort(400, f"Minimum bet is 5 {currency}.")
- gambler_placed_roulette_bet(v, bet, which, amount, currency)
+ gambler_placed_roulette_bet(v, bet, which, amount, currency)
- bets = get_roulette_bets()
+ bets = get_roulette_bets()
- return {"success": True, "bets": bets, "gambler": {"coins": v.coins, "procoins": v.procoins}}
- except:
- abort(400, "Unable to place a bet.")
+ return {"success": True, "bets": bets, "gambler": {"coins": v.coins, "procoins": v.procoins}}
+ except:
+ abort(400, "Unable to place a bet.")
diff --git a/files/templates/casino/blackjack_screen.html b/files/templates/casino/blackjack_screen.html
index 66c71ef2f..189781d21 100644
--- a/files/templates/casino/blackjack_screen.html
+++ b/files/templates/casino/blackjack_screen.html
@@ -2,218 +2,218 @@
{% block script %}
{% endblock %}
@@ -225,74 +225,74 @@
{% block actions %}
-
-
-
-
-
+
+
+
+
+
{% endblock %}
diff --git a/files/templates/casino/game_screen.html b/files/templates/casino/game_screen.html
index a55a3d48f..838cb4e50 100644
--- a/files/templates/casino/game_screen.html
+++ b/files/templates/casino/game_screen.html
@@ -2,468 +2,468 @@
{{game.capitalize()}}
{% endblock %} {% block content %}
{% block script %} {% endblock %}
-
-
-
{{game}}
-
-
-
{% block screen %} {% endblock %}
-
-
- {% block result %} {% endblock %}
-
-
-
-
-
-
{% block actiontext %}Actions{% endblock %}
-
-
- {% block actions %} {% endblock %}
-
-
-
-
Feed
-
-
-
-
-
-
-
-
Leaders
-
-
-
-
-
-
-
![](/e/marseyhappytears.webp)
-
-
-
- Biggest Winner (All Time)
-
-
-
-
-
-
-
-
![](/e/marseyexcited.webp)
-
-
-
- Biggest Winner (Last 24h)
-
-
-
-
-
-
-
-
![](/e/marseycry.webp)
-
-
-
- Biggest Loser (Last 24h)
-
-
-
-
-
-
-
-
![](/e/marseyrain.webp)
-
-
-
- Biggest Loser (All Time)
-
-
-
-
-
-
-
+
+
+
{{game}}
+
+
+
{% block screen %} {% endblock %}
+
+
+ {% block result %} {% endblock %}
+
+
+
+
+
+
{% block actiontext %}Actions{% endblock %}
+
+
+ {% block actions %} {% endblock %}
+
+
+
+
Feed
+
+
+
+
+
+
+
+
Leaders
+
+
+
+
+
+
+
![](/e/marseyhappytears.webp)
+
+
+
+ Biggest Winner (All Time)
+
-
+
+
+
+
+
+
![](/e/marseyexcited.webp)
+
+
+
+ Biggest Winner (Last 24h)
+
-
+
+
+
+
+
+
![](/e/marseycry.webp)
+
+
+
+ Biggest Loser (Last 24h)
+
-
+
+
+
+
+
+
![](/e/marseyrain.webp)
+
+
+
+ Biggest Loser (All Time)
+
-
+
+
+
+
+
{% endblock %}
diff --git a/files/templates/casino/rehab.html b/files/templates/casino/rehab.html
index 8e0238b53..cf024e8fa 100644
--- a/files/templates/casino/rehab.html
+++ b/files/templates/casino/rehab.html
@@ -1,11 +1,11 @@
{% extends "default.html" %} {% block content %}
-
-
No one was there for Britney…
-
-
-
…but we’re here for you. You’ve been checked into Rehab.
-
-
![](/i/rDrama/brit.webp)
+
+
No one was there for Britney…
+
+
+
…but we’re here for you. You’ve been checked into Rehab.
+
+
{% endblock %}
diff --git a/files/templates/casino/roulette_screen.html b/files/templates/casino/roulette_screen.html
index 0fcfef1a3..80a6933d2 100644
--- a/files/templates/casino/roulette_screen.html
+++ b/files/templates/casino/roulette_screen.html
@@ -2,480 +2,480 @@
{% block script %}
{% endblock %}
{% block screen %}
@@ -488,95 +488,95 @@ Bets
{% block actions %}
-
-
-
-
![](/i/pokerchip.webp)
-
![](/e/marseycodecellove.webp)
-
-
111 is betting 4 and 4:
-
-
-
- - 2
that
- the number will be black.
- - 2
that
- the number will be even.
-
-
+
+
+
+
![](/i/pokerchip.webp)
+
![](/e/marseycodecellove.webp)
+
+
111 is betting 4 and 4:
+
+
+
+ - 2
that
+ the number will be black.
+ - 2
that
+ the number will be even.
+
+
-
How to Bet
-
+ How to Bet
+
-
-
- Bet |
- Payout |
- Description |
-
-
-
-
- Straight Up |
- 35:1 |
-
- Click any single number.
- You win if the roulette lands on that number.
- |
-
-
- Line |
- 5:1 |
-
- Click Line 1, Line 2 ... Line 6.
- You win if the roulette lands on any of the six numbers beneath the line.
- |
-
-
- Column |
- 2:1 |
-
- Click Col 1, Col 2 or Col 3.
- You win if the roulette lands on any of the 12 numbers to the left of the column.
- |
-
-
- Dozen |
- 2:1 |
-
- Click 1st12, 2nd12 or 3rd12.
- You win if the roulette lands on a number within 1-12, 13-24 or 25-36, respectively.
- |
-
-
- Even/Odd |
- 1:1 |
-
- Click EVEN or ODD.
- You win if the roulette lands on a number that matches your choice.
- |
-
-
- Red/Black |
- 1:1 |
-
- Click RED or BLACK.
- You win if the roulette lands on a number that is the same color as your choice.
- |
-
-
- High/Low |
- 1:1 |
-
- Click 1:18 or 19:36.
- You win if the roulette lands on a number within your selected range.
- |
-
-
+
+
+ Bet |
+ Payout |
+ Description |
+
+
+
+
+ Straight Up |
+ 35:1 |
+
+ Click any single number.
+ You win if the roulette lands on that number.
+ |
+
+
+ Line |
+ 5:1 |
+
+ Click Line 1, Line 2 ... Line 6.
+ You win if the roulette lands on any of the six numbers beneath the line.
+ |
+
+
+ Column |
+ 2:1 |
+
+ Click Col 1, Col 2 or Col 3.
+ You win if the roulette lands on any of the 12 numbers to the left of the column.
+ |
+
+
+ Dozen |
+ 2:1 |
+
+ Click 1st12, 2nd12 or 3rd12.
+ You win if the roulette lands on a number within 1-12, 13-24 or 25-36, respectively.
+ |
+
+
+ Even/Odd |
+ 1:1 |
+
+ Click EVEN or ODD.
+ You win if the roulette lands on a number that matches your choice.
+ |
+
+
+ Red/Black |
+ 1:1 |
+
+ Click RED or BLACK.
+ You win if the roulette lands on a number that is the same color as your choice.
+ |
+
+
+ High/Low |
+ 1:1 |
+
+ Click 1:18 or 19:36.
+ You win if the roulette lands on a number within your selected range.
+ |
+
+
{% endblock %}
diff --git a/files/templates/casino/slots_screen.html b/files/templates/casino/slots_screen.html
index de584c2ec..dfc1c6261 100644
--- a/files/templates/casino/slots_screen.html
+++ b/files/templates/casino/slots_screen.html
@@ -2,124 +2,124 @@
{% block script %}
{% endblock %}
{% block screen %}
-
-
![coin](/i/rDrama/coins.webp?v=3009)
-
-
-
![coin](/i/rDrama/coins.webp?v=3009)
-
-
-
![coin](/i/rDrama/coins.webp?v=3009)
-
+
+
![coin](/i/rDrama/coins.webp?v=3009)
+
+
+
![coin](/i/rDrama/coins.webp?v=3009)
+
+
+
![coin](/i/rDrama/coins.webp?v=3009)
+
{% endblock %}
{% block actions %}
-
+
{% endblock %}