feat: new tables
This commit is contained in:
parent
eb96c98878
commit
19e62d87d4
|
|
@ -13,6 +13,8 @@ from hubgw.services.warps_service import WarpsService
|
|||
from hubgw.services.whitelist_service import WhitelistService
|
||||
from hubgw.services.punishments_service import PunishmentsService
|
||||
from hubgw.services.audit_service import AuditService
|
||||
from hubgw.services.luckperms_service import LuckPermsService
|
||||
from hubgw.services.teleport_history_service import TeleportHistoryService
|
||||
|
||||
|
||||
async def get_context() -> AppContext:
|
||||
|
|
@ -71,3 +73,13 @@ def get_punishments_service(session: Annotated[AsyncSession, Depends(get_session
|
|||
def get_audit_service(session: Annotated[AsyncSession, Depends(get_session)]) -> AuditService:
|
||||
"""Get audit service."""
|
||||
return AuditService(session)
|
||||
|
||||
|
||||
def get_luckperms_service(session: Annotated[AsyncSession, Depends(get_session)]) -> LuckPermsService:
|
||||
"""Get luckperms service."""
|
||||
return LuckPermsService(session)
|
||||
|
||||
|
||||
def get_teleport_history_service(session: Annotated[AsyncSession, Depends(get_session)]) -> TeleportHistoryService:
|
||||
"""Get teleport history service."""
|
||||
return TeleportHistoryService(session)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from uuid import UUID
|
|||
|
||||
from hubgw.api.deps import get_cooldowns_service, verify_api_key
|
||||
from hubgw.services.cooldowns_service import CooldownsService
|
||||
from hubgw.schemas.cooldowns import CooldownCheckRequest, CooldownCheckResponse, CooldownKey
|
||||
from hubgw.schemas.cooldowns import CooldownCheckRequest, CooldownCheckResponse, CooldownCreate
|
||||
from hubgw.core.errors import AppError, create_http_exception
|
||||
|
||||
router = APIRouter()
|
||||
|
|
@ -25,17 +25,15 @@ async def check_cooldown(
|
|||
raise create_http_exception(e)
|
||||
|
||||
|
||||
@router.put("/touch")
|
||||
async def touch_cooldown(
|
||||
key: CooldownKey,
|
||||
@router.post("/", response_model=dict, status_code=201)
|
||||
async def create_cooldown(
|
||||
request: CooldownCreate,
|
||||
service: Annotated[CooldownsService, Depends(get_cooldowns_service)],
|
||||
_: Annotated[str, Depends(verify_api_key)],
|
||||
seconds: int = Query(..., description="Cooldown duration in seconds"),
|
||||
player_uuid: UUID = Query(..., description="Player UUID")
|
||||
_: Annotated[str, Depends(verify_api_key)]
|
||||
):
|
||||
"""Touch cooldown."""
|
||||
"""Create cooldown."""
|
||||
try:
|
||||
await service.touch_cooldown(player_uuid, key.key, seconds)
|
||||
return {"message": "Cooldown touched successfully"}
|
||||
await service.create_cooldown(request)
|
||||
return {"message": "Cooldown created successfully"}
|
||||
except AppError as e:
|
||||
raise create_http_exception(e)
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ async def get_home(
|
|||
|
||||
@router.get("/{player_uuid}", response_model=HomeListResponse)
|
||||
async def list_homes(
|
||||
player_uuid: UUID,
|
||||
player_uuid: str,
|
||||
service: Annotated[HomesService, Depends(get_homes_service)],
|
||||
_: Annotated[str, Depends(verify_api_key)]
|
||||
):
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
"""LuckPerms endpoints."""
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from typing import Annotated
|
||||
|
||||
from hubgw.api.deps import get_luckperms_service, verify_api_key
|
||||
from hubgw.services.luckperms_service import LuckPermsService
|
||||
from hubgw.schemas.luckperms import LuckPermsPlayer, LuckPermsGroup, LuckPermsUserPermission, LuckPermsPlayerWithPermissions
|
||||
from hubgw.core.errors import AppError, create_http_exception
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/players/{uuid}", response_model=LuckPermsPlayer)
|
||||
async def get_player(
|
||||
uuid: str,
|
||||
service: Annotated[LuckPermsService, Depends(get_luckperms_service)],
|
||||
_: Annotated[str, Depends(verify_api_key)]
|
||||
):
|
||||
"""Get player by UUID."""
|
||||
try:
|
||||
return await service.get_player(uuid)
|
||||
except AppError as e:
|
||||
raise create_http_exception(e)
|
||||
|
||||
|
||||
@router.get("/players/username/{username}", response_model=LuckPermsPlayer)
|
||||
async def get_player_by_username(
|
||||
username: str,
|
||||
service: Annotated[LuckPermsService, Depends(get_luckperms_service)],
|
||||
_: Annotated[str, Depends(verify_api_key)]
|
||||
):
|
||||
"""Get player by username."""
|
||||
try:
|
||||
return await service.get_player_by_username(username)
|
||||
except AppError as e:
|
||||
raise create_http_exception(e)
|
||||
|
||||
|
||||
@router.get("/groups/{name}", response_model=LuckPermsGroup)
|
||||
async def get_group(
|
||||
name: str,
|
||||
service: Annotated[LuckPermsService, Depends(get_luckperms_service)],
|
||||
_: Annotated[str, Depends(verify_api_key)]
|
||||
):
|
||||
"""Get group by name."""
|
||||
try:
|
||||
return await service.get_group(name)
|
||||
except AppError as e:
|
||||
raise create_http_exception(e)
|
||||
|
||||
|
||||
@router.get("/players/{uuid}/permissions", response_model=list[LuckPermsUserPermission])
|
||||
async def get_user_permissions(
|
||||
uuid: str,
|
||||
service: Annotated[LuckPermsService, Depends(get_luckperms_service)],
|
||||
_: Annotated[str, Depends(verify_api_key)]
|
||||
):
|
||||
"""Get user permissions."""
|
||||
try:
|
||||
return await service.get_user_permissions(uuid)
|
||||
except AppError as e:
|
||||
raise create_http_exception(e)
|
||||
|
||||
|
||||
@router.get("/players/{uuid}/with-permissions", response_model=LuckPermsPlayerWithPermissions)
|
||||
async def get_player_with_permissions(
|
||||
uuid: str,
|
||||
service: Annotated[LuckPermsService, Depends(get_luckperms_service)],
|
||||
_: Annotated[str, Depends(verify_api_key)]
|
||||
):
|
||||
"""Get player with permissions."""
|
||||
try:
|
||||
return await service.get_player_with_permissions(uuid)
|
||||
except AppError as e:
|
||||
raise create_http_exception(e)
|
||||
|
|
@ -56,7 +56,7 @@ async def query_punishments(
|
|||
|
||||
@router.get("/ban/{player_uuid}", response_model=ActiveBanStatusResponse)
|
||||
async def get_ban_status(
|
||||
player_uuid: UUID,
|
||||
player_uuid: str,
|
||||
service: Annotated[PunishmentsService, Depends(get_punishments_service)],
|
||||
_: Annotated[str, Depends(verify_api_key)]
|
||||
):
|
||||
|
|
@ -69,7 +69,7 @@ async def get_ban_status(
|
|||
|
||||
@router.get("/mute/{player_uuid}", response_model=ActiveMuteStatusResponse)
|
||||
async def get_mute_status(
|
||||
player_uuid: UUID,
|
||||
player_uuid: str,
|
||||
service: Annotated[PunishmentsService, Depends(get_punishments_service)],
|
||||
_: Annotated[str, Depends(verify_api_key)]
|
||||
):
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"""Main API v1 router."""
|
||||
|
||||
from fastapi import APIRouter
|
||||
from hubgw.api.v1 import health, homes, kits, cooldowns, warps, whitelist, punishments, audit
|
||||
from hubgw.api.v1 import health, homes, kits, cooldowns, warps, whitelist, punishments, audit, luckperms, teleport_history
|
||||
|
||||
api_router = APIRouter()
|
||||
|
||||
|
|
@ -14,3 +14,5 @@ api_router.include_router(warps.router, prefix="/warps", tags=["warps"])
|
|||
api_router.include_router(whitelist.router, prefix="/whitelist", tags=["whitelist"])
|
||||
api_router.include_router(punishments.router, prefix="/punishments", tags=["punishments"])
|
||||
api_router.include_router(audit.router, prefix="/audit", tags=["audit"])
|
||||
api_router.include_router(luckperms.router, prefix="/luckperms", tags=["luckperms"])
|
||||
api_router.include_router(teleport_history.router, prefix="/teleport-history", tags=["teleport-history"])
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
"""Teleport History endpoints."""
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from typing import Annotated
|
||||
|
||||
from hubgw.api.deps import get_teleport_history_service, verify_api_key
|
||||
from hubgw.services.teleport_history_service import TeleportHistoryService
|
||||
from hubgw.schemas.teleport_history import TeleportHistoryCreate, TeleportHistory
|
||||
from hubgw.core.errors import AppError, create_http_exception
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.post("/", response_model=TeleportHistory, status_code=201)
|
||||
async def create_teleport(
|
||||
request: TeleportHistoryCreate,
|
||||
service: Annotated[TeleportHistoryService, Depends(get_teleport_history_service)],
|
||||
_: Annotated[str, Depends(verify_api_key)]
|
||||
):
|
||||
"""Create teleport history entry."""
|
||||
try:
|
||||
return await service.create_teleport(request)
|
||||
except AppError as e:
|
||||
raise create_http_exception(e)
|
||||
|
||||
|
||||
@router.get("/players/{player_uuid}", response_model=list[TeleportHistory])
|
||||
async def list_player_teleports(
|
||||
player_uuid: str,
|
||||
service: Annotated[TeleportHistoryService, Depends(get_teleport_history_service)],
|
||||
_: Annotated[str, Depends(verify_api_key)],
|
||||
limit: int = Query(100, ge=1, le=1000, description="Maximum number of entries to return")
|
||||
):
|
||||
"""List teleport history for player."""
|
||||
try:
|
||||
return await service.list_player_teleports(player_uuid, limit)
|
||||
except AppError as e:
|
||||
raise create_http_exception(e)
|
||||
|
|
@ -1,17 +1,18 @@
|
|||
"""Cooldown model."""
|
||||
|
||||
from sqlalchemy import Column, String, DateTime, Integer
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from sqlalchemy import Column, String, DateTime, Integer, ForeignKey
|
||||
from sqlalchemy.dialects.postgresql import UUID, JSONB
|
||||
from hubgw.models.base import Base
|
||||
|
||||
|
||||
class Cooldown(Base):
|
||||
"""Cooldown model."""
|
||||
|
||||
|
||||
__tablename__ = "hub_cooldowns"
|
||||
|
||||
id = Column(UUID(as_uuid=True), primary_key=True)
|
||||
key = Column(String(255), nullable=False, unique=True, index=True)
|
||||
player_uuid = Column(UUID(as_uuid=True), nullable=False, index=True)
|
||||
expires_at = Column(DateTime(timezone=True), nullable=False)
|
||||
|
||||
id = Column(UUID(as_uuid=True), primary_key=True, server_default="gen_random_uuid()")
|
||||
player_uuid = Column(String(36), ForeignKey("luckperms_players.uuid", ondelete="CASCADE"), nullable=False, index=True)
|
||||
cooldown_type = Column(String(50), nullable=False)
|
||||
expires_at = Column(DateTime(timezone=True), nullable=False, index=True)
|
||||
cooldown_seconds = Column(Integer, nullable=False)
|
||||
metadata = Column(JSONB)
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
"""Home model."""
|
||||
|
||||
from sqlalchemy import Column, String, Float, Integer, ForeignKey
|
||||
from sqlalchemy import Column, Float, String, Boolean, ForeignKey, REAL
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from hubgw.models.base import Base
|
||||
|
||||
|
||||
class Home(Base):
|
||||
"""Home model."""
|
||||
|
||||
|
||||
__tablename__ = "hub_homes"
|
||||
|
||||
id = Column(UUID(as_uuid=True), primary_key=True)
|
||||
player_uuid = Column(UUID(as_uuid=True), nullable=False, index=True)
|
||||
|
||||
id = Column(UUID(as_uuid=True), primary_key=True, server_default="gen_random_uuid()")
|
||||
player_uuid = Column(String(36), ForeignKey("luckperms_players.uuid", ondelete="CASCADE"), nullable=False, index=True)
|
||||
name = Column(String(255), nullable=False)
|
||||
world = Column(String(255), nullable=False)
|
||||
x = Column(Float, nullable=False)
|
||||
y = Column(Float, nullable=False)
|
||||
z = Column(Float, nullable=False)
|
||||
yaw = Column(Float, default=0.0)
|
||||
pitch = Column(Float, default=0.0)
|
||||
is_public = Column(Integer, default=0) # 0 = private, 1 = public
|
||||
world = Column(String, nullable=False) # TEXT type
|
||||
x = Column(Float, nullable=False) # DOUBLE PRECISION
|
||||
y = Column(Float, nullable=False) # DOUBLE PRECISION
|
||||
z = Column(Float, nullable=False) # DOUBLE PRECISION
|
||||
yaw = Column(REAL, default=0.0)
|
||||
pitch = Column(REAL, default=0.0)
|
||||
is_public = Column(Boolean, default=False)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
"""LuckPerms models."""
|
||||
|
||||
from sqlalchemy import (
|
||||
Column,
|
||||
String,
|
||||
Boolean,
|
||||
BigInteger,
|
||||
ForeignKey,
|
||||
Integer,
|
||||
)
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from hubgw.models.base import Base
|
||||
|
||||
|
||||
class LuckPermsPlayer(Base):
|
||||
"""LuckPerms Player model."""
|
||||
|
||||
__tablename__ = "luckperms_players"
|
||||
|
||||
uuid = Column(String(36), primary_key=True)
|
||||
username = Column(String(16), nullable=False, index=True)
|
||||
primary_group = Column(String(36), nullable=False)
|
||||
|
||||
permissions = relationship("LuckPermsUserPermission", back_populates="player", cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class LuckPermsGroup(Base):
|
||||
"""LuckPerms Group model."""
|
||||
|
||||
__tablename__ = "luckperms_groups"
|
||||
|
||||
name = Column(String(36), primary_key=True)
|
||||
|
||||
|
||||
class LuckPermsUserPermission(Base):
|
||||
"""LuckPerms User Permission model."""
|
||||
|
||||
__tablename__ = "luckperms_user_permissions"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
uuid = Column(String(36), ForeignKey("luckperms_players.uuid", ondelete="CASCADE"), nullable=False, index=True)
|
||||
permission = Column(String(200), nullable=False)
|
||||
value = Column(Boolean, nullable=False)
|
||||
server = Column(String(36))
|
||||
world = Column(String(64))
|
||||
expiry = Column(BigInteger)
|
||||
contexts = Column(String(200))
|
||||
|
||||
player = relationship("LuckPermsPlayer", back_populates="permissions")
|
||||
|
|
@ -1,25 +1,27 @@
|
|||
"""Punishment model."""
|
||||
|
||||
from sqlalchemy import Column, String, DateTime, Integer, Text
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from sqlalchemy import Column, String, DateTime, Boolean, Text, ForeignKey
|
||||
from sqlalchemy.dialects.postgresql import UUID, INET
|
||||
from hubgw.models.base import Base
|
||||
|
||||
|
||||
class Punishment(Base):
|
||||
"""Punishment model."""
|
||||
|
||||
|
||||
__tablename__ = "hub_punishments"
|
||||
|
||||
id = Column(UUID(as_uuid=True), primary_key=True)
|
||||
player_uuid = Column(UUID(as_uuid=True), nullable=False, index=True)
|
||||
|
||||
id = Column(UUID(as_uuid=True), primary_key=True, server_default="gen_random_uuid()")
|
||||
player_uuid = Column(String(36), ForeignKey("luckperms_players.uuid", ondelete="CASCADE"), nullable=False, index=True)
|
||||
player_name = Column(String(255), nullable=False)
|
||||
punishment_type = Column(String(50), nullable=False) # ban, warn, mute
|
||||
player_ip = Column(INET)
|
||||
punishment_type = Column(String(50), nullable=False) # BAN, MUTE, KICK, WARN, TEMPBAN, TEMPMUTE
|
||||
reason = Column(Text, nullable=False)
|
||||
staff_uuid = Column(UUID(as_uuid=True), nullable=False)
|
||||
staff_uuid = Column(String(36), ForeignKey("luckperms_players.uuid", ondelete="SET NULL"), nullable=False)
|
||||
staff_name = Column(String(255), nullable=False)
|
||||
created_at = Column(DateTime(timezone=True), nullable=False)
|
||||
expires_at = Column(DateTime(timezone=True), nullable=True) # None for permanent
|
||||
is_active = Column(Integer, default=1) # 0 = inactive, 1 = active
|
||||
revoked_at = Column(DateTime(timezone=True), nullable=True)
|
||||
revoked_by = Column(UUID(as_uuid=True), nullable=True)
|
||||
revoked_reason = Column(Text, nullable=True)
|
||||
expires_at = Column(DateTime(timezone=True))
|
||||
is_active = Column(Boolean, default=True)
|
||||
revoked_at = Column(DateTime(timezone=True))
|
||||
revoked_by = Column(String(36), ForeignKey("luckperms_players.uuid", ondelete="SET NULL"))
|
||||
revoked_reason = Column(Text)
|
||||
evidence_url = Column(Text)
|
||||
notes = Column(Text)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
"""Teleport History model."""
|
||||
|
||||
from sqlalchemy import Column, String, Float, ForeignKey
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from hubgw.models.base import Base
|
||||
|
||||
|
||||
class TeleportHistory(Base):
|
||||
"""Teleport History model."""
|
||||
|
||||
__tablename__ = "hub_teleport_history"
|
||||
|
||||
id = Column(UUID(as_uuid=True), primary_key=True, server_default="gen_random_uuid()")
|
||||
player_uuid = Column(String(36), ForeignKey("luckperms_players.uuid", ondelete="CASCADE"), nullable=False, index=True)
|
||||
from_world = Column(String)
|
||||
from_x = Column(Float)
|
||||
from_y = Column(Float)
|
||||
from_z = Column(Float)
|
||||
to_world = Column(String, nullable=False)
|
||||
to_x = Column(Float, nullable=False)
|
||||
to_y = Column(Float, nullable=False)
|
||||
to_z = Column(Float, nullable=False)
|
||||
tp_type = Column(String(50), nullable=False)
|
||||
target_name = Column(String(255))
|
||||
|
|
@ -1,22 +1,22 @@
|
|||
"""Warp model."""
|
||||
|
||||
from sqlalchemy import Column, String, Float, Integer
|
||||
from sqlalchemy import Column, String, Float, Boolean, REAL
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from hubgw.models.base import Base
|
||||
|
||||
|
||||
class Warp(Base):
|
||||
"""Warp model."""
|
||||
|
||||
|
||||
__tablename__ = "hub_warps"
|
||||
|
||||
id = Column(UUID(as_uuid=True), primary_key=True)
|
||||
|
||||
id = Column(UUID(as_uuid=True), primary_key=True, server_default="gen_random_uuid()")
|
||||
name = Column(String(255), nullable=False, unique=True, index=True)
|
||||
world = Column(String(255), nullable=False)
|
||||
x = Column(Float, nullable=False)
|
||||
y = Column(Float, nullable=False)
|
||||
z = Column(Float, nullable=False)
|
||||
yaw = Column(Float, default=0.0)
|
||||
pitch = Column(Float, default=0.0)
|
||||
is_public = Column(Integer, default=1) # 0 = private, 1 = public
|
||||
description = Column(String(500), nullable=True)
|
||||
world = Column(String, nullable=False) # TEXT type
|
||||
x = Column(Float, nullable=False) # DOUBLE PRECISION
|
||||
y = Column(Float, nullable=False) # DOUBLE PRECISION
|
||||
z = Column(Float, nullable=False) # DOUBLE PRECISION
|
||||
yaw = Column(REAL, default=0.0)
|
||||
pitch = Column(REAL, default=0.0)
|
||||
is_public = Column(Boolean, default=True)
|
||||
description = Column(String(500))
|
||||
|
|
|
|||
|
|
@ -1,18 +1,20 @@
|
|||
"""Whitelist model."""
|
||||
|
||||
from sqlalchemy import Column, String, DateTime
|
||||
from sqlalchemy import Column, String, DateTime, Boolean, ForeignKey
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from hubgw.models.base import Base
|
||||
|
||||
|
||||
class WhitelistEntry(Base):
|
||||
"""Whitelist entry model."""
|
||||
|
||||
|
||||
__tablename__ = "hub_whitelist"
|
||||
|
||||
id = Column(UUID(as_uuid=True), primary_key=True)
|
||||
|
||||
id = Column(UUID(as_uuid=True), primary_key=True, server_default="gen_random_uuid()")
|
||||
player_name = Column(String(255), nullable=False, unique=True, index=True)
|
||||
player_uuid = Column(UUID(as_uuid=True), nullable=True, index=True)
|
||||
player_uuid = Column(String(36), ForeignKey("luckperms_players.uuid", ondelete="SET NULL"), index=True)
|
||||
added_by = Column(String(255), nullable=False)
|
||||
added_at = Column(DateTime(timezone=True), nullable=False)
|
||||
reason = Column(String(500), nullable=True)
|
||||
expires_at = Column(DateTime(timezone=True))
|
||||
is_active = Column(Boolean, default=True)
|
||||
reason = Column(String(500))
|
||||
|
|
|
|||
|
|
@ -15,45 +15,33 @@ class CooldownsRepository:
|
|||
def __init__(self, session: AsyncSession):
|
||||
self.session = session
|
||||
|
||||
async def check(self, player_uuid: UUID, key: str) -> Optional[Cooldown]:
|
||||
async def check(self, player_uuid: str, cooldown_type: str) -> Optional[Cooldown]:
|
||||
"""Check if cooldown is active."""
|
||||
stmt = select(Cooldown).where(
|
||||
Cooldown.player_uuid == player_uuid,
|
||||
Cooldown.key == key,
|
||||
Cooldown.cooldown_type == cooldown_type,
|
||||
Cooldown.expires_at > func.now()
|
||||
)
|
||||
result = await self.session.execute(stmt)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
async def touch(self, player_uuid: UUID, key: str, cooldown_seconds: int) -> Cooldown:
|
||||
"""Touch cooldown (create or update)."""
|
||||
async def create(self, player_uuid: str, cooldown_type: str, cooldown_seconds: int, metadata: Optional[dict] = None) -> Cooldown:
|
||||
"""Create new cooldown."""
|
||||
expires_at = datetime.utcnow() + timedelta(seconds=cooldown_seconds)
|
||||
|
||||
stmt = insert(Cooldown).values(
|
||||
key=key,
|
||||
cooldown = Cooldown(
|
||||
player_uuid=player_uuid,
|
||||
cooldown_type=cooldown_type,
|
||||
expires_at=expires_at,
|
||||
cooldown_seconds=cooldown_seconds,
|
||||
expires_at=expires_at
|
||||
metadata=metadata
|
||||
)
|
||||
stmt = stmt.on_conflict_do_update(
|
||||
index_elements=['key', 'player_uuid'],
|
||||
set_=dict(
|
||||
cooldown_seconds=stmt.excluded.cooldown_seconds,
|
||||
expires_at=stmt.excluded.expires_at
|
||||
)
|
||||
)
|
||||
result = await self.session.execute(stmt)
|
||||
self.session.add(cooldown)
|
||||
await self.session.commit()
|
||||
|
||||
# Get the touched cooldown
|
||||
stmt = select(Cooldown).where(
|
||||
Cooldown.player_uuid == player_uuid,
|
||||
Cooldown.key == key
|
||||
)
|
||||
result = await self.session.execute(stmt)
|
||||
return result.scalar_one()
|
||||
await self.session.refresh(cooldown)
|
||||
return cooldown
|
||||
|
||||
async def list_by_player(self, player_uuid: UUID) -> List[Cooldown]:
|
||||
async def list_by_player(self, player_uuid: str) -> List[Cooldown]:
|
||||
"""List active cooldowns by player."""
|
||||
stmt = select(Cooldown).where(
|
||||
Cooldown.player_uuid == player_uuid,
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class HomesRepository:
|
|||
result = await self.session.execute(stmt)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
async def list_by_player(self, player_uuid: UUID) -> List[Home]:
|
||||
async def list_by_player(self, player_uuid: str) -> List[Home]:
|
||||
"""List homes by player UUID."""
|
||||
stmt = select(Home).where(Home.player_uuid == player_uuid)
|
||||
result = await self.session.execute(stmt)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
"""LuckPerms repository."""
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
from typing import List, Optional
|
||||
|
||||
from hubgw.models.luckperms import LuckPermsPlayer, LuckPermsGroup, LuckPermsUserPermission
|
||||
|
||||
|
||||
class LuckPermsRepository:
|
||||
"""LuckPerms repository for database operations."""
|
||||
|
||||
def __init__(self, session: AsyncSession):
|
||||
self.session = session
|
||||
|
||||
async def get_player(self, uuid: str) -> Optional[LuckPermsPlayer]:
|
||||
"""Get player by UUID."""
|
||||
stmt = select(LuckPermsPlayer).where(LuckPermsPlayer.uuid == uuid)
|
||||
result = await self.session.execute(stmt)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
async def get_player_by_username(self, username: str) -> Optional[LuckPermsPlayer]:
|
||||
"""Get player by username."""
|
||||
stmt = select(LuckPermsPlayer).where(LuckPermsPlayer.username == username)
|
||||
result = await self.session.execute(stmt)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
async def get_group(self, name: str) -> Optional[LuckPermsGroup]:
|
||||
"""Get group by name."""
|
||||
stmt = select(LuckPermsGroup).where(LuckPermsGroup.name == name)
|
||||
result = await self.session.execute(stmt)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
async def get_user_permissions(self, uuid: str) -> List[LuckPermsUserPermission]:
|
||||
"""Get user permissions."""
|
||||
stmt = select(LuckPermsUserPermission).where(LuckPermsUserPermission.uuid == uuid)
|
||||
result = await self.session.execute(stmt)
|
||||
return list(result.scalars().all())
|
||||
|
|
@ -21,12 +21,14 @@ class PunishmentsRepository:
|
|||
punishment = Punishment(
|
||||
player_uuid=request.player_uuid,
|
||||
player_name=request.player_name,
|
||||
player_ip=request.player_ip,
|
||||
punishment_type=request.punishment_type,
|
||||
reason=request.reason,
|
||||
staff_uuid=request.staff_uuid,
|
||||
staff_name=request.staff_name,
|
||||
created_at=datetime.utcnow(),
|
||||
expires_at=request.expires_at
|
||||
expires_at=request.expires_at,
|
||||
evidence_url=request.evidence_url,
|
||||
notes=request.notes
|
||||
)
|
||||
self.session.add(punishment)
|
||||
await self.session.commit()
|
||||
|
|
@ -42,7 +44,7 @@ class PunishmentsRepository:
|
|||
if not punishment:
|
||||
return None
|
||||
|
||||
punishment.is_active = 0
|
||||
punishment.is_active = False
|
||||
punishment.revoked_at = datetime.utcnow()
|
||||
punishment.revoked_by = request.revoked_by
|
||||
punishment.revoked_reason = request.revoked_reason
|
||||
|
|
@ -66,8 +68,8 @@ class PunishmentsRepository:
|
|||
count_stmt = count_stmt.where(Punishment.punishment_type == query.punishment_type)
|
||||
|
||||
if query.is_active is not None:
|
||||
stmt = stmt.where(Punishment.is_active == (1 if query.is_active else 0))
|
||||
count_stmt = count_stmt.where(Punishment.is_active == (1 if query.is_active else 0))
|
||||
stmt = stmt.where(Punishment.is_active == query.is_active)
|
||||
count_stmt = count_stmt.where(Punishment.is_active == query.is_active)
|
||||
|
||||
# Get total count
|
||||
count_result = await self.session.execute(count_stmt)
|
||||
|
|
@ -82,23 +84,23 @@ class PunishmentsRepository:
|
|||
|
||||
return punishments, total
|
||||
|
||||
async def get_active_ban(self, player_uuid: UUID) -> Optional[Punishment]:
|
||||
async def get_active_ban(self, player_uuid: str) -> Optional[Punishment]:
|
||||
"""Get active ban for player."""
|
||||
stmt = select(Punishment).where(
|
||||
Punishment.player_uuid == player_uuid,
|
||||
Punishment.punishment_type == "ban",
|
||||
Punishment.is_active == 1,
|
||||
Punishment.punishment_type.in_(['BAN', 'TEMPBAN']),
|
||||
Punishment.is_active == True,
|
||||
(Punishment.expires_at.is_(None)) | (Punishment.expires_at > datetime.utcnow())
|
||||
)
|
||||
result = await self.session.execute(stmt)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
async def get_active_mute(self, player_uuid: UUID) -> Optional[Punishment]:
|
||||
async def get_active_mute(self, player_uuid: str) -> Optional[Punishment]:
|
||||
"""Get active mute for player."""
|
||||
stmt = select(Punishment).where(
|
||||
Punishment.player_uuid == player_uuid,
|
||||
Punishment.punishment_type == "mute",
|
||||
Punishment.is_active == 1,
|
||||
Punishment.punishment_type.in_(['MUTE', 'TEMPMUTE']),
|
||||
Punishment.is_active == True,
|
||||
(Punishment.expires_at.is_(None)) | (Punishment.expires_at > datetime.utcnow())
|
||||
)
|
||||
result = await self.session.execute(stmt)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
"""Teleport History repository."""
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
from typing import List
|
||||
|
||||
from hubgw.models.teleport_history import TeleportHistory
|
||||
from hubgw.schemas.teleport_history import TeleportHistoryCreate
|
||||
|
||||
|
||||
class TeleportHistoryRepository:
|
||||
"""Teleport History repository for database operations."""
|
||||
|
||||
def __init__(self, session: AsyncSession):
|
||||
self.session = session
|
||||
|
||||
async def create(self, request: TeleportHistoryCreate) -> TeleportHistory:
|
||||
"""Create teleport history entry."""
|
||||
entry = TeleportHistory(**request.model_dump())
|
||||
self.session.add(entry)
|
||||
await self.session.commit()
|
||||
await self.session.refresh(entry)
|
||||
return entry
|
||||
|
||||
async def list_by_player(self, player_uuid: str, limit: int = 100) -> List[TeleportHistory]:
|
||||
"""List teleport history by player."""
|
||||
stmt = select(TeleportHistory).where(
|
||||
TeleportHistory.player_uuid == player_uuid
|
||||
).order_by(TeleportHistory.created_at.desc()).limit(limit)
|
||||
result = await self.session.execute(stmt)
|
||||
return list(result.scalars().all())
|
||||
|
|
@ -42,7 +42,7 @@ class WarpsRepository:
|
|||
if not warp:
|
||||
return None
|
||||
|
||||
update_data = request.dict(exclude_unset=True, exclude={'name'})
|
||||
update_data = request.model_dump(exclude_unset=True, exclude={'name'})
|
||||
for field, value in update_data.items():
|
||||
setattr(warp, field, value)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ class WhitelistRepository:
|
|||
player_name=request.player_name,
|
||||
player_uuid=request.player_uuid,
|
||||
added_by=request.added_by,
|
||||
added_at=datetime.utcnow(),
|
||||
added_at=request.added_at,
|
||||
expires_at=request.expires_at,
|
||||
is_active=request.is_active,
|
||||
reason=request.reason
|
||||
)
|
||||
self.session.add(entry)
|
||||
|
|
|
|||
|
|
@ -7,17 +7,11 @@ from typing import Optional
|
|||
from hubgw.schemas.common import BaseSchema
|
||||
|
||||
|
||||
class CooldownKey(BaseModel):
|
||||
"""Cooldown key schema."""
|
||||
|
||||
key: str
|
||||
|
||||
|
||||
class CooldownCheckRequest(BaseModel):
|
||||
"""Cooldown check request schema."""
|
||||
|
||||
player_uuid: UUID
|
||||
key: str
|
||||
player_uuid: str
|
||||
cooldown_type: str
|
||||
|
||||
|
||||
class CooldownCheckResponse(BaseModel):
|
||||
|
|
@ -28,11 +22,23 @@ class CooldownCheckResponse(BaseModel):
|
|||
remaining_seconds: Optional[int] = None
|
||||
|
||||
|
||||
class Cooldown(BaseSchema):
|
||||
class CooldownBase(BaseModel):
|
||||
"""Base cooldown schema."""
|
||||
|
||||
cooldown_type: str
|
||||
expires_at: datetime
|
||||
cooldown_seconds: int
|
||||
metadata: Optional[dict] = None
|
||||
|
||||
|
||||
class CooldownCreate(CooldownBase):
|
||||
"""Cooldown creation schema."""
|
||||
|
||||
player_uuid: str
|
||||
|
||||
|
||||
class Cooldown(CooldownBase, BaseSchema):
|
||||
"""Cooldown schema."""
|
||||
|
||||
id: UUID
|
||||
key: str
|
||||
player_uuid: UUID
|
||||
expires_at: datetime
|
||||
cooldown_seconds: int
|
||||
player_uuid: str
|
||||
|
|
|
|||
|
|
@ -17,38 +17,45 @@ class HomeBase(BaseModel):
|
|||
z: float
|
||||
yaw: float = 0.0
|
||||
pitch: float = 0.0
|
||||
is_public: int = 0
|
||||
is_public: bool = False
|
||||
|
||||
|
||||
class HomeCreate(HomeBase):
|
||||
"""Home creation schema."""
|
||||
|
||||
player_uuid: UUID
|
||||
player_uuid: str
|
||||
|
||||
|
||||
class HomeUpdate(HomeBase):
|
||||
class HomeUpdate(BaseModel):
|
||||
"""Home update schema."""
|
||||
|
||||
pass
|
||||
name: Optional[str] = None
|
||||
world: Optional[str] = None
|
||||
x: Optional[float] = None
|
||||
y: Optional[float] = None
|
||||
z: Optional[float] = None
|
||||
yaw: Optional[float] = None
|
||||
pitch: Optional[float] = None
|
||||
is_public: Optional[bool] = None
|
||||
|
||||
|
||||
class HomeUpsertRequest(HomeBase):
|
||||
"""Home upsert request schema."""
|
||||
|
||||
player_uuid: UUID
|
||||
player_uuid: str
|
||||
|
||||
|
||||
class Home(HomeBase, BaseSchema):
|
||||
"""Home response schema."""
|
||||
|
||||
id: UUID
|
||||
player_uuid: UUID
|
||||
player_uuid: str
|
||||
|
||||
|
||||
class HomeGetRequest(BaseModel):
|
||||
"""Home get request schema."""
|
||||
|
||||
player_uuid: UUID
|
||||
player_uuid: str
|
||||
name: str
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
"""LuckPerms schemas."""
|
||||
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
from uuid import UUID
|
||||
from hubgw.schemas.common import BaseSchema
|
||||
|
||||
|
||||
class LuckPermsPlayer(BaseSchema):
|
||||
"""LuckPerms Player schema."""
|
||||
|
||||
uuid: str
|
||||
username: str
|
||||
primary_group: str
|
||||
|
||||
|
||||
class LuckPermsGroup(BaseSchema):
|
||||
"""LuckPerms Group schema."""
|
||||
|
||||
name: str
|
||||
|
||||
|
||||
class LuckPermsUserPermission(BaseSchema):
|
||||
"""LuckPerms User Permission schema."""
|
||||
|
||||
id: int
|
||||
uuid: str
|
||||
permission: str
|
||||
value: bool
|
||||
server: Optional[str] = None
|
||||
world: Optional[str] = None
|
||||
expiry: Optional[int] = None
|
||||
contexts: Optional[str] = None
|
||||
|
||||
|
||||
class LuckPermsPlayerWithPermissions(LuckPermsPlayer):
|
||||
"""LuckPerms Player with permissions schema."""
|
||||
|
||||
permissions: list[LuckPermsUserPermission] = []
|
||||
|
|
@ -7,30 +7,35 @@ from uuid import UUID
|
|||
from hubgw.schemas.common import BaseSchema
|
||||
|
||||
|
||||
from ipaddress import IPv4Address
|
||||
|
||||
class PunishmentCreateRequest(BaseModel):
|
||||
"""Punishment create request schema."""
|
||||
|
||||
player_uuid: UUID
|
||||
player_uuid: str
|
||||
player_name: str
|
||||
punishment_type: str # ban, warn, mute
|
||||
player_ip: Optional[IPv4Address] = None
|
||||
punishment_type: str
|
||||
reason: str
|
||||
staff_uuid: UUID
|
||||
staff_uuid: str
|
||||
staff_name: str
|
||||
expires_at: Optional[datetime] = None # None for permanent
|
||||
expires_at: Optional[datetime] = None
|
||||
evidence_url: Optional[str] = None
|
||||
notes: Optional[str] = None
|
||||
|
||||
|
||||
class PunishmentRevokeRequest(BaseModel):
|
||||
"""Punishment revoke request schema."""
|
||||
|
||||
punishment_id: UUID
|
||||
revoked_by: UUID
|
||||
revoked_by: str
|
||||
revoked_reason: str
|
||||
|
||||
|
||||
class PunishmentQuery(BaseModel):
|
||||
"""Punishment query schema."""
|
||||
|
||||
player_uuid: Optional[UUID] = None
|
||||
player_uuid: Optional[str] = None
|
||||
punishment_type: Optional[str] = None
|
||||
is_active: Optional[bool] = None
|
||||
page: int = 1
|
||||
|
|
@ -41,17 +46,20 @@ class PunishmentBase(BaseSchema):
|
|||
"""Base punishment schema."""
|
||||
|
||||
id: UUID
|
||||
player_uuid: UUID
|
||||
player_uuid: str
|
||||
player_name: str
|
||||
player_ip: Optional[IPv4Address] = None
|
||||
punishment_type: str
|
||||
reason: str
|
||||
staff_uuid: UUID
|
||||
staff_uuid: str
|
||||
staff_name: str
|
||||
expires_at: Optional[datetime] = None
|
||||
is_active: int
|
||||
is_active: bool
|
||||
revoked_at: Optional[datetime] = None
|
||||
revoked_by: Optional[UUID] = None
|
||||
revoked_by: Optional[str] = None
|
||||
revoked_reason: Optional[str] = None
|
||||
evidence_url: Optional[str] = None
|
||||
notes: Optional[str] = None
|
||||
|
||||
|
||||
class PunishmentListResponse(BaseModel):
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
"""Teleport History schemas."""
|
||||
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
from uuid import UUID
|
||||
from hubgw.schemas.common import BaseSchema
|
||||
|
||||
|
||||
class TeleportHistoryBase(BaseModel):
|
||||
"""Base teleport history schema."""
|
||||
|
||||
from_world: Optional[str] = None
|
||||
from_x: Optional[float] = None
|
||||
from_y: Optional[float] = None
|
||||
from_z: Optional[float] = None
|
||||
to_world: str
|
||||
to_x: float
|
||||
to_y: float
|
||||
to_z: float
|
||||
tp_type: str
|
||||
target_name: Optional[str] = None
|
||||
|
||||
|
||||
class TeleportHistoryCreate(TeleportHistoryBase):
|
||||
"""Teleport history creation schema."""
|
||||
|
||||
player_uuid: str
|
||||
|
||||
|
||||
class TeleportHistory(TeleportHistoryBase, BaseSchema):
|
||||
"""Teleport history schema."""
|
||||
|
||||
id: UUID
|
||||
player_uuid: str
|
||||
|
|
@ -17,7 +17,7 @@ class WarpBase(BaseModel):
|
|||
z: float
|
||||
yaw: float = 0.0
|
||||
pitch: float = 0.0
|
||||
is_public: int = 1
|
||||
is_public: bool = True
|
||||
description: Optional[str] = None
|
||||
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ class WarpUpdateRequest(BaseModel):
|
|||
z: Optional[float] = None
|
||||
yaw: Optional[float] = None
|
||||
pitch: Optional[float] = None
|
||||
is_public: Optional[int] = None
|
||||
is_public: Optional[bool] = None
|
||||
description: Optional[str] = None
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,11 @@ class WhitelistAddRequest(BaseModel):
|
|||
"""Whitelist add request schema."""
|
||||
|
||||
player_name: str
|
||||
player_uuid: Optional[UUID] = None
|
||||
player_uuid: Optional[str] = None
|
||||
added_by: str
|
||||
added_at: datetime
|
||||
expires_at: Optional[datetime] = None
|
||||
is_active: bool = True
|
||||
reason: Optional[str] = None
|
||||
|
||||
|
||||
|
|
@ -32,7 +35,7 @@ class WhitelistCheckResponse(BaseModel):
|
|||
"""Whitelist check response schema."""
|
||||
|
||||
is_whitelisted: bool
|
||||
player_uuid: Optional[UUID] = None
|
||||
player_uuid: Optional[str] = None
|
||||
|
||||
|
||||
class WhitelistEntry(BaseSchema):
|
||||
|
|
@ -40,9 +43,11 @@ class WhitelistEntry(BaseSchema):
|
|||
|
||||
id: UUID
|
||||
player_name: str
|
||||
player_uuid: Optional[UUID] = None
|
||||
player_uuid: Optional[str] = None
|
||||
added_by: str
|
||||
added_at: datetime
|
||||
expires_at: Optional[datetime] = None
|
||||
is_active: bool = True
|
||||
reason: Optional[str] = None
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from uuid import UUID
|
|||
from datetime import datetime
|
||||
|
||||
from hubgw.repositories.cooldowns_repo import CooldownsRepository
|
||||
from hubgw.schemas.cooldowns import CooldownCheckRequest, CooldownCheckResponse, CooldownKey
|
||||
from hubgw.schemas.cooldowns import CooldownCheckRequest, CooldownCheckResponse, CooldownCreate
|
||||
|
||||
|
||||
class CooldownsService:
|
||||
|
|
@ -16,7 +16,7 @@ class CooldownsService:
|
|||
|
||||
async def check_cooldown(self, request: CooldownCheckRequest) -> CooldownCheckResponse:
|
||||
"""Check cooldown status."""
|
||||
cooldown = await self.repo.check(request.player_uuid, request.key)
|
||||
cooldown = await self.repo.check(request.player_uuid, request.cooldown_type)
|
||||
|
||||
if not cooldown:
|
||||
return CooldownCheckResponse(is_active=False)
|
||||
|
|
@ -29,6 +29,11 @@ class CooldownsService:
|
|||
remaining_seconds=max(0, remaining_seconds)
|
||||
)
|
||||
|
||||
async def touch_cooldown(self, player_uuid: UUID, key: str, cooldown_seconds: int) -> None:
|
||||
"""Touch cooldown (create or update)."""
|
||||
await self.repo.touch(player_uuid, key, cooldown_seconds)
|
||||
async def create_cooldown(self, request: CooldownCreate) -> None:
|
||||
"""Create new cooldown."""
|
||||
await self.repo.create(
|
||||
player_uuid=request.player_uuid,
|
||||
cooldown_type=request.cooldown_type,
|
||||
cooldown_seconds=request.cooldown_seconds,
|
||||
metadata=request.metadata
|
||||
)
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class HomesService:
|
|||
updated_at=home.updated_at
|
||||
)
|
||||
|
||||
async def list_homes(self, player_uuid: UUID) -> HomeListResponse:
|
||||
async def list_homes(self, player_uuid: str) -> HomeListResponse:
|
||||
"""List homes with business logic."""
|
||||
homes = await self.repo.list_by_player(player_uuid)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
"""LuckPerms service."""
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from typing import List, Optional
|
||||
|
||||
from hubgw.repositories.luckperms_repo import LuckPermsRepository
|
||||
from hubgw.schemas.luckperms import LuckPermsPlayer, LuckPermsGroup, LuckPermsUserPermission, LuckPermsPlayerWithPermissions
|
||||
from hubgw.core.errors import NotFoundError
|
||||
|
||||
|
||||
class LuckPermsService:
|
||||
"""LuckPerms service for business logic."""
|
||||
|
||||
def __init__(self, session: AsyncSession):
|
||||
self.repo = LuckPermsRepository(session)
|
||||
|
||||
async def get_player(self, uuid: str) -> LuckPermsPlayer:
|
||||
"""Get player by UUID."""
|
||||
player = await self.repo.get_player(uuid)
|
||||
if not player:
|
||||
raise NotFoundError(f"Player {uuid} not found")
|
||||
return LuckPermsPlayer(
|
||||
uuid=player.uuid,
|
||||
username=player.username,
|
||||
primary_group=player.primary_group,
|
||||
created_at=player.created_at,
|
||||
updated_at=player.updated_at
|
||||
)
|
||||
|
||||
async def get_player_by_username(self, username: str) -> LuckPermsPlayer:
|
||||
"""Get player by username."""
|
||||
player = await self.repo.get_player_by_username(username)
|
||||
if not player:
|
||||
raise NotFoundError(f"Player {username} not found")
|
||||
return LuckPermsPlayer(
|
||||
uuid=player.uuid,
|
||||
username=player.username,
|
||||
primary_group=player.primary_group,
|
||||
created_at=player.created_at,
|
||||
updated_at=player.updated_at
|
||||
)
|
||||
|
||||
async def get_group(self, name: str) -> LuckPermsGroup:
|
||||
"""Get group by name."""
|
||||
group = await self.repo.get_group(name)
|
||||
if not group:
|
||||
raise NotFoundError(f"Group {name} not found")
|
||||
return LuckPermsGroup(
|
||||
name=group.name,
|
||||
created_at=group.created_at,
|
||||
updated_at=group.updated_at
|
||||
)
|
||||
|
||||
async def get_user_permissions(self, uuid: str) -> List[LuckPermsUserPermission]:
|
||||
"""Get user permissions."""
|
||||
permissions = await self.repo.get_user_permissions(uuid)
|
||||
return [
|
||||
LuckPermsUserPermission(
|
||||
id=perm.id,
|
||||
uuid=perm.uuid,
|
||||
permission=perm.permission,
|
||||
value=perm.value,
|
||||
server=perm.server,
|
||||
world=perm.world,
|
||||
expiry=perm.expiry,
|
||||
contexts=perm.contexts,
|
||||
created_at=perm.created_at,
|
||||
updated_at=perm.updated_at
|
||||
)
|
||||
for perm in permissions
|
||||
]
|
||||
|
||||
async def get_player_with_permissions(self, uuid: str) -> LuckPermsPlayerWithPermissions:
|
||||
"""Get player with permissions."""
|
||||
player = await self.repo.get_player(uuid)
|
||||
if not player:
|
||||
raise NotFoundError(f"Player {uuid} not found")
|
||||
|
||||
permissions = await self.repo.get_user_permissions(uuid)
|
||||
|
||||
permission_schemas = [
|
||||
LuckPermsUserPermission(
|
||||
id=perm.id,
|
||||
uuid=perm.uuid,
|
||||
permission=perm.permission,
|
||||
value=perm.value,
|
||||
server=perm.server,
|
||||
world=perm.world,
|
||||
expiry=perm.expiry,
|
||||
contexts=perm.contexts,
|
||||
created_at=perm.created_at,
|
||||
updated_at=perm.updated_at
|
||||
)
|
||||
for perm in permissions
|
||||
]
|
||||
|
||||
return LuckPermsPlayerWithPermissions(
|
||||
uuid=player.uuid,
|
||||
username=player.username,
|
||||
primary_group=player.primary_group,
|
||||
created_at=player.created_at,
|
||||
updated_at=player.updated_at,
|
||||
permissions=permission_schemas
|
||||
)
|
||||
|
|
@ -26,6 +26,7 @@ class PunishmentsService:
|
|||
id=punishment.id,
|
||||
player_uuid=punishment.player_uuid,
|
||||
player_name=punishment.player_name,
|
||||
player_ip=punishment.player_ip,
|
||||
punishment_type=punishment.punishment_type,
|
||||
reason=punishment.reason,
|
||||
staff_uuid=punishment.staff_uuid,
|
||||
|
|
@ -35,7 +36,9 @@ class PunishmentsService:
|
|||
is_active=punishment.is_active,
|
||||
revoked_at=punishment.revoked_at,
|
||||
revoked_by=punishment.revoked_by,
|
||||
revoked_reason=punishment.revoked_reason
|
||||
revoked_reason=punishment.revoked_reason,
|
||||
evidence_url=punishment.evidence_url,
|
||||
notes=punishment.notes
|
||||
)
|
||||
|
||||
async def revoke_punishment(self, request: PunishmentRevokeRequest) -> PunishmentBase:
|
||||
|
|
@ -48,6 +51,7 @@ class PunishmentsService:
|
|||
id=punishment.id,
|
||||
player_uuid=punishment.player_uuid,
|
||||
player_name=punishment.player_name,
|
||||
player_ip=punishment.player_ip,
|
||||
punishment_type=punishment.punishment_type,
|
||||
reason=punishment.reason,
|
||||
staff_uuid=punishment.staff_uuid,
|
||||
|
|
@ -57,7 +61,9 @@ class PunishmentsService:
|
|||
is_active=punishment.is_active,
|
||||
revoked_at=punishment.revoked_at,
|
||||
revoked_by=punishment.revoked_by,
|
||||
revoked_reason=punishment.revoked_reason
|
||||
revoked_reason=punishment.revoked_reason,
|
||||
evidence_url=punishment.evidence_url,
|
||||
notes=punishment.notes
|
||||
)
|
||||
|
||||
async def query_punishments(self, query: PunishmentQuery) -> PunishmentListResponse:
|
||||
|
|
@ -69,6 +75,7 @@ class PunishmentsService:
|
|||
id=p.id,
|
||||
player_uuid=p.player_uuid,
|
||||
player_name=p.player_name,
|
||||
player_ip=p.player_ip,
|
||||
punishment_type=p.punishment_type,
|
||||
reason=p.reason,
|
||||
staff_uuid=p.staff_uuid,
|
||||
|
|
@ -78,7 +85,9 @@ class PunishmentsService:
|
|||
is_active=p.is_active,
|
||||
revoked_at=p.revoked_at,
|
||||
revoked_by=p.revoked_by,
|
||||
revoked_reason=p.revoked_reason
|
||||
revoked_reason=p.revoked_reason,
|
||||
evidence_url=p.evidence_url,
|
||||
notes=p.notes
|
||||
)
|
||||
for p in punishments
|
||||
]
|
||||
|
|
@ -104,6 +113,7 @@ class PunishmentsService:
|
|||
id=ban.id,
|
||||
player_uuid=ban.player_uuid,
|
||||
player_name=ban.player_name,
|
||||
player_ip=ban.player_ip,
|
||||
punishment_type=ban.punishment_type,
|
||||
reason=ban.reason,
|
||||
staff_uuid=ban.staff_uuid,
|
||||
|
|
@ -113,7 +123,9 @@ class PunishmentsService:
|
|||
is_active=ban.is_active,
|
||||
revoked_at=ban.revoked_at,
|
||||
revoked_by=ban.revoked_by,
|
||||
revoked_reason=ban.revoked_reason
|
||||
revoked_reason=ban.revoked_reason,
|
||||
evidence_url=ban.evidence_url,
|
||||
notes=ban.notes
|
||||
)
|
||||
|
||||
return ActiveBanStatusResponse(is_banned=True, punishment=punishment)
|
||||
|
|
@ -129,6 +141,7 @@ class PunishmentsService:
|
|||
id=mute.id,
|
||||
player_uuid=mute.player_uuid,
|
||||
player_name=mute.player_name,
|
||||
player_ip=mute.player_ip,
|
||||
punishment_type=mute.punishment_type,
|
||||
reason=mute.reason,
|
||||
staff_uuid=mute.staff_uuid,
|
||||
|
|
@ -138,7 +151,9 @@ class PunishmentsService:
|
|||
is_active=mute.is_active,
|
||||
revoked_at=mute.revoked_at,
|
||||
revoked_by=mute.revoked_by,
|
||||
revoked_reason=mute.revoked_reason
|
||||
revoked_reason=mute.revoked_reason,
|
||||
evidence_url=mute.evidence_url,
|
||||
notes=mute.notes
|
||||
)
|
||||
|
||||
return ActiveMuteStatusResponse(is_muted=True, punishment=punishment)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
"""Teleport History service."""
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from typing import List
|
||||
|
||||
from hubgw.repositories.teleport_history_repo import TeleportHistoryRepository
|
||||
from hubgw.schemas.teleport_history import TeleportHistoryCreate, TeleportHistory
|
||||
|
||||
|
||||
class TeleportHistoryService:
|
||||
"""Teleport History service for business logic."""
|
||||
|
||||
def __init__(self, session: AsyncSession):
|
||||
self.repo = TeleportHistoryRepository(session)
|
||||
|
||||
async def create_teleport(self, request: TeleportHistoryCreate) -> TeleportHistory:
|
||||
"""Create teleport history entry."""
|
||||
entry = await self.repo.create(request)
|
||||
return TeleportHistory(
|
||||
id=entry.id,
|
||||
player_uuid=entry.player_uuid,
|
||||
from_world=entry.from_world,
|
||||
from_x=entry.from_x,
|
||||
from_y=entry.from_y,
|
||||
from_z=entry.from_z,
|
||||
to_world=entry.to_world,
|
||||
to_x=entry.to_x,
|
||||
to_y=entry.to_y,
|
||||
to_z=entry.to_z,
|
||||
tp_type=entry.tp_type,
|
||||
target_name=entry.target_name,
|
||||
created_at=entry.created_at,
|
||||
updated_at=entry.updated_at
|
||||
)
|
||||
|
||||
async def list_player_teleports(self, player_uuid: str, limit: int = 100) -> List[TeleportHistory]:
|
||||
"""List teleport history for player."""
|
||||
entries = await self.repo.list_by_player(player_uuid, limit)
|
||||
return [
|
||||
TeleportHistory(
|
||||
id=entry.id,
|
||||
player_uuid=entry.player_uuid,
|
||||
from_world=entry.from_world,
|
||||
from_x=entry.from_x,
|
||||
from_y=entry.from_y,
|
||||
from_z=entry.from_z,
|
||||
to_world=entry.to_world,
|
||||
to_x=entry.to_x,
|
||||
to_y=entry.to_y,
|
||||
to_z=entry.to_z,
|
||||
tp_type=entry.tp_type,
|
||||
target_name=entry.target_name,
|
||||
created_at=entry.created_at,
|
||||
updated_at=entry.updated_at
|
||||
)
|
||||
for entry in entries
|
||||
]
|
||||
Loading…
Reference in New Issue