2021-03-16 02:02:17 +00:00
|
|
|
from datetime import datetime
|
2022-02-11 03:20:48 +00:00
|
|
|
|
2022-02-12 15:28:56 +00:00
|
|
|
from django.db import connection
|
2022-02-12 21:21:03 +00:00
|
|
|
from django.db.models.query import RawQuerySet
|
|
|
|
from django.http import HttpRequest
|
2022-02-12 15:28:56 +00:00
|
|
|
|
2022-02-11 03:20:48 +00:00
|
|
|
from django_coreprotect.models import CoWorld, GUIResult
|
|
|
|
from django_coreprotect.utils import safe_int, checkbox, time_to_form
|
2021-03-16 02:02:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
class GUIForm:
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
self.block_break = False
|
|
|
|
self.block_place = False
|
|
|
|
self.chat = False
|
|
|
|
self.chest_use = False
|
|
|
|
self.command = False
|
|
|
|
self.interact = False
|
|
|
|
self.login_logout = False
|
|
|
|
self.sign_place = False
|
|
|
|
self.worlds = []
|
|
|
|
self.ignore_environment = False
|
|
|
|
self.oldest_first = False
|
|
|
|
self.page = ""
|
|
|
|
self.page_size = ""
|
|
|
|
self.start = ""
|
|
|
|
self.players = ""
|
|
|
|
self.x = ""
|
|
|
|
self.y = ""
|
|
|
|
self.z = ""
|
|
|
|
self.radius = ""
|
|
|
|
self.blocks = ""
|
|
|
|
self.date_from = ""
|
|
|
|
self.date_to = ""
|
|
|
|
|
|
|
|
|
2022-02-12 21:21:03 +00:00
|
|
|
def gui_data(request: HttpRequest) -> GUIForm:
|
2021-03-16 02:02:17 +00:00
|
|
|
request_data = request.GET
|
|
|
|
form = GUIForm()
|
|
|
|
worlds = CoWorld.objects.all()
|
|
|
|
|
|
|
|
# Actions
|
|
|
|
form.block_break = checkbox(request_data["block_break"]) if "block_break" in request_data else False
|
|
|
|
form.block_place = checkbox(request_data["block_place"]) if "block_place" in request_data else False
|
|
|
|
form.chat = checkbox(request_data["chat"]) if "chat" in request_data else False
|
|
|
|
form.chest_use = checkbox(request_data["chest_use"]) if "chest_use" in request_data else False
|
|
|
|
form.command = checkbox(request_data["command"]) if "command" in request_data else False
|
|
|
|
form.interact = checkbox(request_data["interact"]) if "interact" in request_data else False
|
|
|
|
form.login_logout = checkbox(request_data["login_logout"]) if "login_logout" in request_data else False
|
|
|
|
form.sign_place = checkbox(request_data["sign_place"]) if "sign_place" in request_data else False
|
|
|
|
|
|
|
|
# Permissions
|
|
|
|
if not request.user.has_perm("django_coreprotect.gui_extra"):
|
|
|
|
form.chat = False
|
|
|
|
form.command = False
|
|
|
|
|
|
|
|
# Worlds
|
|
|
|
request_worlds = request_data.getlist("world")
|
|
|
|
for world in worlds:
|
2022-02-12 21:21:03 +00:00
|
|
|
world_id = f"world_{world.id}"
|
2021-03-16 02:02:17 +00:00
|
|
|
w = {
|
|
|
|
"id": str(world.id),
|
|
|
|
"world_id": world_id,
|
|
|
|
"checked": True if str(world.id) in request_worlds else False,
|
|
|
|
"name": world.world
|
|
|
|
}
|
|
|
|
form.worlds.append(w)
|
|
|
|
|
|
|
|
# Options
|
|
|
|
form.ignore_environment = checkbox(request_data["ignore_environment"]) if "ignore_environment" in request_data else False
|
|
|
|
form.oldest_first = checkbox(request_data["oldest_first"]) if "oldest_first" in request_data else False
|
|
|
|
|
|
|
|
# Limit Results
|
|
|
|
form.page = request_data["page"] if "page" in request_data else "0"
|
|
|
|
form.page_size = request_data["page_size"] if "page_size" in request_data else "20"
|
|
|
|
if safe_int(form.page_size) == 0 or safe_int(form.page_size) > 1000:
|
|
|
|
form.page_size = "1000"
|
|
|
|
form.start = (safe_int(form.page) * safe_int(form.page_size))
|
|
|
|
|
|
|
|
# Players
|
|
|
|
form.players = request_data["players"] if "players" in request_data else ""
|
|
|
|
|
|
|
|
# Coordinates
|
|
|
|
form.x = request_data["x"] if "x" in request_data else ""
|
|
|
|
form.y = request_data["y"] if "y" in request_data else ""
|
|
|
|
form.z = request_data["z"] if "z" in request_data else ""
|
|
|
|
form.radius = request_data["radius"] if "radius" in request_data else ""
|
|
|
|
|
|
|
|
# Blocks
|
|
|
|
form.blocks = request_data["blocks"] if "blocks" in request_data else ""
|
|
|
|
|
|
|
|
# Date and Time
|
2022-02-11 03:20:48 +00:00
|
|
|
form.date_from = time_to_form(request_data["date_from"]) if "date_from" in request_data else ""
|
|
|
|
if form.date_from:
|
|
|
|
form.date_from = form.date_from.timestamp()
|
|
|
|
form.date_to = time_to_form(request_data["date_to"]) if "date_to" in request_data else ""
|
|
|
|
if form.date_to:
|
|
|
|
form.date_to = form.date_to.timestamp()
|
2021-03-16 02:02:17 +00:00
|
|
|
|
|
|
|
return form
|
|
|
|
|
|
|
|
|
2022-02-12 21:21:03 +00:00
|
|
|
def gui_results(form: GUIForm) -> RawQuerySet:
|
2021-03-16 02:02:17 +00:00
|
|
|
queries = []
|
|
|
|
ignore_environment = " AND cu.user NOT LIKE '#%%' " if form.ignore_environment else ""
|
|
|
|
oldest_first = " ASC " if form.oldest_first else " DESC "
|
|
|
|
|
|
|
|
coords = []
|
|
|
|
radius = form.radius if form.radius else "0"
|
|
|
|
if form.x:
|
2022-02-12 21:21:03 +00:00
|
|
|
coords.append(f" x BETWEEN {form.x} - {radius} AND {form.x} + {radius}")
|
2021-03-16 02:02:17 +00:00
|
|
|
if form.y:
|
2022-02-12 21:21:03 +00:00
|
|
|
coords.append(f" y BETWEEN {form.y} - {radius} AND {form.y} + {radius}")
|
2021-03-16 02:02:17 +00:00
|
|
|
if form.z:
|
2022-02-12 21:21:03 +00:00
|
|
|
coords.append(f" z BETWEEN {form.z} - {radius} AND {form.z} + {radius}")
|
2022-02-12 15:38:47 +00:00
|
|
|
coords_clause = ""
|
|
|
|
if coords:
|
2022-02-12 21:21:03 +00:00
|
|
|
clause = " AND ".join(coords)
|
|
|
|
coords_clause = f" AND ({clause})"
|
2021-03-16 02:02:17 +00:00
|
|
|
|
|
|
|
players = []
|
|
|
|
players_clause = ""
|
|
|
|
if form.players:
|
|
|
|
for player in form.players.split(","):
|
|
|
|
players.append(player.strip())
|
2022-02-12 21:21:03 +00:00
|
|
|
clause = " OR ".join([f"cu.user LIKE '{p}%%'" for p in players])
|
|
|
|
players_clause = f" AND ({clause})"
|
2021-03-16 02:02:17 +00:00
|
|
|
|
|
|
|
blocks = []
|
|
|
|
blocks_clause = ""
|
2022-02-11 03:20:48 +00:00
|
|
|
chat_clause = ""
|
|
|
|
command_clause = ""
|
2021-03-16 02:02:17 +00:00
|
|
|
if form.blocks:
|
|
|
|
for block in form.blocks.split(","):
|
|
|
|
blocks.append(block.strip())
|
2022-02-12 21:21:03 +00:00
|
|
|
clause = " OR ".join([f"cmm.material LIKE 'minecraft:{b}%%'" for b in blocks])
|
|
|
|
blocks_clause = f" AND ({clause})"
|
|
|
|
clause = " OR ".join([f"cc.message LIKE '%%{b}%%'" for b in blocks])
|
|
|
|
chat_clause = f" AND ({clause})"
|
|
|
|
clause = " OR ".join([f"cc.message LIKE '%%{b}%%'" for b in blocks])
|
|
|
|
command_clause = f" AND ({clause})"
|
2021-03-16 02:02:17 +00:00
|
|
|
|
|
|
|
worlds_clause = ""
|
|
|
|
worlds = [world["id"] for world in form.worlds if world["checked"]]
|
|
|
|
if len(worlds):
|
2022-02-12 21:21:03 +00:00
|
|
|
clause = ",".join(worlds)
|
|
|
|
worlds_clause = f" AND cw.rowid IN ({clause})"
|
2021-03-16 02:02:17 +00:00
|
|
|
|
|
|
|
time_clause = ""
|
|
|
|
if form.date_from or form.date_to:
|
|
|
|
df, dt = form.date_from, form.date_to
|
|
|
|
if form.date_from and not form.date_to:
|
|
|
|
dt = datetime.now().timestamp()
|
|
|
|
if form.date_to and not form.date_from:
|
|
|
|
df = datetime.now().timestamp()
|
2022-02-12 21:21:03 +00:00
|
|
|
time_clause = f" GROUP BY unix HAVING unix BETWEEN {df} AND {dt} "
|
2021-03-16 02:02:17 +00:00
|
|
|
|
|
|
|
# Block Break, Block Place, and Interact
|
|
|
|
block_actions = []
|
|
|
|
if form.block_break:
|
|
|
|
block_actions.append("0")
|
|
|
|
if form.block_place:
|
|
|
|
block_actions.append("1")
|
|
|
|
if form.interact:
|
|
|
|
block_actions.append("2")
|
|
|
|
if len(block_actions):
|
2022-02-12 21:21:03 +00:00
|
|
|
queries.append(f'''SELECT
|
2021-03-16 02:02:17 +00:00
|
|
|
0 AS id, "block" AS type, cb.time AS unix, cu.user AS player, cb.action, cmm.material AS data, cb.x, cb.y, cb.z, cw.world
|
|
|
|
FROM co_block cb
|
|
|
|
JOIN co_user cu ON cb.user = cu.rowid
|
|
|
|
JOIN co_material_map cmm ON cb.type = cmm.rowid
|
|
|
|
JOIN co_world cw ON cb.wid = cw.rowid
|
2022-02-12 21:21:03 +00:00
|
|
|
WHERE cb.action IN ({",".join(block_actions)})
|
2021-03-16 02:02:17 +00:00
|
|
|
{ignore_environment}
|
2022-02-12 21:21:03 +00:00
|
|
|
{players_clause}
|
|
|
|
{coords_clause}
|
|
|
|
{blocks_clause}
|
|
|
|
{worlds_clause}
|
|
|
|
{time_clause}
|
|
|
|
''')
|
2021-03-16 02:02:17 +00:00
|
|
|
|
|
|
|
# Chat
|
|
|
|
if form.chat:
|
2022-02-12 21:21:03 +00:00
|
|
|
queries.append(f'''SELECT
|
2021-03-16 02:02:17 +00:00
|
|
|
0 AS id, "chat" AS type, cc.time AS unix, cu.user AS player, "" AS action, cc.message AS data, "" AS x, "" AS y, "" AS z, "" AS world
|
|
|
|
FROM co_chat cc
|
|
|
|
JOIN co_user cu ON cc.user = cu.rowid
|
|
|
|
WHERE 1 = 1
|
2022-02-12 21:21:03 +00:00
|
|
|
{players_clause}
|
|
|
|
{chat_clause}
|
|
|
|
{time_clause}
|
|
|
|
''')
|
2021-03-16 02:02:17 +00:00
|
|
|
|
|
|
|
# Chest Use
|
|
|
|
if form.chest_use:
|
|
|
|
concat = 'CONCAT(cc.amount, " ", cmm.material)'
|
|
|
|
if connection.vendor == "sqlite":
|
|
|
|
concat = 'cc.amount || " " || cmm.material'
|
2022-02-12 21:21:03 +00:00
|
|
|
queries.append(f'''SELECT
|
2021-03-16 02:02:17 +00:00
|
|
|
0 AS id, "container" AS type, cc.time AS unix, cu.user AS player, cc.action, {concat} AS data, cc.x, cc.y, cc.z, cw.world
|
|
|
|
FROM co_container cc
|
|
|
|
JOIN co_user cu ON cc.user = cu.rowid
|
|
|
|
JOIN co_material_map cmm ON cc.type = cmm.rowid
|
|
|
|
JOIN co_world cw ON cc.wid = cw.rowid
|
|
|
|
WHERE 1 = 1
|
2022-02-12 21:21:03 +00:00
|
|
|
{worlds_clause}
|
|
|
|
{players_clause}
|
|
|
|
{coords_clause}
|
|
|
|
{blocks_clause}
|
|
|
|
{time_clause}
|
|
|
|
''')
|
2021-03-16 02:02:17 +00:00
|
|
|
|
|
|
|
# Commands
|
|
|
|
if form.command:
|
2022-02-12 21:21:03 +00:00
|
|
|
queries.append(f'''SELECT
|
2021-03-16 02:02:17 +00:00
|
|
|
0 AS id, "command" AS type, cc.time AS unix, cu.user AS player, "" AS action, cc.message AS data, "" AS x, "" AS y, "" AS z, "" AS world
|
|
|
|
FROM co_command cc
|
|
|
|
JOIN co_user cu ON cc.user = cu.rowid
|
|
|
|
WHERE 1 = 1
|
2022-02-12 21:21:03 +00:00
|
|
|
{players_clause}
|
|
|
|
{command_clause}
|
|
|
|
{coords_clause}
|
|
|
|
{time_clause}
|
|
|
|
''')
|
2021-03-16 02:02:17 +00:00
|
|
|
|
|
|
|
# Login/Logout
|
|
|
|
if form.login_logout:
|
2022-02-12 21:21:03 +00:00
|
|
|
queries.append(f'''SELECT
|
2021-03-16 02:02:17 +00:00
|
|
|
0 AS id, "session" AS type, cs.time AS unix, cu.user AS player, cs.action, "" AS data, cs.x, cs.y, cs.z, cw.world
|
|
|
|
FROM co_session cs
|
|
|
|
JOIN co_user cu ON cs.user = cu.rowid
|
|
|
|
JOIN co_world cw ON cs.wid = cw.rowid
|
|
|
|
WHERE 1 = 1
|
2022-02-12 21:21:03 +00:00
|
|
|
{worlds_clause}
|
|
|
|
{players_clause}
|
|
|
|
{coords_clause}
|
|
|
|
{time_clause}
|
|
|
|
''')
|
2021-03-16 02:02:17 +00:00
|
|
|
|
|
|
|
# Sign Place
|
|
|
|
if form.sign_place:
|
2022-02-12 21:21:03 +00:00
|
|
|
queries.append(f'''SELECT
|
2021-03-16 02:02:17 +00:00
|
|
|
0 AS id, "sign" AS type, cs.time AS unix, cu.user AS player, "" AS action, cs.line_1 || "|" || cs.line_2 || "|" || cs.line_3 || "|" || cs.line_4 AS data, cs.x, cs.y, cs.z, cw.world
|
|
|
|
FROM co_sign cs
|
|
|
|
JOIN co_user cu ON cs.user = cu.rowid
|
|
|
|
JOIN co_world cw ON cs.wid = cw.rowid
|
|
|
|
WHERE 1 = 1
|
2022-02-12 21:21:03 +00:00
|
|
|
{worlds_clause}
|
|
|
|
{players_clause}
|
|
|
|
{coords_clause}
|
|
|
|
{time_clause}
|
|
|
|
''')
|
2021-03-16 02:02:17 +00:00
|
|
|
|
|
|
|
query = " UNION ALL ".join(queries)
|
|
|
|
if query:
|
2022-02-12 21:21:03 +00:00
|
|
|
query += f" ORDER BY unix {oldest_first} LIMIT {form.start}, {form.page_size}"
|
2021-03-16 02:02:17 +00:00
|
|
|
return GUIResult.objects.raw(query)
|
2022-02-12 21:21:03 +00:00
|
|
|
return GUIResult.objects.none()
|