2022-11-15 09:19:08 +00:00
|
|
|
import atexit
|
2022-03-24 19:44:12 +00:00
|
|
|
import time
|
2022-09-24 22:05:50 +00:00
|
|
|
import uuid
|
2022-11-15 09:19:08 +00:00
|
|
|
|
2023-01-30 09:57:00 +00:00
|
|
|
from flask_socketio import SocketIO, emit
|
2023-02-16 13:41:58 +00:00
|
|
|
from flask import request
|
2022-11-15 09:19:08 +00:00
|
|
|
|
|
|
|
from files.helpers.actions import *
|
2022-07-11 09:52:59 +00:00
|
|
|
from files.helpers.alerts import *
|
2022-12-11 23:44:34 +00:00
|
|
|
from files.helpers.config.const import *
|
2022-06-24 14:30:59 +00:00
|
|
|
from files.helpers.regex import *
|
2023-03-06 19:52:31 +00:00
|
|
|
from files.helpers.media import *
|
2023-02-07 03:31:49 +00:00
|
|
|
from files.helpers.sanitize import *
|
2022-12-26 03:14:02 +00:00
|
|
|
from files.helpers.alerts import push_notif
|
2022-11-15 09:19:08 +00:00
|
|
|
from files.routes.wrappers import *
|
Bring back orgies (watchparties), now controllable by admins, and generally better in all ways (#165)
This PR adds orgies back into rdrama. Long ago, snakes made the original orgy code, and it was super fun. But he had to rush it out, and ended up making it a bit unsustainable, and had a couple questionable coding decisions, which meant that it had to be removed. Hey, the man literally did it in a few hours before the DB trial continued, lmao.
Anyways, I took my own approach to it. I do not use iframes, i just just repurpose code from /chat window. Because I had that freedom, I also moved things around to make the user experience a bit better. I also added a title to give users some context about what's happening. Check it out
![image](/attachments/6719146c-4922-4d75-967d-8d424a09b198)
Most importantly, this is all configurable from the site. Admins with the permission "ORGIES" will see this in their control panel
![image](/attachments/423d6046-a11d-4e84-bd2c-a2a641afd552)
Nigga, idk where to put it, so I made my own category.
If there is no orgy in progress, admins will see this:
![image](/attachments/7c64b9fa-cdf4-4986-a0c4-f2324878062e)
Click the button, and, viola, the orgy begins.
If there is an orgy in progress, the page will look like this:
![image](/attachments/b65be4b3-5db1-43cb-8857-7d3a8ea24ca7)
Click the button, and the orgy stops.
If an orgy is in progress, navigating to /chat will take the user to the orgy seemlessly. But what if they don't want to participate, liek some kind of spoilsport? Just navigate to /old_chat.
That's just about it, it's really that simple. I have lots of ideas for the future, but I'll let that wait til later :).
A few notes about implementation:
- I moved some functionality out of /templates/chat.html and into /templates/util/macros.html. This is just so I could reference the code directly from my new template, /templates/orgy.html.
- The orgy is stored as a single row in the new table "orgies". Okay, I know this is a little silly, but you know what they say: "if it's stupid and it works, it's not stupid". (tbf the oceangate ceo also said that)
Co-authored-by: Chuck Sneed <sneed@formerlychucks.net>
Reviewed-on: https://fsdfsd.net/rDrama/rDrama/pulls/165
Co-authored-by: HeyMoon <heymoon@noreply.fsdfsd.net>
Co-committed-by: HeyMoon <heymoon@noreply.fsdfsd.net>
2023-07-02 23:55:37 +00:00
|
|
|
from files.classes.orgy import *
|
2022-11-15 09:19:08 +00:00
|
|
|
|
|
|
|
from files.__main__ import app, cache, limiter
|
2022-03-20 20:41:54 +00:00
|
|
|
|
2023-01-21 10:36:21 +00:00
|
|
|
socketio = SocketIO(
|
|
|
|
app,
|
|
|
|
async_mode='gevent',
|
|
|
|
)
|
2022-03-24 19:44:12 +00:00
|
|
|
|
2023-01-30 09:57:00 +00:00
|
|
|
typing = []
|
2023-01-22 00:11:01 +00:00
|
|
|
online = []
|
2023-02-16 13:41:58 +00:00
|
|
|
sessions = []
|
2023-01-22 00:11:01 +00:00
|
|
|
cache.set(CHAT_ONLINE_CACHE_KEY, len(online), timeout=0)
|
2023-01-23 06:04:02 +00:00
|
|
|
muted = cache.get(f'muted') or {}
|
2023-01-30 09:57:00 +00:00
|
|
|
messages = cache.get(f'messages') or {}
|
2022-03-24 19:44:12 +00:00
|
|
|
|
|
|
|
@app.get("/chat")
|
2023-02-26 08:41:04 +00:00
|
|
|
@limiter.limit(DEFAULT_RATELIMIT)
|
2023-01-21 04:39:46 +00:00
|
|
|
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
|
2023-06-15 05:36:28 +00:00
|
|
|
@is_not_permabanned
|
2022-08-17 20:30:07 +00:00
|
|
|
def chat(v):
|
2022-12-26 02:49:14 +00:00
|
|
|
if not v.admin_level and TRUESCORE_CHAT_MINIMUM and v.truescore < TRUESCORE_CHAT_MINIMUM:
|
2023-01-27 11:57:29 +00:00
|
|
|
abort(403, f"Need at least {TRUESCORE_CHAT_MINIMUM} truescore for access to chat!")
|
Bring back orgies (watchparties), now controllable by admins, and generally better in all ways (#165)
This PR adds orgies back into rdrama. Long ago, snakes made the original orgy code, and it was super fun. But he had to rush it out, and ended up making it a bit unsustainable, and had a couple questionable coding decisions, which meant that it had to be removed. Hey, the man literally did it in a few hours before the DB trial continued, lmao.
Anyways, I took my own approach to it. I do not use iframes, i just just repurpose code from /chat window. Because I had that freedom, I also moved things around to make the user experience a bit better. I also added a title to give users some context about what's happening. Check it out
![image](/attachments/6719146c-4922-4d75-967d-8d424a09b198)
Most importantly, this is all configurable from the site. Admins with the permission "ORGIES" will see this in their control panel
![image](/attachments/423d6046-a11d-4e84-bd2c-a2a641afd552)
Nigga, idk where to put it, so I made my own category.
If there is no orgy in progress, admins will see this:
![image](/attachments/7c64b9fa-cdf4-4986-a0c4-f2324878062e)
Click the button, and, viola, the orgy begins.
If there is an orgy in progress, the page will look like this:
![image](/attachments/b65be4b3-5db1-43cb-8857-7d3a8ea24ca7)
Click the button, and the orgy stops.
If an orgy is in progress, navigating to /chat will take the user to the orgy seemlessly. But what if they don't want to participate, liek some kind of spoilsport? Just navigate to /old_chat.
That's just about it, it's really that simple. I have lots of ideas for the future, but I'll let that wait til later :).
A few notes about implementation:
- I moved some functionality out of /templates/chat.html and into /templates/util/macros.html. This is just so I could reference the code directly from my new template, /templates/orgy.html.
- The orgy is stored as a single row in the new table "orgies". Okay, I know this is a little silly, but you know what they say: "if it's stupid and it works, it's not stupid". (tbf the oceangate ceo also said that)
Co-authored-by: Chuck Sneed <sneed@formerlychucks.net>
Reviewed-on: https://fsdfsd.net/rDrama/rDrama/pulls/165
Co-authored-by: HeyMoon <heymoon@noreply.fsdfsd.net>
Co-committed-by: HeyMoon <heymoon@noreply.fsdfsd.net>
2023-07-02 23:55:37 +00:00
|
|
|
orgy = get_orgy()
|
|
|
|
if orgy:
|
2023-07-10 00:38:02 +00:00
|
|
|
return render_template("orgy.html", v=v, messages=messages, orgy = orgy, site = SITE)
|
Bring back orgies (watchparties), now controllable by admins, and generally better in all ways (#165)
This PR adds orgies back into rdrama. Long ago, snakes made the original orgy code, and it was super fun. But he had to rush it out, and ended up making it a bit unsustainable, and had a couple questionable coding decisions, which meant that it had to be removed. Hey, the man literally did it in a few hours before the DB trial continued, lmao.
Anyways, I took my own approach to it. I do not use iframes, i just just repurpose code from /chat window. Because I had that freedom, I also moved things around to make the user experience a bit better. I also added a title to give users some context about what's happening. Check it out
![image](/attachments/6719146c-4922-4d75-967d-8d424a09b198)
Most importantly, this is all configurable from the site. Admins with the permission "ORGIES" will see this in their control panel
![image](/attachments/423d6046-a11d-4e84-bd2c-a2a641afd552)
Nigga, idk where to put it, so I made my own category.
If there is no orgy in progress, admins will see this:
![image](/attachments/7c64b9fa-cdf4-4986-a0c4-f2324878062e)
Click the button, and, viola, the orgy begins.
If there is an orgy in progress, the page will look like this:
![image](/attachments/b65be4b3-5db1-43cb-8857-7d3a8ea24ca7)
Click the button, and the orgy stops.
If an orgy is in progress, navigating to /chat will take the user to the orgy seemlessly. But what if they don't want to participate, liek some kind of spoilsport? Just navigate to /old_chat.
That's just about it, it's really that simple. I have lots of ideas for the future, but I'll let that wait til later :).
A few notes about implementation:
- I moved some functionality out of /templates/chat.html and into /templates/util/macros.html. This is just so I could reference the code directly from my new template, /templates/orgy.html.
- The orgy is stored as a single row in the new table "orgies". Okay, I know this is a little silly, but you know what they say: "if it's stupid and it works, it's not stupid". (tbf the oceangate ceo also said that)
Co-authored-by: Chuck Sneed <sneed@formerlychucks.net>
Reviewed-on: https://fsdfsd.net/rDrama/rDrama/pulls/165
Co-authored-by: HeyMoon <heymoon@noreply.fsdfsd.net>
Co-committed-by: HeyMoon <heymoon@noreply.fsdfsd.net>
2023-07-02 23:55:37 +00:00
|
|
|
else:
|
|
|
|
return render_template("chat.html", v=v, messages=messages)
|
|
|
|
|
|
|
|
@app.get("/old_chat")
|
|
|
|
@limiter.limit(DEFAULT_RATELIMIT)
|
|
|
|
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
|
|
|
|
@is_not_permabanned
|
|
|
|
def old_chat(v):
|
|
|
|
if not v.admin_level and TRUESCORE_CHAT_MINIMUM and v.truescore < TRUESCORE_CHAT_MINIMUM:
|
|
|
|
abort(403, f"Need at least {TRUESCORE_CHAT_MINIMUM} truescore for access to chat!")
|
2023-01-30 09:57:00 +00:00
|
|
|
return render_template("chat.html", v=v, messages=messages)
|
2022-03-24 19:44:12 +00:00
|
|
|
|
|
|
|
@socketio.on('speak')
|
2023-06-15 05:36:28 +00:00
|
|
|
@is_not_permabanned
|
2022-03-24 19:44:12 +00:00
|
|
|
def speak(data, v):
|
2023-01-21 10:36:21 +00:00
|
|
|
image = None
|
|
|
|
if data['file']:
|
|
|
|
name = f'/chat_images/{time.time()}'.replace('.','') + '.webp'
|
|
|
|
with open(name, 'wb') as f:
|
|
|
|
f.write(data['file'])
|
|
|
|
image = process_image(name, v)
|
|
|
|
|
2022-03-24 19:44:12 +00:00
|
|
|
if v.is_banned: return '', 403
|
2022-12-04 18:39:06 +00:00
|
|
|
if TRUESCORE_CHAT_MINIMUM and v.truescore < TRUESCORE_CHAT_MINIMUM:
|
|
|
|
return '', 403
|
2022-03-24 21:01:04 +00:00
|
|
|
|
2023-01-20 04:10:25 +00:00
|
|
|
global messages
|
2022-08-14 02:38:07 +00:00
|
|
|
|
2022-11-16 14:00:04 +00:00
|
|
|
text = sanitize_raw_body(data['message'], False)[:CHAT_LENGTH_LIMIT]
|
2023-03-12 13:02:31 +00:00
|
|
|
if image: text += f'\n\n{image}'
|
2022-11-16 14:00:04 +00:00
|
|
|
if not text: return '', 400
|
2022-08-14 02:38:07 +00:00
|
|
|
|
2023-03-19 12:01:54 +00:00
|
|
|
text_html = sanitize(text, count_emojis=True, chat=True)
|
2023-01-27 07:07:58 +00:00
|
|
|
if isinstance(text_html , tuple):
|
|
|
|
return text_html
|
|
|
|
|
2022-09-24 22:05:50 +00:00
|
|
|
quotes = data['quotes']
|
2023-01-22 02:43:28 +00:00
|
|
|
id = str(uuid.uuid4())
|
2023-01-23 02:45:34 +00:00
|
|
|
|
2023-01-23 06:04:02 +00:00
|
|
|
self_only = False
|
|
|
|
|
|
|
|
vname = v.username.lower()
|
|
|
|
if vname in muted:
|
|
|
|
if time.time() < muted[vname]:
|
|
|
|
self_only = True
|
|
|
|
else:
|
|
|
|
del muted[vname]
|
2023-01-24 05:28:56 +00:00
|
|
|
emit("online", [online, muted], broadcast=True)
|
2023-01-23 06:04:02 +00:00
|
|
|
|
2023-01-24 05:28:56 +00:00
|
|
|
if SITE == 'rdrama.net':
|
|
|
|
def shut_up():
|
|
|
|
self_only = True
|
2023-03-04 18:16:38 +00:00
|
|
|
muted_until = int(time.time() + 600)
|
2023-01-24 05:28:56 +00:00
|
|
|
muted[vname] = muted_until
|
|
|
|
emit("online", [online, muted], broadcast=True)
|
2023-01-23 06:04:02 +00:00
|
|
|
|
2023-01-24 05:28:56 +00:00
|
|
|
if not self_only:
|
2023-01-30 09:57:00 +00:00
|
|
|
identical = [x for x in list(messages.values())[-5:] if v.id == x['user_id'] and text == x['text']]
|
2023-01-24 05:28:56 +00:00
|
|
|
if len(identical) >= 3: shut_up()
|
2023-01-23 06:04:02 +00:00
|
|
|
|
2023-01-24 05:28:56 +00:00
|
|
|
if not self_only:
|
2023-01-30 09:57:00 +00:00
|
|
|
count = len([x for x in list(messages.values())[-12:] if v.id == x['user_id']])
|
2023-01-24 05:28:56 +00:00
|
|
|
if count >= 10: shut_up()
|
2023-01-23 06:04:02 +00:00
|
|
|
|
2023-01-24 05:28:56 +00:00
|
|
|
if not self_only:
|
2023-01-30 09:57:00 +00:00
|
|
|
count = len([x for x in list(messages.values())[-25:] if v.id == x['user_id']])
|
2023-01-24 05:28:56 +00:00
|
|
|
if count >= 20: shut_up()
|
2023-01-23 02:45:34 +00:00
|
|
|
|
2022-11-16 14:00:04 +00:00
|
|
|
data = {
|
2023-01-22 06:00:50 +00:00
|
|
|
"id": id,
|
2023-01-30 09:57:00 +00:00
|
|
|
"quotes": quotes if messages.get(quotes) else '',
|
2022-12-24 22:21:49 +00:00
|
|
|
"hat": v.hat_active(v)[0],
|
2022-09-27 05:15:22 +00:00
|
|
|
"user_id": v.id,
|
2022-03-28 10:06:57 +00:00
|
|
|
"username": v.username,
|
2022-09-17 14:39:50 +00:00
|
|
|
"namecolor": v.name_color,
|
2022-03-28 10:06:57 +00:00
|
|
|
"text": text,
|
|
|
|
"text_html": text_html,
|
2022-04-06 22:54:09 +00:00
|
|
|
"text_censored": censor_slurs(text_html, 'chat'),
|
2022-09-24 20:36:56 +00:00
|
|
|
"time": int(time.time()),
|
2022-03-24 19:44:12 +00:00
|
|
|
}
|
2023-01-01 11:36:20 +00:00
|
|
|
|
2022-03-24 21:01:04 +00:00
|
|
|
|
2022-10-06 05:54:48 +00:00
|
|
|
if v.admin_level >= PERMS['USER_BAN']:
|
2022-03-24 21:01:04 +00:00
|
|
|
text = text.lower()
|
|
|
|
for i in mute_regex.finditer(text):
|
2022-08-13 09:24:56 +00:00
|
|
|
username = i.group(1).lower()
|
2023-01-23 06:04:02 +00:00
|
|
|
muted_until = int(int(i.group(2)) * 60 + time.time())
|
|
|
|
muted[username] = muted_until
|
2023-01-24 05:28:56 +00:00
|
|
|
emit("online", [online, muted], broadcast=True)
|
2023-01-23 06:04:02 +00:00
|
|
|
self_only = True
|
|
|
|
|
2023-02-07 03:31:49 +00:00
|
|
|
if self_only or v.shadowbanned or execute_blackjack(v, None, text, "chat"):
|
2023-01-23 06:04:02 +00:00
|
|
|
emit('speak', data)
|
|
|
|
else:
|
2023-01-30 09:57:00 +00:00
|
|
|
emit('speak', data, broadcast=True)
|
|
|
|
messages[id] = data
|
2023-02-19 08:47:20 +00:00
|
|
|
messages = dict(list(messages.items())[-250:])
|
2022-03-24 21:01:04 +00:00
|
|
|
|
2022-08-15 15:02:19 +00:00
|
|
|
typing = []
|
2022-12-25 20:30:50 +00:00
|
|
|
|
2022-03-24 19:44:12 +00:00
|
|
|
return '', 204
|
|
|
|
|
2023-01-24 05:28:56 +00:00
|
|
|
def refresh_online():
|
|
|
|
emit("online", [online, muted], broadcast=True)
|
2023-01-30 09:57:00 +00:00
|
|
|
cache.set(CHAT_ONLINE_CACHE_KEY, len(online), timeout=0)
|
2023-01-20 04:25:35 +00:00
|
|
|
|
2022-03-24 19:44:12 +00:00
|
|
|
@socketio.on('connect')
|
2023-06-15 05:36:28 +00:00
|
|
|
@is_not_permabanned
|
2022-03-24 19:44:12 +00:00
|
|
|
def connect(v):
|
2023-01-21 10:54:15 +00:00
|
|
|
|
2023-02-17 13:58:02 +00:00
|
|
|
if any(v.id in session for session in sessions) and [v.username, v.id, v.name_color] not in online:
|
|
|
|
# user has previous running sessions with a different username or name_color
|
|
|
|
for chat_user in online:
|
|
|
|
if(v.id == chat_user[1]):
|
|
|
|
online.remove(chat_user)
|
|
|
|
|
2023-02-16 13:41:58 +00:00
|
|
|
sessions.append([v.id, request.sid])
|
2023-01-27 18:15:38 +00:00
|
|
|
if [v.username, v.id, v.name_color] not in online:
|
|
|
|
online.append([v.username, v.id, v.name_color])
|
|
|
|
|
|
|
|
refresh_online()
|
2023-01-25 01:17:39 +00:00
|
|
|
|
2023-01-30 09:57:00 +00:00
|
|
|
emit('typing', typing)
|
2022-03-24 19:44:12 +00:00
|
|
|
return '', 204
|
|
|
|
|
|
|
|
@socketio.on('disconnect')
|
2023-06-15 05:36:28 +00:00
|
|
|
@is_not_permabanned
|
2022-03-24 19:44:12 +00:00
|
|
|
def disconnect(v):
|
2023-02-16 13:41:58 +00:00
|
|
|
if ([v.id, request.sid]) in sessions:
|
|
|
|
sessions.remove([v.id, request.sid])
|
2023-02-17 13:58:02 +00:00
|
|
|
if any(v.id in session for session in sessions):
|
2023-02-16 13:41:58 +00:00
|
|
|
# user has other running sessions
|
|
|
|
return '', 204
|
|
|
|
|
2023-02-17 13:58:02 +00:00
|
|
|
for chat_user in online:
|
|
|
|
if(v.id == chat_user[1]):
|
|
|
|
online.remove(chat_user)
|
|
|
|
if chat_user[0] in typing:
|
|
|
|
typing.remove(chat_user[0])
|
2022-03-24 19:44:12 +00:00
|
|
|
|
2023-02-17 13:58:02 +00:00
|
|
|
refresh_online()
|
2023-02-16 13:41:58 +00:00
|
|
|
|
2022-03-24 19:44:12 +00:00
|
|
|
return '', 204
|
|
|
|
|
|
|
|
@socketio.on('typing')
|
2023-06-15 05:36:28 +00:00
|
|
|
@is_not_permabanned
|
2022-03-24 19:44:12 +00:00
|
|
|
def typing_indicator(data, v):
|
2023-01-30 09:57:00 +00:00
|
|
|
if data and v.username not in typing:
|
|
|
|
typing.append(v.username)
|
|
|
|
elif not data and v.username in typing:
|
|
|
|
typing.remove(v.username)
|
2022-03-24 19:44:12 +00:00
|
|
|
|
2023-01-30 09:57:00 +00:00
|
|
|
emit('typing', typing, broadcast=True)
|
2022-03-24 19:44:12 +00:00
|
|
|
return '', 204
|
|
|
|
|
|
|
|
|
2022-09-10 09:31:51 +00:00
|
|
|
@socketio.on('delete')
|
2022-10-06 00:57:08 +00:00
|
|
|
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
|
2023-01-21 10:36:21 +00:00
|
|
|
def delete(id, v):
|
2023-01-30 09:57:00 +00:00
|
|
|
del messages[id]
|
2022-09-10 09:31:51 +00:00
|
|
|
|
2023-01-30 09:57:00 +00:00
|
|
|
emit('delete', id, broadcast=True)
|
2022-09-10 09:31:51 +00:00
|
|
|
|
|
|
|
return '', 204
|
|
|
|
|
|
|
|
|
2022-03-24 19:44:12 +00:00
|
|
|
def close_running_threads():
|
2023-01-20 04:10:25 +00:00
|
|
|
cache.set(f'messages', messages)
|
|
|
|
cache.set(f'muted', muted)
|
2022-09-24 04:26:44 +00:00
|
|
|
atexit.register(close_running_threads)
|